При разработке цветовых схем продукта вместе с дизайнером мы увидели нестыковки с тем, как именуются переменные цвета. Я провёл ресерч, после чего пришло осознание, что очень важно семантически правильно именовать переменные до начала этапа разработки.
Возможно, гипотеза, описанная в данной статье, станет хорошим подспорьем для обсуждения и решения одной из проблем, которые возникают при разработке дизайн-системы, а именно — правильной настройки цветовой схемы.
Характеристики цвета
Цвета разделяют на две категории: хроматические и ахроматические. Ахроматические — это не спектральные цвета. Черный, белый, оттенки серого. Они имеют только одну характеристику — светлоту.
Цветовые системы
Классификация цветовых систем:
По свету (RGB). Смесь. Красный, зеленый, синий
По краске (CMYK). Вычитание. Голубой, пурпурный, желтый, черный
На мониторах мы имеем дело со светом, поэтому разберем более подробно, что такое цветовая система света.
В 1676 Исаак Ньютон провел следующий эксперимент: пропустил луч света через трёхгранную призму и получил цветовой спектр — от красного к фиолетовому, кроме пурпурного. После этого спектр был пропущен через собирательную линзу, в результате чего был получен белый цвет.
Своим экспериментом Ньютон доказал, что белый цвет не первичен и состоит из цветных компонент с разной степенью преломляемости. Эти составляющие как раз и оказались первичными. Далее он пропустил синий цвет через еще одну трехгранную призму, но синий цвет не разложился на новый спектр, что в свою очередь доказало, что этот цвет и является первичным.
Цвет света
До этого эксперимента все считали, что предметы обладают цветом. Однако, Ньютон определил что предмет при попадании на него луча света часть световых волн поглощает, а часть – отражает. И в зависимости от того, с каким углом происходит преломление, таким мы и считаем цвет предмета.
“Красный сосуд выглядит красным потому, что он поглощает все остальные цвета светового луча и отражает только красный”.
Иоганн Гёте смешал фиолетовый и красный, таким образом, получив пурпурный цвет и появился новый цветовой круг.
Филипп Отто Рунге расширил ряд первичных цветов, добавив в него черный и белый. Рунге строил свои выводы на опытах с пигментами, что делало его учение более близким живописи.
Иоханнес Иттен. Его 12-частный цветовой круг показывает наиболее распространенную в мире систему расположения цветов и их взаимодействие между собой.
Иттен выделил основные цвета, цвета второго порядка (зеленый, фиолетовый и оранжевый), которые получаются при смешении пары основных цветов, и цвета третьего порядка, которые получаются при смешении основного цвета с цветом второго порядка.
Мишель Шеврёль был первым, кто разработал цветовой атлас. В его основе 6 основных цветов в двенадцати модификациях.
Цвет краски (Субтрактивный цвет или Subtractive color)
Эта система предсказывает спектр мощности света после прохождения света через последовательно поглощающие слои разных сред. Создателем цветового колеса при вычитаемом смешении является Моисей Харрис.
Если красную бумагу (её поверхность поглощает все лучи кроме красного) освещать зеленым цветом, то она покажется нам черной, потому что зеленый цвет не содержит в себе лучей красного цвета, которые могли быть отражены нашей красной бумагой. Все краски являются вещественными (впитывающими), поэтому при их смешивании нужно руководствоваться принципами вычитания.
Какой формат использует большинство?
Еще со времен CSS 2.1 принято использовать либо HEX, либо RGB-цвета. Недостатками использования такой формы представления цвета являются:
Система не понятна интуитивно. Мы не разделяем цвет отдельно на красный, зеленый и синий и не приводим цвет в шестнадцатеричную систему счисления, да и не говорим, например, “Кремль цвета #ff0000”.
Отсутствует поддержка. Дизайнерам может понадобиться 10 типов одного цвета, а в HEX и RGB нет никакой привязки к оттенкам.
HSL (hue, saturation, lightness)
Цвет в HSL представлении определяется тремя значениями:
тоном (оттенком, hue);
значением (светлотой, яркостью, value);
хромой (цветностью, насыщенностью, chroma, saturation).
Существует трехмерная колометрическая система Манселла. В ней цвет определяется с помощью трех координат.
Если составляющие цвета переименовать, мы получим следующую картину:
Выбор цветовой схемы
Темизация, white label, редизайн — вот перечень основных пунктов, с которыми может столкнуться команда разработки. И чтобы эти пункты не превратились в проблемы, нужно с самого начала разработки предпринять ряд шагов.
1. Выбор типа цветовой схемы
Итак, какие же бывают цветовые схемы, согласно теории цвета:
Монохромные (используется один основной цвет и его оттенки)
https://codepen.io/gevara2015/pen/xxVdooe
Комплиментарная схема — берутся цвета, расположенные на противоположных сторонах цветового круга. Сочетание таких цветов выглядит очень живо и энергично. Такую схему лучше не брать для создания текстовых композиций. Лучше всего использовать ее, когда необходимо что-то выделить или подчеркнуть.
Всего же существует 5 цветовых схем:
Монохроматическая схема (один основной цвет).
Добавочная схема (два основных цвета).
Триадная схема (три основных цвета).
Тетраэдная схема (четыре основных цвета).
Примыкающая схема (два или три основных цвета).
Не будем тратить время на подробный разбор каждой схемы, это сделано вот здесь, перейдём ближе к коду.
2. Именование переменных
Большинство именований переменных цвета, которые есть сейчас: accent, base, high, button-contrast-alpha, positive, negative, faint, success, warning... множество их. И почти к каждому обозначению есть вопросы.
Возьмём, к примеру, high — относительно чего он high, есть ли low, насколько high больше и по какому параметру low?
Button-contrast-alpha. Если следовать логике этого именования, должен быть ряд alpha, beta, gamma. Опять же вопрос: чем они будут отличаться и в какой степени? Какой цвет будет иметь средние значения?
Низкий уровень абстракции: button, text, link и т. д.
По именованию, мне кажется, нужно придерживаться ряда правил:
Вместо alpha, beta, gamma использовать strong, base, weak.
Primary (основной цвет бренда).
Учитывая множество абстракций в именовании (в имени переменной нельзя указывать конкретный параметр элемента разметки или сам элемент), я подумал о том, что было бы неплохо придерживаться именования по слоям (мало кто вспомнит аддон Tilt в Firefox). Чтобы отличить один элемент от другого, достаточно представить, что он находится просто уровнем выше. А чтобы он выделялся, нужно ему задать этот самый цвет подложки, что-то наподобие background и foreground.
И тут я наткнулся на объяснение принципов именования переменных для Material Design.
Background (0dp elevation surface overlay)
Surface (with 1dp elevation surface overlay)
Primary
Secondary
On Background
On Surface
On Primary
On Secondary
2.1 Разделение именований
Лучшим решением для разработчиков и дизайнеров является описание переменных и промежуточного слоя, который это все соединяет. То есть переменные для разработчиков описывают лишь отдельные свойства с привязкой на их расположение в "слоях" потока элементов. А вот переменные для дизайнеров наоборот должны быть связаны конкретно с цветом, тоном, яркостью.
https://codepen.io/gevara2015/pen/poywzLj
То есть для описания свойств элементов нам будет достаточно следующего набора переменных:
/* elements variables */
--global-background: var(--bg);
--surface: var(--bg-weak);
--on-color: #fff;
--on-background: var(--contrast-weak);
--on-primary: var(--on-color);
--on-secondary: var(--on-color);
--on-error: var(--on-color);
--on-surface-prime: var(--contrast-weak);
--on-surface-second: var(--contrast-strong);
--input-background: var(--bg-weak);
--input-outline: inset 0 0 0 1px var(--secondary-strong);
--component-outline: none;
Также стоит отметить, что для описания границ элемента лучше использовать не border, а box-shadow, так как он является более комплексным (можем применить сразу хоть три значения тени):
--component-outline: 15px 17px 26px -4px rgba(34, 60, 80, 0.6), 15px 17px 19px -11px rgba(20, 117, 191, 0.6), -22px -36px 19px -11px rgba(56, 167, 103, 0.6);
Плюс он не меняет размер всей кнопки или, к примеру, инпутау (если мы берем за исходные данные box-sizing: border-box). Мне кажется, что это является хорошим решением, так как разработчики описывают для каждого компонента набор переменных, а дизайнер в дальнейшем может играться с цветами или цветовыми схемами, с дизайнерскими подходами (skeuomorphism, neumorphism) или даже использовать LCH цвета, все на усмотрение дизайнера.
Lea Verou в своей статье указывает на вариант конвертации цветовой схемы для темной темы с помощью L (светлота) параметра в HSL формате. В итоге для светлой темы получается лесенка:
--l-0: 0%;
--l-30: 30%;
--l-40: 40%;
--l-50: 50%;
--l-90: 90%;
--l-100: 100%;
а для тёмной — обратная лесенка переменных:
@media (prefers-color-scheme: dark) {
:root {
--l-0: 100%;
--l-30: 70%;
--l-40: 60%;
--l-90: 10%;
--l-100: 0%;
}
}
И казалось бы, все логично, можно просто определить текущий параметр светимости как формула 100% - lightness, и он будет средним как для темной, так и для светлой темы. Однако у hsl есть недостаток. В светлой теме будет недостаточно контраста для ряда элементов. Решение, предложенное Lea Verou c использованием LCH цветов, как мне кажется, еще слишком сырое, это все еще драфт в спецификациях w3c.
Выводы
Для того, чтобы грамотно использовать цветовые схемы, в которых цвета не будут сливаться (или будет недостаточная контрастность) нужно разделить переменные "для дизайнеров" и переменные "для разработчиков".
Настройка цветовой схемы лежит полностью на дизайнере, и он отдает всего лишь итоговый файл конфиг.
Компания Stripe сделала инструмент для внутреннего использования в своих продуктах, но для разработки подобного инструмента нужны ресурсы.
Автор: Александр Танцюра, Frontend Developer в Space307.