Упрощаем фоновые рисунки c помощью конических градиентов

Один из известных способов создания повторяющихся фоновых узоров — это применение
линейных градиентов. Но если использовать с этой же целью conic-gradient(), требуется значительно меньшее количество CSS-кода. Данное преимущество конических градиентов проиллюстрировано в статье несколькими примерами, взятыми из галереи Лии Веру.

Нам предстоит рассмотреть

Если вдруг вы пропустили важную новость, Firefox теперь поддерживает конические градиенты.

75 версия Firefox, вышедшая 7 апреля, дала возможность, перейдя в редактор настроек about:config, найти параметр layout.css.conic-gradient.enabled и поменять его значение на true. Значение по умолчанию — false, и переключить его можно двойным кликом.

Активируем конические градиенты в Firefox 75+

Теперь мы готовы проверить, как отрабатывает наш CSS в разных браузерах, включая Firefox.

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

Что мне особенно нравится в конических градиентах, так это то, что они значительно облегчают создание фоновых узоров. Давайте возьмем несколько фоновых рисунков из галереи, созданной Лией Веру около 10 лет назад на основе linear-gradient(), и посмотрим, насколько их можно упростить, используя конический градиент.

Пирамиды

Орнамент из пирамид

В данном примере используются четыре линейных градиента:

