Page Content
Дизайнерам и фрондендерам посвящается. Сказ о том⁠, как с палитрой удобно работать.
Речь не о том как выбрать палитру цветов, а о том⁠, как именно с ней работать⁠: к какому виду её привести⁠, как сделать так⁠, чтобы по ходу разработки не пришлось цвета делать «чуть-чуть поярче».
Публикация от ⁠.
Из жизни
Для примера возьмём палитру цветов сайта lonelyplanet.com⁠. Эта палитра — часть большого Style Guide от команды проекта.
Ниже представлены основные цвета данной палитры.
- #142B44
- DARKBLUE
- #1D508D
- NAVBLUE
- #297CBB
- LPBLUE
- #288AD6
- LINKBLUE
- #0FDEBD
- TEAL
- #16C98D
- GREEN
- #FEEF6D
- YELLA
- #FFC83F
- ORANGE
- #FA5E5B
- RED
- #BF538D
- PLUM
Палитра имеет вспомогательные цвета⁠.
- #2C3643
- DARKGRAY
- #3B444F
- TITLEGRAY
- #67747C
- BODYGRAY
- #99A9B3
- LIGHTGRAY
- #DBE6EC
- SUBDUEGRAY
- #684E79
- MAUVE
- #FF708E
- PINK
- #47A899
- DARKCYAN
- #8ABEE5
- SOFTBLUE
- #C7E6AA
- SOFTGREEN
- #CFCBAF
- BEIGE
- #582C2B
- MAROON
- #841E1B
- DARKRED
- #2C3643
- COLOR-PALETTE
Палитра разработана дизайнером, а разработчик перенес палитру «⁠как есть⁠» в Sass для дальнейшей работы⁠. Далее мой коллега заводит пул переменных со значениями цветов⁠. Мы ведь же уже все⁠, пользуемся препроцессорами, да?
$darkblue : #142b44 !default
$navblue : #1d508d !default
$lpblue : #297CBB !default
$linkblue : #288ad6 !default
$teal : #0FDEBD !default
$green : #16c98d !default
$yella : #feef6d !default
$orange : #ffc83f !default
$red : #fa5e5b !default
$plum : #bf538d !default
Полный исходный код таблицы переменных доступен на github.com⁠. Что не так с этой палитрой?
- Отсутствует визуальная структура / Да, признаться, я чуть изменил структуру, объединив четыре группы цветов в две⁠, но даже в исходном варианте, ориентироваться в палитре не легче⁠, палитра представляет собой линейный неупорядоченный набор⁠;
- Названия цветов не отражают сути / Вот зачем⁠, мне как разработчику⁠, знать что цвет
#684E79
— это не просто пурпурный, а именно Mauve⁠? Или как мне «⁠на лету⁠» понять чтоlpblue
темнее или светлееnavblue
⁠? - Разное количество оттенков каждого цвета (тона) / Различное количество оттенков одного цвета со временем неизбежно приведет к тому⁠, что отсутствующие оттенки других цветов будут созданы и общее количество цветов используемых на сайте будет расти⁠, расти неупорядоченно. Так почему бы не сделать это сразу⁠, системно?
Далее мой коллега создаёт функциональный слой переменных. Это перечень переменных, каждая из которых⁠, несёт в себе цвет для конкретной сущности в конкретном контексте/состоянии⁠. Т.е. цвета не создаются⁠, а назначаются⁠. Ниже представлена часть цветов функциональной палитры сайта lonelyplanet.com.
- #FFC83F
- SECTION-ACTIVITY
- #C7E6AA
- SECTION-ARTICLE
- #297CBB
- SECTION-ENTERTAINMENT
- #684E79
- SECTION-EVENT
- #BF538D
- SECTION-HOTEL
- #3B444F
- SECTION-NEED-TO-KNOW
- #47A899
- SECTION-RESTAURANT
- #FF708E
- SECTION-SHOPPING
- #FA5E5B
- SECTION-SIGHT
- #16C98D
- SECTION-TOUR
- #3B444F
- SECTION-TRANSPORT
- #0FDEBD
- SECTION-DESTINATION
Цвета исходной палитры (палитры дизайнера) в функциональной палитре могут использоваться несколько раз. Теоритически⁠, сущностей в интерфейсе намного больше чем самих цветов⁠.
Код функциональной палитры доступен на github.com. Ниже одна из его секций⁠.
$section--activity : $orange !default
$section--article : $softgreen !default
$section--entertainment : $lpblue !default
$section--event : $mauve !default
$section--hotel : $plum !default
$section--need-to-know : $titlegray !default
$section--restaurant : $darkcyan !default
$section--shopping : $pink !default
$section--sight : $red !default
$section--tour : $green !default
$section--transport : $titlegray !default
$section--destination : $teal !default
Если посмотреть внимательнее на функциональную палитру и её код⁠, то можно обнаружить переменные, которые не наследуют ранее созданные цвета⁠, а создают свои⁠, например,
$body-background : #f5f5f5 !default
$body-background-offset : mix($lpblue, #fff, 5%) !default
$card-figure-bg : #f4fbfe !default
$details-panel-bg : mix($subduedgray, #fff, 15%) !default
$details-panel-border : $subduedgray !default
$high-contrast-bg : $titlegray !default
$high-contrast-fg : $lightgray !default
$input-border : $subduedgray !default
$new-header-grey-shadow : rgba(3, 46, 92, 0.12)
$responsive-nav-bg : mix($linkblue, #fff, 3%)
$responsive-nav-subnav-bg : mix($linkblue, #fff, 6%)
$highlight-error : lighten($red, 25%) !default
$highlight-success : lighten($green, 45%) !default
$highlight-warning : lighten($yella, 20%) !default
$highlight-announcement : mix($linkblue, #fff, 25%) !default
Такая организация кода — это следствие того⁠, что, во-первых⁠, некоторые цвета палитры дизайнера представлены сильно ограниченным количеством оттенков (3-4)⁠, а во вторых⁠, палитра не имеет системы/структуры⁠.
Двумерная палитра
Решить такого рода коллизии поможет организация кода и двумерная палитра. Выберите основные цвета по «цвету»⁠, не по яркости⁠, не по светлоте⁠, не по насыщенности⁠, а по привычному нам понятию «цвет»⁠.
Тон (англ. hue) — одна из трёх основных характеристик цвета наряду с насыщенностью и светлотой⁠. В строгом колориметрическом смысле тон - ⁠это направление вектора цветности (вектора на диаграмме цветности с началом в точке белого и концом в данной цветности).
Направление может быть задано углом (⁠это и есть цветовой тон⁠), в то время как удаленность от точки белого задается в процентах и называется насыщенностью (степенью смешивания наиболее насыщенных цветов - спектральных или крайних пурпурных с белым⁠). Именно тон определяет название цвета⁠, например «красный», «синий», «зелёный».
Назовите цвета односложно, понятно любому разработчику и дизайнеру⁠, например: $gray
⁠, $blue
⁠, $purple
и $pink
⁠.
Просто договоритесь, что синий в контексте данного конкретного проекта это не #0000ff
⁠, а, скажем, #297CBB
⁠. А все оттенки синего пусть наследуются от него⁠. Такое значение имеет цвет $lpblue
из палитры lonelyplanet.com.
Примерно таким образом созданы и названы цвета в моём блоге⁠.
$gray: hsl( 0, 0%, 50%);
$blue: hsl(200, 80%, 50%);
$pink: hsl(340, 80%, 50%);
$purple: mix($blue, $pink);
Настоятельно рекомендую «откалибровать» палитру. Я использую цветовую модель HSL для выравнивания цветов по насыщенности и светлоте⁠.
Кстати, вы можете использовать эту цветовую модель непосредственно на клиенте⁠, так как её поддержка в броузерах хороша⁠.
За базовый цвет каждого семейства оттенков цвета⁠, берём цвет у которого светлота равна 50%⁠. Тем самым⁠, как бы центрируем все цвета между черным и белым⁠. При этом⁠, «брендовые» цвета могут и не быть базовыми, главное, чтобы срез по светлоте проходил ровно по светлоте корпоративного цвета⁠.
Вот так выглядит палитра моего блога⁠.
В моей палитре все цвета разложены с шагом в 10% по светлоте⁠. Шкала уровней отклонения светлости от базового цвета равна⁠: ±47, ±40, ±30, ±20, ±10. Крайние цвета имеют отклонение в 47% вместо 50%⁠, иначе бы они превратились в белые и черные цвета⁠.
Шаг между уровнями должен быть достаточным для визуального отличия, но не большим и не маленьким⁠, таким, чтобы не пришлось создавать промежуточные цвета и их не было слишком много⁠. Обычно, в моих проектах шаг составляет 10% светлости⁠.
Калибровка позволяет избежать ситуаций, когда заливка определённым цветом «кричит» отвлекая на себя внимание пользователя.
Производные от базового цвета обозначены «говорящими» суффиксами-модификаторами⁠: $purple_3d
⁠, $purple_2l
и т.п.
$pink : hsl(340, 80%, 50%);
$pink_5l: hsl(340, 80%, 95%);
$pink_4l: hsl(340, 80%, 90%);
$pink_3l: hsl(340, 80%, 80%);
$pink_2l: hsl(340, 80%, 70%);
$pink_1l: hsl(340, 80%, 60%);
$pink_1d: hsl(340, 80%, 40%);
$pink_2d: hsl(340, 80%, 30%);
$pink_3d: hsl(340, 80%, 20%);
$pink_4d: hsl(340, 80%, 10%);
$pink_5d: hsl(340, 80%, 5%);
Что эквивалентно записи с использованием Sass-методов lighten и darken⁠.
$pink : hsl(340, 80%, 50%);
$pink_5l: lighten($pink, 45%);
$pink_4l: lighten($pink, 40%);
$pink_3l: lighten($pink, 30%);
$pink_2l: lighten($pink, 20%);
$pink_1l: lighten($pink, 10%);
$pink_1d: darken($pink, 10%);
$pink_2d: darken($pink, 20%);
$pink_3d: darken($pink, 30%);
$pink_4d: darken($pink, 40%);
$pink_5d: darken($pink, 45%);
Наличие таких переменных позволяет более удобно работать с цветами палитры. Например, переменная $blue_1d
может сделать текст синим⁠, со светлостью ниже на 10% от базового тона⁠. А $blue_1l
— может повысить его светлость на 20% от предыдущего состояния, например, по hover
⁠.
Уровни отклонения от базового цвета (⁠срезы по светлоте⁠), это не обязательно +10 или -20 по светлоте⁠, нужно воспринимать это как абстрактные «уровни».
Т.е. в обычной жизни нам даже не нужно знать⁠, что, например, $gray_4l
соответствуют отклонению +33 по светлоте⁠, мы просто используем переменную по уровню⁠.
А если палитра уже существует⁠?
Метод разложения цветов по светлости и представления множества цветов палитры в виде двумерной палитры может быть полезен даже в том случае⁠, когда палитра и сайт уже существуют⁠. Для примера⁠, приведём в порядок палитру от lonelyplanet.com.
Для начала найдем множество уникальных цветов, даже если они представлены в палитре различными оттенками. Для наглядности представим цвета в цветовом пространстве hsl.
$red : #fa5e5b = hsl( 1, 94%, 67% )
$orange : #ffc83f = hsl( 43, 100%, 62% )
$yella : #feef6d = hsl( 54, 99%, 71% )
$green : #16c98d = hsl( 160, 80%, 44% )
$teal : #0fdebd = hsl( 170, 87%, 46% )
$lpblue : #297cbb = hsl( 206, 64%, 45% )
$linkblue: #288ad6 = hsl( 206, 69%, 50% )
$darkblue: #142b44 = hsl( 211, 55%, 17% )
$navblue : #1d508d = hsl( 213, 66%, 33% )
$plum : #bf538d = hsl( 328, 46%, 54% )
Посмотрим внимательно на полученное hsl-представление цветов⁠. Цвета $lpblue
и $linkblue
равны по параметру «Hue» (цвет)⁠. А их параметры «насыщенность» очень близки⁠.
$lpblue : #297cbb = hsl( 206, 64%, 45% )
$linkblue: #288ad6 = hsl( 206, 69%, 50% )
Если чуть «похулиганить», то к данной группе можно добавить и другие цвета из основной палитры.
$lpblue : #297cbb = hsl( 206, 64%, 45% )
$linkblue: #288ad6 = hsl( 206, 69%, 50% )
$darkblue: #142b44 = hsl( 211, 55%, 17% )
$navblue : #1d508d = hsl( 213, 66%, 33% )
С небольшим допущением, данные цвета можно заменить одним базовым и его производными по светлости⁠:
$lpblue : #297cbb = hsl( 206, 64%, 45% ) ——> hsl( 206, 69%, 45% )
$linkblue: #288ad6 = hsl( 206, 69%, 50% ) ——> hsl( 206, 69%, 50% )
$darkblue: #142b44 = hsl( 211, 55%, 17% ) ——> hsl( 206, 69%, 17% )
$navblue : #1d508d = hsl( 213, 66%, 33% ) ——> hsl( 206, 69%, 33% )
Определим возможные уровни и создадим переменные.
$red : #fa5e5b = hsl( 1, 94%, 67% ) ——> hsl( 1, 94%, 67% ) = $red_3l
$orange : #ffc83f = hsl( 43, 100%, 62% ) ——> hsl( 43, 100%, 62% ) = $orange_2l
$yella : #feef6d = hsl( 54, 99%, 71% ) ——> hsl( 54, 99%, 71% ) = $yella_4l
$green : #16c98d = hsl( 160, 80%, 44% ) ——> hsl( 160, 80%, 45% ) = $green_1d
$teal : #0fdebd = hsl( 170, 87%, 46% ) ——> hsl( 170, 87%, 45% ) = $teal_1d
$lpblue : #297cbb = hsl( 206, 64%, 45% ) ——> hsl( 206, 69%, 45% ) = $blue_1d
$linkblue: #288ad6 = hsl( 206, 69%, 50% ) ——> hsl( 206, 69%, 50% ) = $blue
$darkblue: #142b44 = hsl( 211, 55%, 17% ) ——> hsl( 206, 69%, 17% ) = $blue_5d
$navblue : #1d508d = hsl( 213, 66%, 33% ) ——> hsl( 206, 69%, 33% ) = $blue_3d
$plum : #bf538d = hsl( 328, 46%, 54% ) ——> hsl( 328, 46%, 54% ) = $plum_1l
В данном примере шкала уровней отклонения светлости от базового цвета равна⁠: ±33, ±21, ±17, ±12, ±5 (4)⁠. Для максимальной релевантности брендовых цветов и новой палитры на уровне 1l
отклонение по светлости равно +4⁠, а на уровне 1d
— -5.
Результат наших манипуляций представлен ниже⁠. Это «живой» HTML и CSS⁠, тут можно поинспектировать, исследовать значения цветов и их разницу⁠.
Серой рамкой обозначены базовые цвета⁠, т.е. те цвета⁠, которые являются основой для всех остальных (производных) цветов палитры.
Маркером (⁠белой точкой⁠) указаны брендовые цвета⁠. Рядом с маркером⁠, для сравнения⁠, имеется область исходного цвета из палитры дизайнера. Для наглядности⁠, ниже представлен увеличенный участок палитры, с цветами имеющими отличие от исходных⁠.
Такие расхождения — следствие допущений принятых при построении палитры. При работе с синими я приравнял их параметры Hue и Saturation⁠, а при работе с цветами близкими по светлоте⁠, их светлота приводилась к единому значению, всё это повлияло на конечный результат.
Чем меньше цветов одного тона будет в исходной палитре и чем больше будет цветов равных по светлоте⁠, тем выше будет релевантность исходной и новой палитры.
Для того чтобы палитра получилась идеальная, расскажите дизайнеру о нюансах разработки, решите вопрос дополнительных цветов заранее.
Кстати, обратите внимание на верхнюю часть полученной палитры (⁠выше базовых цветов), там брендовые цвета все сохранились без искажений⁠.
Для изучения материала рекомендую проанализировать палитры других сайтов: gov.uk⁠, disqus.com⁠, linkedin.com
Используйте качественные палитры!
Sass автоматически конвертирует hsl в rgb. И делает это практически правильно. На момент написания статьи bug имеет статус «open»⁠.
Вместо заключения — Задолба!ли — Говорите поярче⁠.