Построение цветовой схемы

Базовый обзор того, как создать динамическую и настраиваемую цветовую схему.

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

Демо

Если вы предпочитаете видео, вот версия этого поста на YouTube:

Обзор

Мы создадим доступную систему цвета с настраиваемыми свойствами и calc() , чтобы сделать веб-страницу адаптивной к предпочтениям пользователя, сохраняя при этом минимальный опыт разработки. Начинаем с базового фирменного цвета и выстраиваем из него систему вариантов: 2 цвета текста, 4 цвета поверхности и соответствующую тень.

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

Бренд

Часто цвет бренда уже установлен и поставляется в шестнадцатеричном или RGB- формате. В этом вызове GUI используется базовый фирменный цвет #0af . Во-первых, для этой цветовой системы шестнадцатеричное значение необходимо преобразовать в hsl .

* {
  --brand: #0af;
  --brand: hsl(200 100% 50%);
}

Чтобы реализовать концепцию затемнения или осветления цвета бренда, скажем, на 20%, 3 канала значения цвета hsl необходимо извлечь в свои собственные свойства, например:

* {
  --brand-hue: 200;
  --brand-saturation: 100%;
  --brand-lightness: 50%;
}

CSS может выполнять математические операции с этими свойствами цвета, например calc(var(--brand-lightness) - 20%) чтобы уменьшить значение яркости на 20%. Это основа построения цветовой схемы, поскольку CSS может сохранять все цвета в одном и том же семействе оттенков, регулируя насыщенность и яркость hsl.

Светлая тема

Каждый вариант цвета будет отмечен соответствующей схемой, в данном случае к каждому добавляется параметр -light .

предварительный просмотр конечных результатов светлой темы

Бренд

Начиная с цвета бренда, он перестраивается путем заключения пользовательских свойств --brand-hue , --brand-saturation и --brand-lightness в скобки функции hsl () без каких-либо вычислений:

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}

Цвета текста

Далее, для основы цветовой схемы необходимы цвета текста. В светлой теме текст должен быть очень темным. Обратите внимание, насколько низка яркость следующих цветов, значительно ниже 50%.

* {
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
}

--text1-light , поскольку при яркости 10% он очень темный, сохраняется насыщенность на 100%, поэтому цвет бренда все еще может проглядывать в темно-темно-синий.

--text2-light , он не такой темный, как первый цвет, что хорошо, поскольку это второстепенный цвет, а также он гораздо менее насыщенный.

Цвета поверхности

Цвета поверхности — это фон, границы и другие декоративные поверхности, на которых или внутри которых находится текст. В светлой теме это светлые цвета, в отличие от темных цветов текста. Чтобы создать светлые цвета с помощью hsl, мы будем использовать более высокие процентные значения третьего значения яркости. Мы также снизим насыщенность, чтобы светло-серые цвета не выглядели слишком затемненными.

* {
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
}

Было создано 4 цвета поверхности, поскольку декоративные цвета, как правило, требуют большего количества вариантов для интерактивных моментов, таких как :focus или :hover , или для создания видимости слоев бумаги. В этих сценариях полезно перейти --surface2-light при наведении на --surface3-light , поэтому наведение приводит к увеличению контрастности (с 99% яркости до 92% яркости; делая его темнее).

Тени

Тени в цветовой схеме выходят за рамки, но добавляют эффекту реалистичности и помогают ему выделиться среди нереалистичных теней на черной основе. Для этого цвет тени будет использовать пользовательское свойство hue: он будет слегка насыщенным оттенком, но все равно очень темным. По сути, создаем очень темную, слегка синюю тень.

* {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

--surface-shadow-light не заключен в функцию hsl. Это связано с тем, что значение --shadow-strength будет объединено для создания некоторой непрозрачности, а CSS нужны эти части для выполнения вычислений. Перейдите в раздел «Рад-тень», чтобы узнать больше.

Светлые цвета все вместе

Нет необходимости искать, как создаются те или иные цвета света, все они находятся в одном месте в CSS.

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
  --surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
  --shadow-strength-light: .02;
}
скриншот всех светлых цветов вместе
Песочница на CodePen

Темная тема

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

  1. Пользователи, как правило, будут в неведении при использовании этой темы, поэтому тестируйте в темноте.
  2. Цвета должны обесцвечиваться, чтобы не вибрировать на экране из-за чрезмерной интенсивности.

предварительный просмотр конечного результата темной темы

Бренд

В светлой теме использовались значения трех цветовых каналов бренда HSL без изменений, в темной теме — нет. Насыщенность уменьшена вдвое, а яркость уменьшена примерно на 50%.

* {
  --brand-dark: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 2)
    calc(var(--brand-lightness) / 1.5)
  );
}

Цвета текста

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

* {
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
}

Цвета поверхности

В темной теме цвета поверхности должны быть темными. Следующие цвета имеют низкую яркость и насыщенность, причем первая поверхность является самой темной (10%).

* {
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
}

Тени

В темной теме тени может быть очень трудно увидеть. Это имеет смысл, поскольку трудно затемнить то, что и так довольно темное. Здесь очень удобен --shadow-strength-dark , поскольку он позволяет нам затемнить тени, изменив одну переменную.

* {
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}