background:   linear-gradient(315deg, transparent 75%, #d45d55 0) -10px 0,   linear-gradient(45deg, transparent 75%, #d45d55 0) -10px 0,   linear-gradient(135deg, #a7332b 50%, transparent 0) 0 0,   linear-gradient(45deg, #6a201b 50%, #561a16 0) 0 0 #561a16; background-size: 20px 20px; 

Здесь довольно много CSS, да и выглядит он, пожалуй, довольно устрашающе. С первого взгляда сложно понять, как эти градиенты в совокупности образуют узор из пирамид. У меня определенно не получилось, и пришлось потратить некоторое время на то, чтобы это осмыслить, хотя, что касается CSS, я весьма неплохо разбираюсь в градиентах. Так что не переживайте, если не понимаете, как создан этот градиентный фон, потому что, во-первых, это действительно сложно, а во-вторых, даже нет необходимости в этом разбираться.

С помощью CSS-функции conic-gradient() можно получить аналогичный результат гораздо более простым способом. Нам понадобится всего один слой фона, и это вместо четырех!

При создании повторяющихся орнаментов мне нравится размечать прямоугольники, определяемые свойством background-size, равноудаленными вертикальными и горизонтальными линиями. Что касается данного примера, достаточно очевидно, что мы имеем дело с прямоугольниками, и понятно, где проходят их границы. Но в более сложных случаях указанная техника может оказаться действительно полезной.

Выделяем элементы орнамента

По умолчанию конические градиенты начинаются в точке, соответствующей положению стрелки часов, указывающей на 12, и далее распределяются по часовой стрелке. Но в нашем случае нужно сдвинуть начальную точку на угол 45° по часовой стрелке, а затем поочередно отрисовать треугольники, каждый из которых занимает четверть (25%) площади квадрата.

Элемент орнамента на основе конического градиента с резкими переходами цветов через каждые 25% с началом, отстоящим от вертикальной оси на 45°. См. демо

Это означает, что узор из пирамид можно сократить следующим образом:

$s: 20px; background:   conic-gradient(from 45deg,      #561a16 25%,      #6a201b 0% 50%,      #a7332b 0% 75%,      #d45d55 0%)      50%/ #{$s $s}; 

Теперь CSS не только выглядит проще, но и занимает 103 байта вместо 260. Так что количество кода, необходимое для создания фонового орнамента, сократилось более чем вдвое.

В примере используется двойное позиционирование, которое тоже хорошо поддерживается браузерами на сегодняшний день.

Пример можно посмотреть в действии на CodePen:

Шахматный узор

Шахматный узор

Данный узор создан с помощью двух линейных градиентов:

background-color: #eee; background-image:   linear-gradient(45deg, black 25%, transparent 25%,      transparent 75%, black 75%, black),   linear-gradient(45deg, black 25%, transparent 25%,      transparent 75%, black 75%, black); background-size: 60px 60px; background-position: 0 0, 30px 30px;

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

Как и в предыдущем случае, проведем вертикальные и горизонтальные линии, чтобы визуально выделить прямоугольники, созданные с помощью свойства background-size.

Выделяем элементы орнамента

Глядя на квадрат на рисунке, обведенный темно-розовым цветом, мы видим, что в данном случае конический градиент начинается в дефолтной исходной позиции, соответствующей положению стрелки часов, указывающей на 12. Четверть квадрата имеет черную заливку, следующая четверть — светло-серую, а затем идет повтор: снова черная и светло-серая четверти.

Участок узора, созданного с помощью конического градиента с резкими переходами цветов через каждые 25%, с началом в исходной точке по умолчанию. После 50% рисунок повторяется. Cм. демо.

Такое повторение на второй половине участка от 0 до 100% означает, что можно использовать repeating-conic-gradient(). С помощью последнего мы получим 76 байтов скомпилированного CSS вместо 263, сократив таким образом код более чем на 70%:

$s: 60px; background:   repeating-conic-gradient(#000 0% 25%, #eee 0% 50%)      50%/ #{$s $s};

Демо можно посмотреть на CodePen:

Шахматный рисунок по диагонали

Шахматный узор по диагонали

Данный рисунок также образован двумя линейными градиентами:

background-color: #eee; background-image:    linear-gradient(45deg, black 25%, transparent 25%,      transparent 75%, black 75%, black),   linear-gradient(-45deg, black 25%, transparent 25%,      transparent 75%, black 75%, black); background-size: 60px 60px;

Проведем горизонтальные и вертикальные линии, чтобы разбить рисунок на одинаковые квадраты:

Выделяем элементы узора

Получается практически тот же шахматный орнамент, что и в предыдущем примере. Единственное отличие состоит в том, что градиент начинается не в дефолтной исходной точке, а сдвинут относительно нее на 45° по часовой стрелке.

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

Обратите внимание, что демо не работает в браузерах, не поддерживающих конический градиент.

Итак, код выглядит следующим образом:

b$s: 60px; background:   repeating-conic-gradient(from 45deg,      #000 0% 25%, #eee 0% 50%)    50%/ #{$s $s};

Демо можно посмотреть на CodePen:

Код опять же не только стал проще для восприятия, но и сократился почти на две трети: получилось всего 83 байта скомпилированного СSS вместо 229.

Треугольники (половины ромбов)

Орнамент из треугольников

Рассматриваемый рисунок образован сочетанием четырех линейных градиентов:

background: #36c; background:   linear-gradient(115deg, transparent 75%, rgba(255,255,255,.8) 75%) 0 0,   linear-gradient(245deg, transparent 75%, rgba(255,255,255,.8) 75%) 0 0,   linear-gradient(115deg, transparent 75%, rgba(255,255,255,.8) 75%) 7px -15px,   linear-gradient(245deg, transparent 75%, rgba(255,255,255,.8) 75%) 7px -15px,   #36c; background-size: 15px 30px;

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

Выделяем элементы узора

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

Параллельные линии

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

Фрагмент рисунка, полученного с помощью конического градиента с резкими переходами цвета. Линии перехода цвета либо горизонтальны, либо проходят через вершины прямоугольника. Начало градиента сдвинуто относительно вертикальной оси на угол β. См. демо.

На рисунке представлен конический градиент, начало которого смещено относительно начала по умолчанию на угол β. Первый участок градиента (верхний правый маленький треугольник) доходит до угла α, второй участок (нижний правый темный треугольник) — до угла 2·α. Третий участок (нижний светлый треугольник) завершается в точке, соответствующей 180° (50%) относительно начала градиента. Четвертый участок (нижний левый темный треугольник) доходит до угла 180° + α, а пятый (верхний левый светлый треугольник) — до угла 180° + 2·α, тогда как шестой занимает оставшуюся часть круга.

Получаем углы α и β (демо)

Для треугольника, выделенного справа на рисунке, получаем следующее:

tan(α) = (.5·h)/(.5·w) = h/w;

Зная ширину (w) и высоту (h) фрагмента рисунка, можно вычислить величины углов α и β:

α = atan(h/w) β = 90° - α

В результате получаем следующий код, необходимый для отрисовки узора:

$w: 15px; $h: 30px; $a: atan($h/$w)*180deg/pi(); $b: 90deg - $a; $c0: #36c; $c1: #d6e0f5;  html {   background:      conic-gradient(from $b,        $c1 0% $a,        $c0 0% 2*$a,        $c1 0% 50%,        $c0 0% 180deg + $a,        $c1 0% 180deg + 2*$a,        $c0 0%)      0 0/ #{$w $h}; }

Таким образом, получается всего 157 байтов скомпилированного CSS вместо 343. Ниже можно посмотреть результат:

Чтобы увидеть, как рисунок сплющивается и растягивается при различных соотношениях ширины и высоты, вы можете поэкспериментировать с их значениями в Sass-коде.

Существует особый случай, когда величина угла между 2*$a и 50% (180deg) равна $a, откуда следует, что величина $a равна 60deg, то есть равнобедренные треугольники являются равносторонними. В этом случае объем скомпилированного CSS можно сократить до менее чем 100 байтов за счет применения повторяющегося градиента:

$a: 60deg; $b: 90deg - $a; $w: 15px; $h: $w*tan($a); $c0: #36c; $c1: #d6e0f5;  html {   background:      repeating-conic-gradient(from $b,        $c1 0% $a, $c0 0% 2*$a)      0 0/ #{$w $h} }

Ниже можно посмотреть демо:

Бонус: фон из пересекающихся линий

Примеры фонов из пересекающихся линий

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

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

Структура бонусного фонового рисунка

Градиент распределен вокруг точки пересечения прямых с координатами (x,y). Он начинается от угла β, образованного вертикальной осью и отрезком прямой, расположенным в верхнем правом углу. Градиент имеет резкие переходы цветов на участках, соответствующих углам α, 50% (180°) и 180° + α.

Если необходимо создать несколько элементов с подобными фонами, образуемыми пересекающимися линиями разных цветов, для этого идеально подойдут CSS-переменные:

.panel {   background:      conic-gradient(from var(--b) at var(--xy),        var(--c0) var(--a), var(--c1) 0% 50%,        var(--c2) 0% calc(180deg + var(--a)), var(--c3) 0%); }

Нужно всего лишь задать значения положения центра градиента (—xy), угла начала градиента (—b), первого угла перехода цвета (—a) и цветов палитры с —c0 до —c3.

.panel {   /* same as before */      &:nth-child(1) {     --xy: 80% 65%;      --b: 31deg;     --a: 121deg;      --c0: #be5128;     --c1: #ce9248;     --c2: #e4c060;     --c3: #db9c4e   }      /* similarly for the other panels */ }

Вместо того, чтобы захардкодить значения указанных параметров, можно сгенерировать случайные значения или же получить их из объекта с помощью препроцессоров CSS и HTML. В последнем случае можно применить встроенные стили, что я и сделала в своем демо на Codepen:

В данном примере в качестве аргументов conic-gradient() используются CSS-переменные, поэтому демо не работает в браузерах, которые их не поддерживают.

На этом я заканчиваю статью. Надеюсь она вам понравилась и дала некоторое представление о том, как можно облегчить себе жизнь с помощью конических градиентов.

ссылка на оригинал статьи https://habr.com/ru/post/509016/

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

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