О режимах наложения в CSS без тайн

Перевод статьи Blending Modes Demystified с сайта alistapart.com для css-live.ru. Автор — Джастин Макдауэл.

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

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

Что такое режимы наложения

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

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

  • Прозрачность
  • Текстура
  • Добавление цвета

Эффект прозрачности с multiply (Умножение)

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

x = a × b

Вот и всё. Она буквально перемножает цвет верхнего слоя (а) с нижнем слоем (b), чтобы получить итоговый цвет (х), отсюда и название «умножение»

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

При использовании режима наложения multiply (Умножение), компьютер берёт значение яркости красного канала для обоих слоёв, приводит их к масштабу от 0 до 1 и перемножает их. Затем он проделывает тоже самое с зелёным и синим каналами. После получения всех результатов он соединяет эти каналы в итоговый цвет.

Это конечно здорово, но в чём практический эффект?

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

fig-1--multiply1

Два слоя без наложения.

 

fig-1--multiply2

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

После перемножения чёрные пиксели на верхнем слое отображаются во всей красе: чёрными. А белых пикселей вообще не видно. Они полностью прозрачны. Промежуточные оттенки серого по краям букв затемняют слой ниже. И мы получаем приятные ровные границы с минимумом усилий. Это как если бы графика была с прозрачным фоном изначально.

Такой трюк работает только с чёрными фигурами. Если у источника есть цвет, то это в какой-то мере окрасит результат. Однако, если фигуры белые, то можно использовать режим наложения screen (Экран).

Пыль и царапины с режимом screen(Экран)

Функциональная противоположность multiply — «Экран». Минуточку, если это противоположность режима «Умножение», почему она не называется «Деление»? И снова ответ лежит в математике:

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

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

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

fig-2--screen1

Наложение со слоем пыли и царапин (можно ознакомиться на «Spoon Graphics») и слоем бледно-лилового цвета.

fig-2--screen2

Изображение с двумя слоями, где к верхнему слою применён режим наложения screen

Кстати, в некоторых приложениях есть режим деления, но его нет в спецификации W3C. (Я не особо огорчён по этому поводу, поскольку мне никогда не требовался этот режим.)

Добавление цвета с помощью hue и color

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

hue

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

fig-3--hue1

fig-3--hue2

color

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

fig-4--color

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

Того же эффекта можно достичь, если изменить порядок слоёв, поместив цвет под фотографию, и наложить фотографию с помощью режима наложения luminosity (Яркость).

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

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

fig-5--differencesУправление цветом — непростая область, и хотя W3C рекомендует по умолчанию цветовой профиль sRGB, поддержка в разных браузерах неоднородна. Каждый браузер отображает цвет по своему капризу. Например, Chrome отображает картинки в своем «необработанном» цветовом пространстве по умолчанию, если в изображении не указан цветовой профиль. Firefox работает так же, но вдобавок у него есть переключатель (скрытый в настройках конфигурации), позволяющий включить sRGB для изображений без профиля. Между тем Safari, скорее всего, будет наиболее соответсвовать Photoshop, поскольку API графики Apple списан с языка PostScript от Adobe. Но даже там есть различия.

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

И конечно же тестируйте на реальных устройствах, чтобы понимать, как аппаратные ограничения (маленькая оперативная память, к примеру) повлияют на сайт. С некоторыми режимами наложения прокрутка может тормозить. Если вам нужна идеальная плавность с полноценными 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;
}

fig-6--background-blend-mode

Для каждого объявления background-image можно применять свой режим наложения. Перечисляйте их в том же порядке, что и ваши фоны, разделяя их запятыми. Итоговое объявление — нижний слой — автоматически накладывается в обычном режиме, и это нельзя изменять. Если использовать background-color, то это и будет нижний слой.

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

Теперь осветлим изображение, как мы делали ранее, и придадим ему оттенок коричневого цвета (сепия).

.background {
  background-image: 
  linear-gradient(hsl(26, 24%, 42%), hsl(26, 24%, 42%)),  /* сепия */
  linear-gradient(hsl(316, 22%, 37%), hsl(316, 22%, 37%)), /* бледно-лиловый цвет */
  url("dust-and-scratches.jpg"), url("mountain.jpg");

  background-blend-mode: color,   /* сепия*/
  screen,  /* бледно-лиловый цвет */
  screen;  /* пыль и царапины */
}

fig-7--multiple-backgrounds

Наложение 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%)),  /* сепия */
  linear-gradient(hsl(316, 22%, 37%), hsl(316, 22%, 37%)), /* бледно-лиловый цвет */
  url("dust-and-scratches.jpg"), url("mountain.jpg");                     
  
  background-blend-mode: color,  /* сепия */
  screen, /* бледно-лиловый цвет */
  screen;  /* пыль и царапины */
}

.graphic {
  mix-blend-mode: multiply;
  opacity: 70%;  /* эффект штампа*/
}

fig-8--mix-blend-mode

Вот новый пример использования 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;
}

fig-9--multiple-elements

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

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

.background {
  isolation: isolate;
}

fig-10--isolation

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

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

В следующем примере я зашёл в Photoshop и набросал макет рекламы вымышленного производителя лыжного снаряжения, которое назвал Masstif. Сначала я создал плашку с текстом и логотипом. Потом смешал плашку с помощью режима «Осветление». Это дает отчетливый контраст с фоном и позволяет тексту и графике выделяться лучше.

fig-11-text-container-blending1

Когда я выстраивал это с помощью HTML и CSS, то ожидал увидеть следующее:

<div class="background">
  <div class="ad-contents">
    <p>Когда ты находишься на вершине миры,<br/>
    можно идти только вниз.</p>
    <p>Глэдли.</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;
}

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

fig-12-text-container-blending2

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

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

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

И учтите, что Safari 9 не поддерживает режимы наложения hue, saturation, luminosity и color.

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

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

P.S. Это тоже может быть интересно:

1 Комментарий

  1. Алексей

    Познавательная статья :)

Оставить комментарий

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

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