Зернистые градиенты

Посмотрите Dribbble или Behance — и вы увидите, что дизайнеры используют простой способ придать изображению текстуру — добавляют шум. Добавление шума делает сплошные цвета или плавные градиенты, например тени, более реалистичными. Но, несмотря на любовь дизайнеров к текстурам, в веб-дизайне шум применяется редко.

Ниже мы создадим красочный шум, чтобы добавить текстуру к градиенту при помощи небольшого количества кода на CSS и SVG.

Интерактивная песочница

Посмотрите песочницу. Самый быстрый способ понять происходящее — поиграть с параметрами, из которых состоят слои.

Хитрость — шум на SVG и градиенты на CSS

Основная техника в этой статье основывается на ответе со Stack Overflow на вопрос «Можно ли добавить шум к CSS-градиенту?» от Криса Пакла.

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

Основные ингредиенты

Вот с чем мы работаем под капотом:

  • Применяем SVG-турбулентность — это наш фильтр для шума.
  • Создаем фон CSS при помощи SVG и градиента — помещаем этот фильтр в CSS как фоновое изображение, которое объединяет фильтр с градиентом CSS.
  • Увеличиваем яркость и контрастность — затем обращаемся к свойству CSS filter, чтобы увеличить яркость и контрастность шума.
  • Смешиваем градиенты — наконец, как опцию применяем mix-blend-mode, чтобы далее фильтровать цвета и смешивать градиенты.

Погрузимся в детали каждой операции.

Применяем SVG-турбулентность

В мире 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>, который можно использовать для зернистых градиентов. Обратите внимание, что SVG <filter> определяется отдельно от <rect>; сам <rect> просто ссылается на фильтр.

Скриншоты CodePen здесь и далее кликабельны и ведут на CodePen. Поиграйте с переключателями каких-нибудь свойств <feTurbulence>:

Сохраним этот SVG как отдельный файл. Мы ссылаемся на внешнюю ссылку, чтобы получить SVG в демонстрациях этой статьи, но на практике вы будете ссылаться на локальный файл или собственную CDN — сеть доставки контента. В CSS по какой-то странной причине невозможно ссылаться на SVG по его id в CSS, но можно встроить SVG, как показывается в демо из песочницы. В демо-версиях так не делается по соображениям разборчивости [рисунка].

Создаем фон CSS при помощи SVG и градиента

После того как мы где-нибудь сохранили SVG, ссылаться на него можно по URL-адресу или пути; теперь его можно прописать в свойство background, комбинируя с градиентом.

.noise {
  /* ... */
  background:
    linear-gradient(to right, blue, transparent),
    url(https://grainy-gradients.vercel.app/noise.svg);
}

Здесь важен порядок. В этом конкретном примере хочется, чтобы сплошной цвет (т. е. цвет без шума) перешел в шум, а после в другой цвет. А ещё хочется, чтобы один конец градиента был прозрачным, чтобы шум проступал сквозь него.

Вот так:

Однако это не особенно приятно, потому что шум чересчур беспорядочный. Его нужно растереть и сделать более зернистым. И сделать это можно…

Усиливаем яркость и контрастность

Добавление свойства CSS filter делает шум резче, смещая самые блеклые цвета в сторону белого или черного. Фильтр применяется ко всему <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 позволяет накладывать слои цвета. В следующем примере добавим к разметке еще один <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 в следующем примере, градиент и наложение смешаются с цветом фона. Попробуйте сделать это в Pen, закомментируйте строку ниже!

/* Тот же код, что и раньше */

.isolate {
  isolation: isolate;
  /* ... */
}

Несколько примеров

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

Свет и тени с зернистостью

Где градиенты возникают естественным образом? Например, со светом и тенью. Можно воспользоваться свойством CSS mix-blend-mode, чтобы плавно смешивать градиенты и выборочно фильтровать цвета, которые хочется увидеть зашумленными.

В примере «тени» мы создаем темный градиент. Этот пример инвертируется, чтобы создать эффект в примере «света». В обоих случаях mix-blend-mode позволяет нам смешивать основной градиент с другими.

Голографическая фольга

Резкое усиление яркости и контрастности создает ощущение радуги, напоминающий реминисцентную фольгу.

Продвигаемся дальше

Попробуйте песочницу и поэкспериментируйте с разными параметрами, чтобы посмотреть, как они влияют на текстуру.

Кроме того, вот несколько способов ещё повозиться с этой техникой:

  • Используйте другой SVG. Все градиенты из этой статьи используют один и тот же SVG, но можно настроить параметры, генерирующие шум: грубость зерна, внешний вид в песочнице.
  • Попробуйте разные градиенты. Помимо linear, CSS предлагает еще четыре типа градиентов. Сможете назвать их? (Вот еще один).
  • Добавьте больше слоев. С помощью смешивания можно наложить столько слоев, сколько захотите, и затем смешать их.
  • Применяйте разные фильтры SVG. Доступны все виды фильтров, включая размытие по Гауссу и различные типы освещения. Кроме того, на них можно ссылаться в фильтре CSS и применять к любому элементу помимо SVG.

Что еще можно придумать? Пожалуйста, дайте нам знать в комментариях, что обнаружили вы.

Поддержка подхода браузерами

Здесь нельзя не сказать о поддержке браузеров. Суть этого метода поддерживается всеми современными браузерами. Как и следовало ожидать, в Internet Explorer он не работает. Тем не менее Internet Explorer поддерживает SVG в качестве фона CSS, но не через filter.

SVG как фоновое изображение через CSS

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

ChromeFirefoxIEEdgeSafari
5249165
Десктопные
Android ChromeAndroid FirefoxAndroidiOS Safari
12612734.2-4.3
Мобильные/планшетные

Поддержка эффектов CSS filter

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

ChromeFirefoxIEEdgeSafari
18*35Нет796*
Мобильные
Android ChromeAndroid FirefoxAndroidiOS Safari
1261274.4*6.0-6.1*
Планшетные

Я также заметил, что браузеры на основе Blink (например, Chrome) и браузеры на базе WebKit (например, Safari) реализуют mix-blend-mode немного по-разному, поэтому обязательно тестируйте разные браузеры, если используете смешивание. В своих проектах я использовал медиа-запросы для конкретного браузера, чтобы вручную совместить визуальные различия, немного изменив CSS.

Вот и все! Теперь, когда вы имеете представление о фильтрах SVG и о том, как комбинировать их с фильтрами CSS для фона, у вас есть еще один изящный визуальный эффект, позволяющий добавить дизайну глубину и текстуру.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Jimmy Chion: Grainy Gradients

Предыдущая статья5 функций-расширений в арсенале каждого разработчика Jetpack Compose
Следующая статьяБыстрый поиск фотографий: оптимизированные подходы