От автора: посмотрите на заголовок блога на сайте оригинальной статьи, он имеет наклон. Одна из моих любимых вещей в новом дизайне этого сайта. Используемой мной технике не важен размер экрана, угол наклона будет всегда одним и тем же. На фон можно поставить изображение, а для создания такого эффекта мне потребовался всего один HTML тег и никаких псевдоэлементов. Как я это сделал.
Требования
Если коротко, то у данного способа были требования.
смотреться одинаково с любым размером экрана;
поддерживать фоновые изображения и текст переднего плана;
работать на всех устройствах (за IE не беспокойтесь).
Ну и если можно максимально упростить HTML и CSS, но это уже как бонус, а не требование.
Начальная идея
Первоначально для создания наклонных граней я хотел использовать поворот на всем элементе в свойстве transform. Этот подход приводит к быстро возрастающей сложности.
1 2 3 4 |
header { width:100%; transform:rotate(2deg); } |
Поворачивая элемент, мы оголяем задний фон в верхнем левом и правом углу. Это можно поправить, сделав внутренний элемент шире и добавив отрицательное смещение, чтобы элемент правильно закрывал верхний левый и правый углы:
1 2 3 4 5 6 |
header { width:110%; top:-5%; left:-5%; transform:rotate(2deg); } |
Далее добавляем на страницу или дополнительный элемент overflow:hidden, чтобы нас не смущала горизонтальная полоса прокрутки:
1 2 3 4 5 6 7 8 9 10 |
body { overflow:hidden; } header { width:110%; top:-5%; left:-5%; transform:rotate(2deg); } |
Смотрится хорошо, но что будет, если добавить текст?
Текст не только наклонен, но и немного уходит за левую границу. Чтобы поправить текст, нам нужно повернуть его в противоположном направлении и сместить.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
body { overflow:hidden; } header { width:110%; top:-5%; left:-5%; transform:rotate(2deg); } header p { margin-left:5%; transform:rotate(-2deg); } |
До этих самых пор все работает просто замечательно. Проблемы начинаются, когда вы переходите с фиксированной ширины на адаптивную. Тот же самый элемент, только шире:
Сверху справа опять начинает вылезать задний фон. Единственный выход – растянуть заголовок за видимые пределы. Так будет при каждом увеличении экрана, что сильно затрудняет способ и делает его ненадежным.
Кроме того, при использовании трансформаций по краям наблюдается легкая пикселизация. Этот баг исправят в новых версиях браузеров, однако сейчас это смотрится не очень красиво.
Псевдоэлемент ::after
Другая часто используемая техника – использование свойства transform на псевдоэлементе ::after, а не самом элементе. По сравнению с предыдущим кодом у этого метода есть несколько преимуществ:
не нужно думать о том, что в верхних левом и правом углах будет выглядывать фон;
не нужно поворачивать обратно контент.
Давайте попробуем:
1 2 3 4 5 6 7 8 9 |
header::after { position:absolute; content: " "; display:block; left:-5%; bottom:-10px; transform:rotate(2deg); width:110%; } |
Я добавил немного прозрачности, чтобы было понятно расположение элементов. Метод работает, однако нужно слегка сдвинуть элемент after вверх, чтобы он полностью закрывал нижнюю грань блока. Как и в примерах выше, псевдоэлемент должен быть немного шире, чтобы слева и справа не вылезали углы. Я отключил свойство overflow:hidden;, чтобы вы увидели, насколько псевдоэлемент вылезает за видимые границы.
Эффект хорошо смотрится только, когда фон блока и псевдоэлемента совпадают.
Псевдоэлемент ::after с рамкой
В CSS можно комбинировать видимые и прозрачные рамки для создания треугольников, которые будут заменять наклонные грани. Давайте создадим псевдоэлемент ::after с наклонной рамкой:
1 2 3 4 5 6 7 8 9 10 11 |
header::after { position:absolute; content: " "; display:block; left:0; bottom:-20px; width:100%; border-style: solid; border-width: 0 100vw 20px 0; border-color: transparent rgba(0,0,0,0.4) transparent transparent; } |
Смотрится хорошо, у данного способа намного лучше сглаживание. Метод работает даже, если сильно расширить блок (при условии, что используется сопоставимая ширина рамки):
Я также видел, как вместо рамок используют фоновое изображение формата SVG, которое на 100% ширины и высоты занимает область элемента ::after. Результат будет тот же самый.
На данный момент лучше всего смотрится способ с рамками. В нем не так много кода, однако метод неидеальный по нескольким причинам:
используется еще один абсолютно позиционированный элемент, о котором нужно помнить;
трудно поддерживать нужный угол наклона;
можно использовать только монотонные фоновые цвета.
На данный момент ни один из моих примеров не использовал фоновые изображения (это само по себе сложно), но иногда мне действительно хочется поставить в заголовок или футер фоновое изображение. Псевдоэлемент ::after вообще не поддерживает такой эффект. С трансформированным хедером возникнут свои проблемы, связанные с позиционированием фонового рисунка.
Все вышеописанные варианты либо сложны в плане кода, либо не достаточно гибкие, когда нужно одинаково выглядеть на всех экранах.
Метод на clip-path
Трансформации и рамки с ::after не подходят, остался только один способ – clip-path.
Clip-path не очень хорошо поддерживается. Он работает только в браузерах Webkit, Blink и Gecko. Для последнего также нужен тег SVG. К счастью для меня я могу спокойно использовать этот метод на своем блоге.
Добавить clip-path довольно просто. Нужно воспользоваться функцией polygon и создать трапецию (прямоугольник с наклонными гранями):
1 2 3 4 5 6 7 8 |
header { clip-path: polygon( 0 0, /* лево верх */ 100% 0, /* право верх */ 100% 100%, /* право низ */ 0 90% /* лево низ */ ); } |
Все отлично работает! Метод делает все то, что не могут предыдущие способы. Можно поставить фоновое изображение, ничего не вылезает за края, края острые, а для создания эффекта потребовался всего один тег header.
Единственный недостаток – трапеция привязана к элементу. Если у элемента изменится соотношение ширины и высоты, то изменится и угол наклона нижней грани. На мобильных устройствах наклон будет сильным, а на ретина экранах почти незаметным. Тот же самый clip-path, но на широком элементе:
Наклон намного меньше, эффект тоже меньше. А мы хотим, чтобы наклон был одинаковым вне зависимости от ширины элемента. Я решил эту проблему при помощи единиц измерения vw.
Вычисления на основе ширины
Проценты в объявлении трапеции привязывают точки фигуры к высоте элемента. Чтобы угол наклона был постоянным, нам нужно менять значения высоты. Если равномерно менять значения, угол наклона будет оставаться неизменным.
Сделать это можно при помощи единиц измерения vw. С их помощью мы будем определять позицию левой нижней точки относительно нижней грани элемента. Для этого в CSS нам понадобится функция calc():
1 2 3 4 5 6 7 8 |
header { clip-path: polygon( 0 0, 100% 0, 100% 100%, 0 calc(100% - 6vw) ); } |
Если теперь изменить ширину, то позиция левой нижней точки будет опускаться, создавая эффект того, что угол наклона не меняется.
Если хотите сделать наклонной верхнюю грань, это будет еще проще. Заменяете первую строку на «6vw 0», даже не нужна функция calc().
Прокрутите страницу к хедеру или футеру, посмотрите эффект в действии.
Поддержка в Firefox
К сожалению, Firefox поддерживает только SVG полигоны для записи clip path. Пока в этом браузере не будет нормальной поддержки, у всех будут разные углы.
Создание clip-path для Firefox требует знаний SVG. SVG clipPaths принимает как значения типа пикселей, так и значения с плавающей точкой от 0 до 1 для процентов. В SVG есть атрибут clipPathUnits=»objectBoundingBox», с помощью которого браузер может получить размеры элемента и применить clip-path к нему. Без атрибута будут использоваться размеры SVG. Если совместить значения с плавающей точкой и этот атрибут, можно получить трапецию, которую мы создали выше:
1 2 3 4 5 6 7 |
<svg xmlns="//www.w3.org/2000/svg" xmlns:xlink="//www.w3.org/1999/xlink"> <defs> <clipPath id="header" clipPathUnits="objectBoundingBox"> <polygon points="0 0, 1 0, 1 1, 0 0.87" /> </clipPath> </defs> </svg> |
Запись @moz-document – это хак, чтобы правило не применялось в других браузерах. Или же, как заметил Sven Wolfermann, просто задайте url() clip-path перед polygon() clip-path, и Firefox автоматически сделает фолбек. Когда в Firefox добавится поддержка (намечается на середину апреля 2017), браузер автоматически начнет использовать функцию polygon().
Кроме одинакового наклона на разных экранах браузер использует все бонусы CSS clip-path: элемент имеет нормальное расположение, углы отлично сглаживаются, а фон применяется ровно так, как вы ожидаете.
Наклоненные под одним углом края в CSS
Собственно, вот так можно создать в CSS наклоненные под одним углом грани. Не нужно использовать overflow:hidden, можно поставить на фон изображение, а также для создания эффекта нужен всего один тег.
Источник: //kilianvalkhof.com/
Редакция: Команда webformyself.
Комментарии (4)