Также посмотрите, насколько насыщенна эта тень. Можете ли вы заметить цвет, когда смотрите на интерфейс? Попробуйте убрать насыщенность из инструментов разработчика, что вы предпочитаете?!

Темные цвета все вместе

* {
  --brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}
скриншот всех темных цветов вместе
Песочница на CodePen

Тусклая тема

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

предварительный просмотр конечных результатов из тусклой темы

Бренд

* {
  --brand-dim: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 1.25)
    calc(var(--brand-lightness) / 1.25)
  );
}

Цвета текста

* {
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
}

Цвета поверхности

* {
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
}

Тени

* {
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}

Тусклые цвета все вместе

* {
  --brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}
скриншот всех тусклых цветов вместе
Песочница на CodePen

Доступные цвета

Обратите внимание, что самая низкая яркость в наборе цветов темного текста составляет 65%, а самая высокая яркость темных поверхностей — 25%. Это 40% легкости передышки между ними. В светлой теме есть 55% передышки. Поддержание разницы в яркости между цветами текста и поверхности на уровне около 40–50 % может помочь сохранить высокий коэффициент цветового контраста, а также стать тонким рычагом для корректировки в случае плохих оценок.

Я называю это «удар, удар, пока не пройдешь», что представляет собой повышение значения яркости до тех пор, пока инструмент не покажет, что я пас.

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

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

.surface1 {
  background-color: var(--surface1);
  color: var(--text2);
}

.surface2 {
  background-color: var(--surface2);
  color: var(--text2);
}

.surface3 {
  background-color: var(--surface3);
  color: var(--text1);
}

.surface4 {
  background-color: var(--surface4);
  color: var(--text1);
}
Скриншот тусклой поверхности и сочетания текста
Скриншот тусклой поверхности и текстовых сочетаний с VisBug

Рад Тень

Темы используют служебный класс .rad-shadow . Эта тень была создана с помощью инструмента Smooth Shadow , который я очень ценю. Я взял сгенерированный фрагмент и настроил его, используя свои собственные цвета и расчеты непрозрачности. Причина этого заключалась в том, чтобы создать тень, которую я мог бы регулировать в каждой цветовой схеме.

каждая тень рядом друг с другом

Для этого я создал две переменные для каждой цветовой схемы: цвет тени и силу тени. Цвет предназначен для настройки насыщенности и темноты, а сила — для простого способа повысить интенсивность теней в темной цветовой схеме. Конечный результат был примерно таким.

:root {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

.rad-shadow {
  box-shadow:
    0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
    0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
  ;
}

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

Использование цветовых схем

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

Для этого использование цветовой схемы должно осуществляться исключительно через общие пользовательские свойства, которые мы определим чуть позже. Таким образом, людям, использующим переменные дизайна, никогда не придется беспокоиться о том, какая цветовая схема установлена ​​в данный момент, им просто нужно использовать цвета поверхности и текста. Вместо color: var(--text1-light) используйте color: var(--text1) . Вся адаптация и поворот цветов выполняется на гораздо более высоком уровне в CSS.

Подробно рассмотрим соединительные стили светлой темы в следующем блоке кода, соединяющие общее пользовательское свойство с цветом, специфичным для светлой темы. Теперь при любом использовании var(--brand) будет использоваться светлый фирменный цвет.

Светлая тема (авто)

:root {
  color-scheme: light;
  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

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

Тёмная тема (авто)

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --brand: var(--brand-dark);
    --text1: var(--text1-dark);
    --text2: var(--text2-dark);
    --surface1: var(--surface1-dark);
    --surface2: var(--surface2-dark);
    --surface3: var(--surface3-dark);
    --surface4: var(--surface4-dark);
    --surface-shadow: var(--surface-shadow-dark);
    --shadow-strength: var(--shadow-strength-dark);
  }
}

Светлая тема

[color-scheme="light"] {
  color-scheme: light;

  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

Темная тема

[color-scheme="dark"] {
  color-scheme: dark;

  --brand: var(--brand-dark);
  --text1: var(--text1-dark);
  --text2: var(--text2-dark);
  --surface1: var(--surface1-dark);
  --surface2: var(--surface2-dark);
  --surface3: var(--surface3-dark);
  --surface4: var(--surface4-dark);
  --surface-shadow: var(--surface-shadow-dark);
  --shadow-strength: var(--shadow-strength-dark);
}

Тусклая тема

[color-scheme="dim"] {
  color-scheme: dark;

  --brand: var(--brand-dim);
  --text1: var(--text1-dim);
  --text2: var(--text2-dim);
  --surface1: var(--surface1-dim);
  --surface2: var(--surface2-dim);
  --surface3: var(--surface3-dim);
  --surface4: var(--surface4-dim);
  --surface-shadow: var(--surface-shadow-dim);
  --shadow-strength: var(--shadow-strength-dim);
}

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

Заключение

Теперь, когда вы знаете, как я это сделал, как бы вы поступили?! 🙂

Давайте разнообразим наши подходы и изучим все способы разработки в Интернете. Создайте Codepen или разместите собственную демоверсию, напишите мне о ней в Твиттере, и я добавлю ее в раздел ремиксов сообщества ниже.

Источник

Ремиксы сообщества — @chris-kruining добавил ползунок оттенка, цвета статуса и режимы контрастности для no-preference , more и less : демо .