Главная » Статьи » Использование масок CSS для создания зубчатых краев

Использование масок CSS для создания зубчатых краев

Использование масок CSS для создания зубчатых краев

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

Я начал со старого доброго HTML-изображения в элементе оболочки:

<div class="jagged-wrapper"> <img src="path-to-image.jpg" />
</div>

Затем я использовал псевдо-элемент ::after, чтобы добавить в него повторяющееся фоновое изображение:

.jagged-wrapper::after { content: ""; background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1" preserveAspectRatio="none"><polygon style="fill:white;" points="1,0 1,1 0,1 "/></svg>'); background-size: 30px 30px; width: 100%; height: 30px; position: absolute; bottom: 0px; right: 0; z-index: 2;
}

Это фоновое изображение? Это код SVG, преобразованный в URI данных. Вот оригинальный код SVG. У Криса есть хорошее видео, где он описывает преобразование.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1" preserveAspectRatio="none"> <polygon style="fill: white;" points="1,0 1,1 0,1 "/>
</svg>

«Вот и все!» — подумал я.

Хотя это, безусловно, работает, черт возьми, это хлопотно. Так сложно читать разметку SVG в CSS. Кроме того, раздражает необходимость не забывать цитировать их (например url(‘data:image/svg+xml’…)). Конечно, мы можем закодировать SVG с помощью base64, чтобы избежать этого, но это еще более раздражает. Кроме того, SVG должен быть заполнен тем же цветом фона, что и изображение (или везде, где он используется), иначе он не будет работать.

Подождите, не для этого ли предназначены маски? Да! Да, для этого и нужна маскировка.

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

Маскирование в значительной степени поддерживается везде — по крайней мере, простым способом, о котором я говорю здесь. Мы также говорим о чем-то, что может быть реализовано с прогрессивным улучшением; если маски не поддерживаются в данном браузере, то вы просто не получите эффект зазубренного края. Определенно не конец света.

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

Одним из способов работы маски CSS является предоставление изображения с альфа-каналом в виде mask-image. Базовый — маскируемый — элемент становится (полу) прозрачным в той степени, в которой это задает альфа-канал mask-image. Таким образом, если изображение маски представляет собой белый чайник на прозрачном фоне, замаскированный элемент будет обрезан по форме чайника и все, что снаружи будет скрыто.

Нам нужно одно «пилообразное» изображение, похожее на SVG выше, где верхняя левая половина заполнена белым, а нижняя левая половина полупрозрачная. И, в идеале, это изображение не должно быть реальным SVG, так как это вернуло бы нас в ужасный беспорядок URI данных, в котором мы были прежде.

В этот момент вы можете подумать: «Эй, просто вставьте SVG непосредственно в CSS, определите в нем маску, а затем укажите CSS на идентификатор маски в SVG!»

Хорошая идея! И это, безусловно, выполнимо, если вы можете редактировать HTML. Однако в конкретном описываемом проекте я работал с WordPress, и на самом деле я хотел ограничить изменения только CSS, а не вставлять дополнительные части в HTML. Это было бы намного больше работы. Я не думаю, что это что-то необычное. Мы обычно стараемся избегать семантически бесполезных элементов-оболочек только для того, чтобы обеспечить привязки к стилю, но я чувствую, что это также относится к добавлению всей разметки SVG в документ… или даже в шаблон WordPress.

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

.el { linear-gradient( to bottom right, white, white 50%, transparent 50%, transparent );
}

Здесь он размещается на радиальном фоне, так что вы можете видеть, что он действительно прозрачный:

Отлично! Мы можем просто использовать это как mask-image для нашего баннера, верно? Нам нужно установить mask-size, что делается, как background-size, и mask-repeat, как background-repeat, и все в порядке?

К сожалению нет. Не все так просто. Первая причина заключается в том, что, если вы не используете Firefox, вы, скорее всего, не увидите никакой маскировки в этом примере. Это связано с тем, что Blink и WebKit все еще поддерживают маскирование только с вендорным префиксом на момент написания статьи. Это означает, что нам нужны префиксные -webkit- версии всего.

Помимо префиксов поставщиков, то, что мы делаем, также концептуально неправильно. Если мы ограничим маску только нижней полосой изображения с помощью mask-size, то у остальной части изображения вообще не будет mask-image, что полностью его замаскирует. В результате мы не можем использовать зубчатое изображение в качестве маски. Нам нужно прямоугольное mask-image размером с полное изображение, с пилообразным краем внизу. Что-то вроде этого:

Мы создадим его с помощью двух градиентных изображений. Первое изображение — это тот же пилообразный треугольник, что и выше, для которого установлено repeat-x и позиционирование bottom, так что он повторяется только вдоль нижнего края изображения. Второе изображение — это еще один градиент, прозрачный для нижних 30 пикселей (чтобы не закрывать пилообразные зубцы), непрозрачный выше этого (что в демонстрации показано переходом от черного к белому) и занимающий весь размер элемента.

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

И мы это сделали!

Автор: Stuart Langridge

Источник: https://css-tricks.com

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