Изучая графику на Dribbble или Behance, вы найдёте там дизайнеров, использующих простую технику добавления в изображения текстур: шум. Добавление шума делает сплошные цвета или плавные градиенты, например, тени, более реалистичными. Но несмотря на любовь дизайнеров к текстурам, шум редко применяется в веб-дизайне.
В этой статье мы при помощи CSS и SVG сгенерируем цветной шум, позволяющий добавлять текстуру к градиенту.
Интерактивная песочница
Проще всего разобраться, что происходит, поиграв в песочнице с параметрами, создающими слои.
SVG-шум и CSS-градиенты
Базовая техника, описываемая в этой статье, создана на основе ответа Криса Пахла на вопрос в Stack Overflow: можно ли добавить шум к CSS-градиенту?
Хитрость заключается в создании шума при помощи SVG-фильтра с последующим использованием этого шума в качестве фона. Подложите под него градиент, увеличьте яркость и контрастность, вот и всё — у вас получился градиент с плавным дизерингом.
Основные ингредиенты
Вот с чем мы будем работать:
SVG turbulence: это наш фильтр шума.
Фон с градиентом и SVG: дальше мы добавляем этот фильтр в CSS в качестве фонового изображения, сочетающего фильтр с CSS-градиентом.
Повышение яркости и контрастности: затем мы применяем
filter
CSS, чтобы увеличить яркость и контрастность шума.Смешение градиентов: наконец, можно использовать
mix-blend-mode
для дальнейшей фильтрации цветов и смешения градиентов.
Давайте подробно рассмотрим каждый из этапов.
Использование SVG turbulence
Работая с SVG, мы можем задавать фильтры, и один из таких фильтров позволяет нам создать шум Перлина. Он называется <feTurbulence>
, для него можно задать атрибуты, например, выбрать, «турбулентность» это или «шум», указать размер зерна. Бенсе Сабо объясняет это гораздо подробнее, демонстрируя, как это можно использовать для создания паттернов.
<svg viewBox="0 0 200 200" xmlns='http://www.w3.org/2000/svg'>
<filter id='noiseFilter'>
<feTurbulence
type='fractalNoise'
baseFrequency='0.65'
numOctaves='3'
stitchTiles='stitch' />
</filter>
<rect width='100%' height='100%' filter='url(#noiseFilter)' />
</svg>
Этот пример SVG создаёт фильтр и рендерит элемент <rect>
, который можно использовать для зернистых градиентов. Обратите внимание, что <filter>
SVG задаётся отдельно от <rect>
, а <rect>
просто ссылается на него.
Можно поэкспериментировать с изменением некоторых из свойств <feTurbulence>
Мы сохраним этот SVG как отдельный файл. В используемых в статье демо для получения SVG мы ссылаемся на внешнюю ссылку. Однако на практике вы будете ссылаться на локальный файл или собственную CDN. По какой-то странной причине на SVG нельзя сослаться по его id
в CSS, но можно встроить SVG, как мы показали в демо. Мы не применяем этот приём в демо ради повышения читаемости.
Создание CSS-фона при помощи SVG и градиента
После того, как мы сохранили куда-нибудь файл SVG, можно ссылаться на него по URL или пути и использовать его вместе с градиентом в background
CSS.
.noise {
/* ... /
background:
linear-gradient(to right, blue, transparent),
url(https://grainy-gradients.vercel.app/noise.svg);
}
Здесь важен порядок. В этом конкретном примере мы хотим, чтобы сплошной цвет (то есть с отсутствующим шумом) переходил в шум, а затем в другой цвет. Также мы хотим, чтобы один конец градиента был прозрачным, чтобы сквозь него был виден шум.
Вот так:
Однако выглядит это не очень красиво, потому что шум слишком размыт. Нам нужно «потрепать» его и сделать более зернистым. И для этого нам понадобится…
Повышение яркости и контрастности
Добавление filter
CSS делает шум более очевидным, сдвигая самые тусклые цвета в сторону белого или чёрного. Фильтр применяется ко всему <div>
, поэтому синий в самой левой части отличается от чистого синего, с которого мы начали.
.noise {
/ ... /
background:
linear-gradient(to right, blue, transparent),
url(https://grainy-gradients.vercel.app/noise.svg);
filter: contrast(170%) brightness(1000%);
}
Можете поэкспериментировать с тем, как контрастность и яркость влияют на градиент. В демо ниже увеличение яркости и контрастности выделяет размытые оттенки серого.
Шум не однороден по цвету
Если приблизить изображение, то можно заметить, что шум состоит из множества цветов. SVG-фильтр изначально был цветным, а повышение яркости и контрастности выделило некоторые цвета. Хотя это конфетти малозаметно, оно нежелательно, поэтому мы продолжим отфильтровывать цвета при помощи CSS-смешения (например, mix-blend-mode
и background-blend-mode
).
CSS-смешение
Давайте создадим зернистый градиент, выполняющий переход между двумя цветами. CSS-смешение позволяет нам накладывать друг на друга слои цвета. В следующем примере мы добавим в разметку ещё один <div>
, разместив его над исходным градиентом, а затем применим mix-blend-mode: multiply;
, чтобы всё сгладить.
<section>
<div class="isolate">
<div class="noise"></div>
<div class="overlay"></div>
</div>
</section>
.noise {
/ ... /
background:
linear-gradient(20deg, rebeccapurple, transparent),
url(https://grainy-gradients.vercel.app/noise.svg);
contrast(170%) brightness(1000%);
}
.overlay {
/ ... /
background: moccasin;
mix-blend-mode: multiply;
}
Можно использовать свойство CSS isolation
, чтобы создать новый контекст наложения и выбрать, что мы будем смешивать. Если бы мы пропустили isolation
в следующем примере, то градиент и верхний слой смешались бы с цветом фона. Можете попробовать закомментировать эту строку в Codepen!
/* Без изменений */
.isolate {
isolation: isolate;
/* ... /
}
Примеры использования
Мы рассмотрели довольно простой пример создания шумного градиента, но где он может пригодиться? Давайте рассмотрим способы его применения.
Свет и тени с зернистостью
Где градиенты возникают естественным образом? Например, в свете и тенях. Мы можем воспользоваться свойством CSS mix-blend-mode
для плавного смешения градиентов и выборочной фильтрации цветов, которые хотим видеть в шуме.
В примере с тенью мы создаём тёмный градиент и инвертируем его для создания эффекта в примере со светом. В обоих случаях mix-blend-mode
позволяет нам выполнять их смешивание с другими градиентами.
Голографическая плёнка
Существенное повышение яркости и контрастности создаёт радужный эффект, напоминающий голографическую плёнку.
Дальнейшее развитие
Попробуйте поэкспериментировать с разными параметрами в песочнице, чтобы понять, как они влияют на текстуру.
Кроме того, эту технику можно развить и другими экспериментами:
Использовать другой SVG: во всех градиентах из этой статьи используется один и тот же SVG, но в песочнице можно поиграться с генерирующими шум параметрами, чтобы отрегулировать зернистость, а также внешний вид .
Попробовать разные градиенты: кроме
linear-gradient
в CSS есть ещё четыре типа градиентов. Можете вспомнить их? (Вот один из них.)Добавить новые слои: при помощи CSS-смешения можно наложить друг на друга любое количество слоёв и смешать их.
Применить другие SVG-фильтры: существует множество разных фильтров, в том числе гауссово размытие и разные типы освещения. Кроме того, на них можно ссылаться в CSS-фильтре и применять к любому элементу в дополнение к SVG.
Браузерная поддержка
Невозможно избежать темы поддержки браузерами. База этой техники поддерживается всеми современными браузерами. Как можно догадаться, она не работает в Internet Explorer. Тем не менее, Internet Explorer поддерживает SVG как фон для CSS (только не со свойством CSS filter
).
SVG как фоновое изображение CSS
Эти данные о браузерной поддержке взяты с Caniuse, где их можно изучить подробнее. Число означает, что браузер поддерживает функцию от указанной версии и выше.
Эффекты фильтров CSS
Ещё я заметил, что браузеры на основе Blink (например, Chrome) и браузеры на основе WebKit (например, Safari) реализуют mix-blend-mode
немного по-разному, поэтому при использовании CSS-смешения проверьте его в разных браузерах. В своих собственных проектах я использовал browser-specific media queries , чтобы вручную разрешать визуальные различия при помощи небольших изменений в CSS.