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

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

Описание режимов наложения

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

В рекомендации W3C есть 15 новых режимов наложения. У нас хватает информации о том, как разные режимы наложения работают, но нет правильного способа выбора конкретного режима. Давайте рассмотрим несколько самых полезных режимов более подробно. В своей практике я использую следующие возможности режимов наложения:

  • прозрачность
  • текстуризация
  • раскрашивание

Эффект прозрачности с multiply

Начнем с режима наложения “умножение” (multiply). Математическую формулу этого режима можно представить так:

x = a × b

Все. Мы действительно умножаем цвет верхнего слоя (a) на цвет нижнего слоя (b), чтобы получить итоговый цвет и (x), именно поэтому режим называется умножение.

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

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

Это все хорошо, но что с этим можно сделать на практике?

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

Два слоя без смешивания Два слоя без смешивания

Два слоя в режиме смешивания multiply Два слоя в режиме смешивания multiply

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

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

Пыль и царапины с помощью screen

Функциональная противоположность multiply называется screen (экран). Минутку, а разве противоположность умножению это не деление? Ответ опять лежит в области математики:

x = 1 − (1 − a) × (1 − b)

Этот режим не называется “деление”, потому что на самом деле в нем мы умножаем еще больше! В данном случае мы умножаем инвертированное значение слоя a на инвертированное значение слоя b и затем инвертируем результат. В итоге белые пиксели на верхнем слое полностью непрозрачны, а черные пиксели наоборот прозрачны. Каждый оттенок между слоями осветляет нижний слой.

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

Слои для смешивания: слой с лавандовым цветом и слой с пылью и царапинами

Слои для смешивания: слой с лавандовым цветом и слой с пылью и царапинами (с сайта Spoon Graphics)

Результат смешивания фотографии с этими слоями в режиме screen

Результат смешивания фотографии с этими слоями в режиме screen

Раскрашивание с помощью hue и color

У всех режимов смешивания есть потенциал к изменению цвета графики, но особо полезны для раскрашивания два из них: цветовой тон (hue) и цветность (color).

Цветовой тон hue

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

3 варианта коричневого цвета

Тонирование разными оттенками дает одинаковый результат

Цветность color

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

Красно-коричневое наложение делает пиксели исходника красновато-коричневыми

Красно-коричневое наложение делает пиксели исходника красновато-коричневыми, также как и в режиме hue, но оно также придает им одинаковую насыщенность

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

Кроссбраузерное наложение

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

Различия режима смешивания в разных браузерах

Управление цветом это сложный мир и хотя W3C рекомендует использовать по умолчанию профиль sRGB, подход производителей браузеров различается — каждый браузер рендерит цвета согласно своим прихотям. Например, в Chrome рендеринг изображений основывается на “неуправляемом” цветовом пространстве, если в изображении не прописан цветовой профиль. Firefox работает также, но глубоко в его конфигурационных настройках запрятан флаг, устанавливающий sRGB по умолчанию для изображений с не указанным профилем. А Safari действует почти как Photoshop, так как графический API Apple основан на Adobe Postscript. Да, даже здесь есть свои отличия.

Идем дальше — различия не исчерпываются браузерами. Люди тоже разные. Например, миллионы живут с цветовой слепотой. И они видят ваш дизайн совсем не таким, как вы предполагаете. Как и всегда — тестируйте ваш труд в разных браузерах, проверяйте доступность и не рассчитывайте на то, что ваш дизайн будет выглядеть одинаково везде.

И еще — не забывайте тестировать на “живых” устройствах, а не только в режиме эмуляции, чтобы понять как хардверные ограничения (типа нехватки оперативной памяти) влияют на ваш сайт. Некоторые режимы наложения могут вызвать задержки при прокрутке страницы. И если вы добиваетесь гладкости 60 кадров в секунду, учитывайте это при своем выборе.

Применение режимов наложения

Режимы наложения можно применить с помощью пары свойств CSS: background-blend-mode и mix-blend-mode, также нам может пригодиться свойство isolation.

Наложение фоновых изображений

Свойство background-blend-mode смешивает изображения, указанные в декларации background-image. Это значит, что все изображения располагаются в стеке поверх друг друга и вы используете режим наложения, чтобы смешать их вместе.

Попробуем добавить пыль и царапины на фото. (Обратите внимание, что код предназначен для конкретных примеров).

<div class="background"></div>
.background {
  background-image: url("dust-and-scratches.jpg"), url("mountain.jpg");
  background-blend-mode: screen;
}

Фото с добавленными царапинами и пылью

Вы можете использовать разные режимы наложения для каждой декларации background-image. Перечислите их в том же порядке, что и фоновые изображения и разделите запятыми. Последней декларации — самому нижнему слою автоматически задается нормальный режим наложения и это нельзя изменить. Если вы задали фоновый цвет с помощью background-color, то самым нижним уровнем будет он.

Иногда у вас может возникнуть потребность использовать цвет в качестве наложения. К сожалению, свойство CSS background-color ограничено одним цветом и это всегда будет самый нижний слой, независимо от того, объявлен ли он в начале списка фонов или нет. Рекомендация W3C предлагает нотацию image(), позволяющую использовать цвет в качестве изображения, но на данный момент это не поддерживается ни в одном браузере. К счастью, у нас есть обходной путь: так как градиенты в CSS рассматриваются как изображение, мы можем обмануть браузер, подсунув ему однотонный цвет с двумя идентичными точками останова.

Итак, осветлим изображение, как мы делали это ранее и изменим его цвет на сепию.

