Макеты с диагональными сечениями довольно популярны уже несколько лет. Это не новый горячий материал , и вы, вероятно, не найдете его в статьях под названием «Тенденции дизайна на 2020 год». Но я думаю, что эта статья вам пригодится. Это инструмент, который дизайнеры и верстальщики могут использовать, чтобы придать динамику всем прямоугольным блокам со скучными углами в 90 градусов.
Раньше данное решение реализовывалось с помощь картинок-треугольников сверху и снизу. Картинки были не обязательно .jpg и .png, использовались так же .svg. Теперь же быстрые и лучше это делать с помощью css. И так начнем…
Базовая разметка
<div class="diagonal-box">
<div class="content"> ... </div>
</div>
Внешний div — это наш раздел полной ширины, тогда как внутренний будет содержать фактическое содержимое. Как правило, у вас будет max-width для внутреннего div и задайте горизонтальное поле auto для его центрирования. На данный момент внешний контейнер получает не что иное, как приятный маленький градиент в качестве background-image.
.diagonal-box {
background-image: linear-gradient(45deg, #6303B1, #ff0099);
}
.content {
max-width: 50em;
margin: 0 auto;
}
Делаем преобразование
Первой идеей для создания диагоналей может быть вращение всего контейнера. Проблема здесь в том, что после поворота поля 100% -width вы должны увеличить ширину выше 100%, чтобы она по-прежнему покрывала весь видимый экран. Величина увеличения ширины увеличивается с высотой сечения.
Поэтому вместо его вращения мы будем использовать менее известное косо-преобразование. Точнее, мы будем использовать SkewY для перекоса сечения вдоль оси Y.
.diagonal-box {
background-image: linear-gradient(45deg, #6303B1, #ff0099);
transform: skewY(-11deg);
}
Внутренняя и внешняя трансформация
Возможно, вы заметили, что теперь весь раздел трансформирован, а вместе с ним и контент, «живущий» в нем. Хотя этот эффект может быть весьма приятным, иногда вы не хотите, чтобы контент наследовал данное преобразование. Чтобы вернуть все в нормальное состояние, вы должны полностью изменить переход:
.diagonal-box {
background-image: linear-gradient(45deg, #654ea3, #eaafc8);
transform: skewY(-11deg);
}
.content {
max-width: 50em;
margin: 0 auto;
transform: skewY(11deg);
}
Используйте псевдоэлемент
Если вы хотите использовать другие переходы на внутреннем элементе (например, некоторую анимацию постепенного появления), вам всегда нужно сначала подумать о добавлении преобразования. Другие преобразования будут размещены поверх первого. Это может стать немного сложным. К счастью, есть решение этой проблемы: вместо преобразования всего контейнера вы можете добавить к нему псевдоэлемент с теми же размерами, а затем исказить это. Наш код будет выглядеть так:
.diagonal-box {
position: relative;
}
.diagonal-box:before {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-image: linear-gradient(45deg, #654ea3, #eaafc8);
transform: skewY(-11deg);
}
.content {
max-width: 50em;
margin: 0 auto;
position: relative;
}
Теперь вся магия происходит в элементе before. Поскольку он позиционируется с использованием абсолютного положения, необходимо добавить два относительных значения положения. Первый относится к внешнему контейнеру, поэтому все его дочерние элементы могут быть расположены относительно его границ. А другой — к внутреннему контейнеру, так что он остается поверх элемента before.
Размещайте свой контент без страха
Возможно, вы заметили, что теперь содержимое не полностью окружено окружающим контейнером. Если вы хотите поместить что-то в контейнер, не боясь, что оно пересечет диагональные линии, вам нужно немного дополнить. Один из способов найти правильное количество отступов, которое вам подходит, — это использовать метод проб и ошибок. Или вы углубляетесь в свои знания тригонометрии и вычисляете точную высоту:
Когда вы посмотрите на иллюстрацию, вы увидите, что мы уже знаем ширину a , поскольку это наша ширина контейнера. Тогда α — это тот же угол, который мы использовали для перекоса нашего элемента (11deg). И мы знаем, что все образует прямоугольный треугольник. С помощью этой информации мы можем вычислить х, используя эту формулу:
x = tan(α) * a / 2
К сожалению, мы не можем использовать это с вычислениями CSS, так как функция тангенса не поддерживается. Это не большая проблема, хотя в большинстве случаев угол остается неизменным, поэтому его можно рассчитать один раз, а затем сохранить. Тем не менее, есть одна точка , где вы должны быть осторожны: Большинство из вас будет использовать в качестве единицы градусы, когда вы делаете преобразование: skewY(-11deg)
. Если вы сделаете это, вы также должны использовать Deg, а не Rad, когда вычисляете тангенс. Стандартный калькулятор Google использует Rad по умолчанию.
Веселье с Custom-Properties
Числа, которые вы получаете из расчета тангенса, выглядят не так хорошо. В этом примере tan (11 °) / 2 дает 0,09719. К счастью, мы можем использовать пользовательские свойства и сделать наш код намного проще для чтения:
:root {
--magic-number: 0.09719; /* tan(11°)/2 */
--content-width: 100vw;
--skew-padding: calc(var(--content-width) * var(--magic-number));
}
@media screen and (min-width: 42em) {
:root {
--content-width: 42em;
}
}
Посмотрим, что здесь происходит. Сначала мы вычисляем наше магическое число и сохраняем его в переменной. Затем мы также храним контент-ширину. Наконец, мы вычисляем требуемое заполнение путем умножения двух предыдущих переменных, а также сохраняем значение в переменной. Поскольку CSS-переменные обновляются в режиме реального времени, мы можем изменить --content-width
и соответственно --skew-padding
скорректировать.
Теперь, когда у вас есть расстояние, сохраненное в переменной, вы можете использовать его в любом месте вашего проекта. Например, вы можете расположить несколько прямоугольников так, чтобы они были выровнены по диагонали. В зависимости от количества ящиков, вам нужно использовать некоторые расчеты. Подобно:transform: translateY(calc(var(--skew-padding) / 2));
Здесь вы можете увидеть рабочий пример. Значения для магического числа обновляются с помощью JavaScript, остальное — чистый CSS.
See the Pen Diagonal Layouts in 2020 by Nils Binder (@enbee81) on CodePen.