Наклоненные под одним углом края в CSS

Наклоненные под одним углом края в CSS

От автора: посмотрите на заголовок блога на сайте оригинальной статьи, он имеет наклон. Одна из моих любимых вещей в новом дизайне этого сайта. Используемой мной технике не важен размер экрана, угол наклона будет всегда одним и тем же. На фон можно поставить изображение, а для создания такого эффекта мне потребовался всего один HTML тег и никаких псевдоэлементов. Как я это сделал.

Требования

Если коротко, то у данного способа были требования.

смотреться одинаково с любым размером экрана;

поддерживать фоновые изображения и текст переднего плана;

работать на всех устройствах (за IE не беспокойтесь).


Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Ну и если можно максимально упростить HTML и CSS, но это уже как бонус, а не требование.

Начальная идея

Первоначально для создания наклонных граней я хотел использовать поворот на всем элементе в свойстве transform. Этот подход приводит к быстро возрастающей сложности.

header {
  width:100%;
  transform:rotate(2deg);
}

Наклоненные под одним углом края в CSS

Поворачивая элемент, мы оголяем задний фон в верхнем левом и правом углу. Это можно поправить, сделав внутренний элемент шире и добавив отрицательное смещение, чтобы элемент правильно закрывал верхний левый и правый углы:

header {
  width:110%;
  top:-5%;
  left:-5%;
  transform:rotate(2deg);
}

Наклоненные под одним углом края в CSS

Далее добавляем на страницу или дополнительный элемент overflow:hidden, чтобы нас не смущала горизонтальная полоса прокрутки:

body {
  overflow:hidden;
}

header {
  width:110%;
  top:-5%;
  left:-5%;
  transform:rotate(2deg);
}

Наклоненные под одним углом края в CSS

Смотрится хорошо, но что будет, если добавить текст?

Наклоненные под одним углом края в CSS

Текст не только наклонен, но и немного уходит за левую границу. Чтобы поправить текст, нам нужно повернуть его в противоположном направлении и сместить.

body {
  overflow:hidden;
}

header {
  width:110%;
  top:-5%;
  left:-5%;
  transform:rotate(2deg);
}

header p {
  margin-left:5%;
  transform:rotate(-2deg);
}

Наклоненные под одним углом края в CSS

До этих самых пор все работает просто замечательно. Проблемы начинаются, когда вы переходите с фиксированной ширины на адаптивную. Тот же самый элемент, только шире:

Наклоненные под одним углом края в CSS

Сверху справа опять начинает вылезать задний фон. Единственный выход – растянуть заголовок за видимые пределы. Так будет при каждом увеличении экрана, что сильно затрудняет способ и делает его ненадежным.

Кроме того, при использовании трансформаций по краям наблюдается легкая пикселизация. Этот баг исправят в новых версиях браузеров, однако сейчас это смотрится не очень красиво.

Псевдоэлемент ::after

Другая часто используемая техника – использование свойства transform на псевдоэлементе ::after, а не самом элементе. По сравнению с предыдущим кодом у этого метода есть несколько преимуществ:

не нужно думать о том, что в верхних левом и правом углах будет выглядывать фон;

не нужно поворачивать обратно контент.

Давайте попробуем:

header::after {
  position:absolute;
  content: " ";
  display:block;
  left:-5%;
  bottom:-10px;
  transform:rotate(2deg);
  width:110%;
}

Наклоненные под одним углом края в CSS

Я добавил немного прозрачности, чтобы было понятно расположение элементов. Метод работает, однако нужно слегка сдвинуть элемент after вверх, чтобы он полностью закрывал нижнюю грань блока. Как и в примерах выше, псевдоэлемент должен быть немного шире, чтобы слева и справа не вылезали углы. Я отключил свойство overflow:hidden;, чтобы вы увидели, насколько псевдоэлемент вылезает за видимые границы.

Эффект хорошо смотрится только, когда фон блока и псевдоэлемента совпадают.

Псевдоэлемент ::after с рамкой

В CSS можно комбинировать видимые и прозрачные рамки для создания треугольников, которые будут заменять наклонные грани. Давайте создадим псевдоэлемент ::after с наклонной рамкой:

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;
}

Наклоненные под одним углом края в CSS

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Узнать подробнее

Смотрится хорошо, у данного способа намного лучше сглаживание. Метод работает даже, если сильно расширить блок (при условии, что используется сопоставимая ширина рамки):

Наклоненные под одним углом края в CSS

Я также видел, как вместо рамок используют фоновое изображение формата SVG, которое на 100% ширины и высоты занимает область элемента ::after. Результат будет тот же самый.

На данный момент лучше всего смотрится способ с рамками. В нем не так много кода, однако метод неидеальный по нескольким причинам:

