Недавно мне пришлось работать над сайтом, интенсивно используя наклонные углы как часть его рекомендаций по дизайну. Под «углами наклона» я подразумеваю те секции, верхний или нижний край которых не полностью горизонтален и скорее немного наклонен.
Есть немало способов реализовать это. Вы можете использовать в качестве фона изображения в кодировке 64, но это затрудняет настройку (цвет, угол и т. Д.).
Другим способом было бы наклонить и / или повернуть абсолютно позиционированный псевдоэлемент, но если есть одна вещь, с которой я не хочу иметь дело, это перекосное преобразование. Боже, нет.
При использовании Sass вы можете использовать библиотеку Angled Edges, которая кодирует динамически генерируемый SVG. Он работает очень хорошо, однако требует фиксированной ширины и высоты, выраженной в пикселях, что меня это беспокоит.
Я также очень хотел посмотреть, смогу ли я реализовать это и как это сделать. Я получил решение, которым я действительно горжусь, даже если оно может быть немного перегружено для простых сценариев.
В чем идея?
Моя идея состояла в том, чтобы применить полупрозрачный, полутвердый градиент к абсолютно позиционированному псевдоэлементу. Угол наклона определяет угол наклона.
background-image: linear-gradient($angle, $color 50%, transparent 50%);
Это упаковано в mixin, который применяет цвет фона к контейнеру и генерирует псевдоэлемент с правильным градиентом, основанным на данном угле. Достаточно просто. Вы бы использовали это так:
.container { @include tilted($angle: 3deg, $color: rgb(255, 255, 255)); }
Основная проблема, с которой я столкнулся, заключалась в том, чтобы выяснить, какую высоту должен иметь псевдоэлемент. Вначале я сделал это аргументом миксина, но в итоге я использовал метод проб и ошибок под каждым новым углом, чтобы выяснить, какая будет наилучшая высота для псевдо. Не идеально.
И как раз когда я собирался перевернуть все это на стол, я решил оставить ноутбук, взял ручку и бумагу и начал рисовать, чтобы понять формулу, лежащую в основе. Мне потребовалось некоторое время (и несколько поисков в Google), чтобы вспомнить тригонометрию, которую я изучил в старшей школе, но в конце концов я сделал это.
Чтобы избежать необходимости угадывать или придумывать хорошие приближения, высота псевдоэлемента вычисляется из заданного угла. Это, конечно, все сделано с небольшим количеством Sass и большим количеством геометрии. Пошли.
Вычисление высоты псевдоэлемента
Поверь мне, когда я говорю тебе, это не будет слишком сложно. Первое, что мы знаем, это то, что у нас есть псевдоэлемент полной ширины. Линия градиента будет буквально диагональю псевдо, поэтому мы получим прямоугольник с треугольником.
Давайте назовем его ABC, где C
— это прямой угол, B
— известный угол (аргумент $angle
), и поэтому A
— это C - B
Как показано на этой диаграмме, мы пытаемся выяснить, что такое b
.
Чтобы сделать это, нам нужно найти значение c
(линия градиента, иначе гипотенуза), которая является длиной a
(нижняя сторона, 100%), деленная на синус угла A
(с B = 5°
, A
будет 85 ° например).
c = a / sin(C - B)
Оттуда мы должны использовать теорему Пифагора:
Квадрат гипотенузы (сторона, противоположная прямому углу) равна сумме квадратов двух других сторон.
Следовательно, квадрат другой стороны равен квадрату гипотенузы минус квадрат третьей стороны. Таким образом, квадрат b
равен квадрату c
минус квадрат a
.
b² = c² - a²
Наконец, длина b
равна квадратному корню квадрата c
минус квадрат a
.
b = √(c² - a²)
Вот и все. Теперь мы можем построить небольшую функцию Sass, вычисляющую высоту псевдоэлемента на основе заданного угла.
@function get-tilted-height($angle) { $a: (100% / 1%); $A: (90deg - $angle); $c: ($a / sin($A)); $b: sqrt(pow($c, 2) - pow($a, 2)); @return (abs($b) * 1%); }
Примечание: функции pow()
, sqrt()
и sin()
могут исходить из Sassy-Math , Compass или из пользовательских источников .
Строим наклонный миксин
Мы сделали самое сложное, поверь мне! Последнее, что нужно сделать, это создать реальный tilted()
tilted tilted()
. Он принимает угол и цвет в качестве аргумента и генерирует псевдоэлемент.
@mixin tilted($angle, $color) { $height: get-tilted-height($angle); position: relative; background-color: $color; &::before { content: ''; padding-top: $height; position: absolute; left: 0; right: 0; bottom: 100%; background-image: linear-gradient($angle, $color 50%, transparent 50%); } }
Несколько вещей, на которые следует обратить внимание: миксин применяет position: relative
контейнера, чтобы определить контекст позиции для псевдоэлемента. При использовании этого миксина на абсолютных или фиксированных элементах, возможно, стоит рассмотреть возможность удаления этого объявления из миксина.
Миксин применяет цвет фона к самому контейнеру, а также псевдо-градиент, так как они должны быть синхронизированы в любом случае.
Наконец, высота псевдоэлемента должна быть передана через padding-top
(или padding-bottom
в этом отношении) вместо height
. Поскольку высота выражается в процентах на основе ширины родителя, мы не можем полагаться на height
(так как она вычисляется из высоты родителя).
Заключительные мысли и дальше
В этой статье я выбрал простую версию миксина, которая может не обладать гибкостью и теоретически может представлять следующие проблемы:
- Его невозможно использовать для элемента, уже использующего псевдоэлемент its
::before
. Эту проблему можно решить, добавив необязательный параметр для указания псевдоэлемента, по умолчанию —before
. - Невозможно отобразить наклонный край в нижней части контейнера как
bottom: 0
в настоящее время жестко запрограммирован в ядре миксина. Это может быть решено путем предоставления дополнительной позиции миксину.
Кроме того, моя существующая версия использует математические функции на основе Sass, как это было в проекте Jekyll, не позволяя мне расширять слой Sass. Если вы используете node-sass, вы можете легко передать эти функции из JavaScript в Sass через Eyeglass или Sassport , что было бы намного лучше.
Надеюсь тебе понравилось! Если вы можете придумать что-нибудь, чтобы улучшить это, пожалуйста, не стесняйтесь поделиться в комментариях. 🙂