.background {
  background-image: 
  linear-gradient(hsl(26, 24%, 42%), hsl(26, 24%, 42%)),  /* sepia */
  linear-gradient(hsl(316, 22%, 37%), hsl(316, 22%, 37%)), /* lavender */
  url("dust-and-scratches.jpg"), url("mountain.jpg");

  background-blend-mode: color,   /* sepia */
  screen,  /* lavender */
  screen;  /* dust-and-scratches */
}

Добавление царапин, пыли и тонирование сепией с помощью режима наложения

Наложение элементов HTML

Свойство mix-blend-mode задает режим наложения для элементов HTML, поэтому элементы на перекрывающихся слоях будут использовать его при смешивании с нижними слоями. Давайте опять добавим заглавие к изображению, удалив нежелательный белый фон заглавия с помощью режима multiply. Я также сделал элемент с изображением немного прозрачным, чтобы улучшить наложение цветов.

<div class="background">
  <div class="text-box">
    <h1>
      <img class="graphic" alt="Chamonix Harmony" src="chamonix-harmony.jpg" />
    </h1>
  </div>
</div>
.background {
  background-image: 
  linear-gradient(hsl(26, 24%, 42%), hsl(26, 24%, 42%)),  /* sepia */
  linear-gradient(hsl(316, 22%, 37%), hsl(316, 22%, 37%)), /* lavender */
  url("dust-and-scratches.jpg"), url("mountain.jpg");                     
  
  background-blend-mode: color,  /* sepia */
  screen, /* lavender */
  screen;  /* dust and scratches */
}

.graphic {
  mix-blend-mode: multiply;
  opacity: 70%;  /* overprint effect */
}

Наложение логотипа с помощью режима multiply

А вот пример использования mix-blend-mode для наложения нескольких элементов.

<div class="background">
  <div class="red-disc">
    <img alt="" src="red-disc.svg" />
  </div>
  <div class="green-disc">
    <img alt="" src="green-disc.svg" />
  </div>
  <div class="blue-disc">
    <img alt="" src="blue-disc.svg" />
  </div>
</div>
.red-disc, .green-disc, .blue-disc {
  mix-blend-mode: screen;
}

Использование mix-blend-mode для наложения нескольких элементов

Использование mix-blend-mode для наложения нескольких элементов

Если вы не хотите, чтобы элемент в нижнем слое смешивался с каким-либо из верхних слоев, их можно отделить друг от друга с помощь третьего свойства: isolation. Это используется для наложения нескольких элементов без воздействия на базовый слой. Каждому из дисков в нашем примере задано mix-blend-mode в значение screen, что вынуждает их создавать новые цвета при пересечении. Но мы хотим, чтобы фотография горы не смешивалась с ними.

.background {
  isolation: isolate;
}

Использование isolation для предотвращения смешивания нижнего слоя с остальными

Использование isolation для предотвращения смешивания нижнего слоя с остальными

Учитывайте, что mix-blend-mode применяется к элементу целиком, вместе со всеми его потомками. Это аналогично воздействию свойства opacity, делающему невидимым не только контейнер, но и его содержимое. Точно также и mix-blend-mode смешивает и контейнер, и содержимое.

Для следующего примера я немного поработал в Photoshop и создал набросок дизайна для вымышленного производителя лыжного оборудования Masstif. В этом наброске я создал блок с небольшим текстом и логотипом. Я смешал этот блок в режиме осветления цветов (color-dodge). Это дает четкий контраст по отношению к фону и помогает лучше сочетать текст и графику.

Образец дизайна с наложением слоев color-dodge

При попытке воспроизвести это средствами HTML и CSS, я рассчитывал, что работать будет следующий код:

<div class="background">
  <div class="ad-contents">
    <p>When you’re on top of the world,<br/>
    the only way to go is down.</p>
    <p>Gladly.</p>
    <img alt="Masstif" src="logo.svg" />
  </div>
</div>
.background {
  background-image: url("mountain.jpg");
}
.ad-contents {
  background-color: white;
  mix-blend-mode: color-dodge;
}

Но в результате содержимое смешалось с контейнером так, как на следующем изображении.

Логотип и текст смешались с контейнером

Также как отдельные проблемы с прозрачностью частично решаются за счет альфа-каналов фона, здесь мы тоже можем решить проблему с mix-blend-mode путем перемещения того, что возможно в фон. Вместо создания блока и наложения его с помощью mix-blend-mode, будет работать прием с конвертацией блока в background-image. Это не является решением для всех случаев, но попытаться стоит. Другого способа изолировать дочерние узлы от содержащего их смешиваемого элемента нет.

Поддержка в браузерах

Режимы наложения поддерживаются в большинстве основных браузеров, кроме Internet Explorer и Edge. Некоторый оптимизм есть в том, что реализация режимов наложения для Edge находится в стадии рассмотрения, а этот браузер уже поддерживает все режимы наложения для SVG, что дает шанс на скорую реализацию. Вы можете повлиять на процесс, проголосовав на сайте пожеланий для разработчиков Edge.

Также есть проблема с Safari — он не поддерживает режимы hue, saturation, luminosity и color.

Учитывайте, что в не поддерживающих режимы наложения браузерах, ваш дизайн не будет отображаться так, как вам надо. Это может все осложнить, пока вы не уверены, что у вашей аудитории достаточно продвинутые браузеры. Спрашивайте себя — приемлемы ли запасные варианты для вашей аудитории. Если нет — вам надо искать обходной путь.

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

Дополнительные материалы