Оттенки серого с помощью color-mix()
![](/static/storage/222394806287152713100870935353486083173.png)
Серый. Кто его не любит? Когда речь идет о создании сайтов, удобно иметь в своем распоряжении несколько оттенков серого, независимо от цветовой палитры. Мы используем их для создания границ и тонких разделителей, теней, а также для обозначения изменений состояния, не перегружая пользователя цветом. Некоторые дизайнеры считают, что для передачи тонкостей на сайте необходимо использовать несколько оттенков серого. Однажды я работал над проектом, в котором было буквально 50 оттенков серого.
Если ваш родной язык — американский английский, вас может немного смутить мое написание слова «grey». К счастью, цвета в CSS очень инклюзивны, когда дело доходит до серого. Все оттенки серого представлены в вариантах US/UK — выбирайте из этих красавцев:
- lightgrey/lightgray (светло-серый)
- grey/gray (серый)
- darkgrey/darkgray (which is lighter than grey/gray!) (тёмно-серый, но он темнее обычного серого)
- lightslategrey/lightslategray
- slategrey/slategray
- darkslategrey/darkslategray
- dimgrey/dimgray
- whitesmoke (technically a grey) (белая дымка, технически серый)
- silver (also grey) (серебряный, тоже серый)
Однако они, скорее всего, не подойдут для всех ваших потребностей в пользовательском интерфейсе. Нам нужен хороший выбор серых цветов, дополняющих нашу цветовую палитру. Конечно, мы можем использовать цветовой набор и наш любимый инструмент дизайна (скучный). Или мы можем создать палитру серых цветов с помощью функции CSS color-mix()
. Давайте остановимся на втором варианте.
Пособие по color-mix()
Функция color-mix()
позволяет смешивать процентные соотношения двух цветов и выводить результат. Для её использования необходимо указать три аргумента: метод цветовой интерполяции и два цвета, которые мы хотим смешать. Мы можем указать пропорции каждого цвета в процентах. Если мы опустим эти значения, они будут смешаны 50/50, или мы можем указать один из них, а другой будет изменен таким образом, что они будут равны 100%.
/* 50% red, 50% blue */
color-mix(in srgb, red, blue)
/* 60% red, 40% blue */
color-mix(in srgb, red 60%, blue)
/* 60% red, 40% blue */
color-mix(in srgb, red, blue 40%)
Если мы захотим разобраться в деталях, то нам придется изучить ещё много чего, особенно когда речь идет о том, как работают различные методы интерполяции цвета. Я рекомендую доклад Криса Лилли на CSS Day, если вы хотите понять, насколько сложным может быть цвет. Если когда-либо и существовала тема, способная расплавить ваш мозг, то это цвет в Интернете. Но если вы просто хотите смешать пару цветов, то сама функция color-mix()
в целом довольно интуитивна.
Что такое серый цвет?
Давайте вернемся к серому цвету. Нас с детства учат, что серый цвет получается от смешивания черного и белого. Это правда, поскольку это, конечно, дает нам оттенки серого, но когда дело доходит до дизайна, наш выбор серого цвета, как правило, не такой однообразный. Мы можем захотеть использовать более теплые или более холодные оттенки серого, которые смешиваются с небольшим количеством цвета, и всё же мы будем называть результат "серым" в нашей цветовой палитре или системе дизайна.
Простые серые цвета с помощью color-mix()
Мы можем смешивать черный и белый цвета с помощью функции color-mix()
, чтобы создать различные оттенки серого, от светлого до темного. Здесь мы будем смешивать их с шагом в 20 %, от 20 % черного/80 % белого до 80 % черного/20 % белого, сохраняя их как пользовательские свойства, чтобы можно было использовать их в любом месте нашего CSS. (Исходная переменная --grey
, как мы видели в предыдущем примере, принимает значение 50% черного/50% белого).
:root {
--grey: color-mix(in oklch, black, white);
--grey-20: color-mix(in oklch, black 20%, white);
--grey-40: color-mix(in oklch, black 40%, white);
--grey-60: color-mix(in oklch, black 60%, white);
--grey-80: color-mix(in oklch, black 80%, white);
}
Нам нужно указать процентное соотношение только для одного из цветов (в данном случае черного), второй будет подразумеваться.
Конечно, если вы действительно хотите получить 50 оттенков серого, создавайте столько переменных, сколько хотите. Можете даже вставить туда несколько calc()
, я не против.
:root {
--steps: 50;
--increment: calc(100% / var(--steps));
--grey-1: color-mix(in oklch, black var(--increment), white);
--grey-2: color-mix(in oklch, black calc(var(--increment) * 2), white);
--grey-3: color-mix(in oklch, black calc(var(--increment) * 3), white);
/* etc. */
}
Небольшое замечание о цветовых пространствах (обещаю, оно будет кратким): Мы используем oklch
, потому что цвета в этом пространстве перцептивно однородны. Это означает, что процентная разница между цветами (серыми в том числе) будет восприниматься зрителем как одинаковая. Если мы сравним те же пять оттенков серого в пространстве srgb
, то увидим, что разница есть.
* {
box-sizing: border-box;
}
:root {
--space: oklch;
--grey-20: color-mix(in var(--space), black 20%, white);
--grey-40: color-mix(in var(--space), black 40%, white);
--grey: color-mix(in var(--space), black, white);
--grey-60: color-mix(in var(--space), black 60%, white);
--grey-80: color-mix(in var(--space), black 80%, white);
}
ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
}
li {
width: calc(100% / 5);
aspect-ratio: 1;
background: var(--grey);
&:first-child {
background: var(--grey-20);
}
&:nth-child(2) {
background: var(--grey-40);
}
&:nth-child(4) {
background: var(--grey-60);
}
&:nth-child(5) {
background: var(--grey-80);
}
}
.srgb {
--space: srgb;
--grey-20: color-mix(in var(--space), black 20%, white);
--grey-40: color-mix(in var(--space), black 40%, white);
--grey: color-mix(in var(--space), black, white);
--grey-60: color-mix(in var(--space), black 60%, white);
--grey-80: color-mix(in var(--space), black 80%, white);
}
У Леа Вероу есть отличная статья о цветах LCH в CSS, в том числе о том, что на самом деле означает однородность восприятия.
Оттенки серого
Теперь давайте создадим более теплые и более холодные оттенки серого, смешав другой цвет с нашими серыми переменными. Да, именно так, мы можем смешивать цвета, выводимые функцией color-mix()
.
Для более холодных серых тонов мы добавим немного синего. Мы используем цвет CSS с именем blue
, который соответствует rgb(0 0 255)
, но не стесняйтесь использовать любой синий или голубоватый цвет в любом цветовом пространстве, которое вам нравится. Мы собираемся смешать одинаковое количество цвета с каждым из наших серых оттенков, поэтому создадим пользовательское свойство "mixer". Таким образом, если мы захотим изменить наш синий тон, нам нужно будет сделать это только в одном месте.
:root {
--blue-mixer: blue 10%;
}
Затем с помощью функции color-mix()
мы подмешаем его к нашему исходному набору серых цветов, создав новый набор пользовательских свойств:
:root {
--blue-grey: color-mix(in oklch, var(--grey), var(--blue-mixer));
--blue-grey-20: color-mix(in oklch, var(--grey-20), var(--blue-mixer));
--blue-grey-40: color-mix(in oklch, var(--grey-40), var(--blue-mixer));
--blue-grey-60: color-mix(in oklch, var(--grey-60), var(--blue-mixer));
--blue-grey-80: color-mix(in oklch, var(--grey-80), var(--blue-mixer));
}
![](/static/storage/295109641183949934863267037255512996745.png)
Возможно, они слишком синие для вас? Конечно, вы можете уменьшить или увеличить количество синего цвета, изменив процентное значение в пользовательском свойстве --blue-mixer
.
То же самое мы можем сделать с красным оттенком, чтобы создать теплые серые цвета. Кто сказал, что серый должен быть скучным?
* {
box-sizing: border-box;
}
:root {
--space: oklch;
--grey-20: color-mix(in var(--space), black 20%, white);
--grey-40: color-mix(in var(--space), black 40%, white);
--grey: color-mix(in var(--space), black, white);
--grey-60: color-mix(in var(--space), black 60%, white);
--grey-80: color-mix(in var(--space), black 80%, white);
--blue-mixer: blue 5%;
--blue-grey-20: color-mix(in var(--space), var(--grey-20), var(--blue-mixer));
--blue-grey-40: color-mix(in var(--space), var(--grey-40), var(--blue-mixer));
--blue-grey: color-mix(in var(--space), var(--grey), var(--blue-mixer));
--blue-grey-60: color-mix(in var(--space), var(--grey-60), var(--blue-mixer));
--blue-grey-80: color-mix(in var(--space), var(--grey-80), var(--blue-mixer));
--red-mixer: red 5%;
--red-grey-20: color-mix(in var(--space), var(--grey-20), var(--red-mixer));
--red-grey-40: color-mix(in var(--space), var(--grey-40), var(--red-mixer));
--red-grey: color-mix(in var(--space), var(--grey), var(--red-mixer));
--red-grey-60: color-mix(in var(--space), var(--grey-60), var(--red-mixer));
--red-grey-80: color-mix(in var(--space), var(--grey-80), var(--red-mixer));
}
ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
}
li {
width: calc(100% / 5);
aspect-ratio: 1;
background: var(--grey);
&:first-child {
background: var(--grey-20);
}
&:nth-child(2) {
background: var(--grey-40);
}
&:nth-child(4) {
background: var(--grey-60);
}
&:nth-child(5) {
background: var(--grey-80);
}
}
.blue-grey {
li {
background: var(--blue-grey);
&:first-child {
background: var(--blue-grey-20);
}
&:nth-child(2) {
background: var(--blue-grey-40);
}
&:nth-child(4) {
background: var(--blue-grey-60);
}
&:nth-child(5) {
background: var(--blue-grey-80);
}
}
}
.red-grey {
li {
background: var(--red-grey);
&:first-child {
background: var(--red-grey-20);
}
&:nth-child(2) {
background: var(--red-grey-40);
}
&:nth-child(4) {
background: var(--red-grey-60);
}
&:nth-child(5) {
background: var(--red-grey-80);
}
}
}