используется еще один абсолютно позиционированный элемент, о котором нужно помнить;

трудно поддерживать нужный угол наклона;

можно использовать только монотонные фоновые цвета.

На данный момент ни один из моих примеров не использовал фоновые изображения (это само по себе сложно), но иногда мне действительно хочется поставить в заголовок или футер фоновое изображение. Псевдоэлемент ::after вообще не поддерживает такой эффект. С трансформированным хедером возникнут свои проблемы, связанные с позиционированием фонового рисунка.

Все вышеописанные варианты либо сложны в плане кода, либо не достаточно гибкие, когда нужно одинаково выглядеть на всех экранах.

Метод на clip-path

Трансформации и рамки с ::after не подходят, остался только один способ – clip-path.

Clip-path не очень хорошо поддерживается. Он работает только в браузерах Webkit, Blink и Gecko. Для последнего также нужен тег SVG. К счастью для меня я могу спокойно использовать этот метод на своем блоге.

Добавить clip-path довольно просто. Нужно воспользоваться функцией polygon и создать трапецию (прямоугольник с наклонными гранями):

header {
  clip-path: polygon(
 0 0, /* лево верх */
 100% 0, /* право верх */ 
 100% 100%, /* право низ */
 0 90% /* лево низ */
  );
}

Наклоненные под одним углом края в CSS

Все отлично работает! Метод делает все то, что не могут предыдущие способы. Можно поставить фоновое изображение, ничего не вылезает за края, края острые, а для создания эффекта потребовался всего один тег header.

Единственный недостаток – трапеция привязана к элементу. Если у элемента изменится соотношение ширины и высоты, то изменится и угол наклона нижней грани. На мобильных устройствах наклон будет сильным, а на ретина экранах почти незаметным. Тот же самый clip-path, но на широком элементе:

Наклоненные под одним углом края в CSS

Наклон намного меньше, эффект тоже меньше. А мы хотим, чтобы наклон был одинаковым вне зависимости от ширины элемента. Я решил эту проблему при помощи единиц измерения vw.

Вычисления на основе ширины

Проценты в объявлении трапеции привязывают точки фигуры к высоте элемента. Чтобы угол наклона был постоянным, нам нужно менять значения высоты. Если равномерно менять значения, угол наклона будет оставаться неизменным.

Сделать это можно при помощи единиц измерения vw. С их помощью мы будем определять позицию левой нижней точки относительно нижней грани элемента. Для этого в CSS нам понадобится функция calc():

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. Если совместить значения с плавающей точкой и этот атрибут, можно получить трапецию, которую мы создали выше:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://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, можно поставить на фон изображение, а также для создания эффекта нужен всего один тег.

Источник: https://kilianvalkhof.com/

Редакция: Команда webformyself.


Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Самые свежие новости IT и веб-разработки на нашем Telegram-канале

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (4)

  1. Дмитрий

    Почему вы не указали в самом начале для body — position:relative, а для header — position:absolute ??
    Разве без этого можно двигать top и left ?

    • Андрей Кудлай

      По ссылке в конце статьи можно посмотреть оригинальную статью, в которой можно изучить верстку всех элементов. Там есть 2 блока, для них указано относительное позиционирование и дочерний смещается относительно родительского.

  2. Дмитрий

    Ну и ну… Вы хоть бы код перечитали, прежде чем переводить статью какой-то англоязычной школоты.
    Позиционирование он начинает указывать только начиная с того варианта, где псевдоэлементы.
    Но даже если указать для первого случая position, очень интересно, как у него получится позиционировать по вертикали:


    body {
    overflow:hidden;
    }

    header {
    width:110%;
    top:-5%;
    left:-5%;
    transform:rotate(2deg);
    }

    Не пробовали смещать по вертикали? Наверно еще что-то дописать надо кроме position ?

    • Андрей Кудлай

      >> очень интересно, как у него получится позиционировать по вертикали
      Ну так в оригинальной статье ведь есть примеры, Вы их смотрели? Они ведь работают. Код, который дается — это не полный код.

      >> Позиционирование он начинает указывать только начиная с того варианта, где псевдоэлементы.
      Насколько я вижу, позиционирование есть и до того.

      >> Не пробовали смещать по вертикали? Наверно еще что-то дописать надо кроме position ?
      Только что попробовал в оригинальной статье, работает.
      Честно говоря, не совсем понимаю, чем вызвано Ваше недовольство? Автор реализует некую задачу, показывает примеры, они работают, это видно в оригинале статьи, где есть примеры. Так что не так? Единственная претензия может быть к тому, что автор зачем-то вместо реальных блоков, с которыми работает, указывает body и header. Но в этом случае никто не мешает проинспектировать примеры со страницы, собственно, для этого там примеры и есть.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree