Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Современные цвета

В уроке о цветах были rgb() и hsl(). У них есть недостаток: числа плохо совпадают с тем, как цвет видит глаз. Современный CSS добавил функцию oklch(), в которой одинаковые числа означают одинаковую на вид яркость, и инструменты, чтобы получать новые цвета из уже существующих.

Функция oklch()

oklch() принимает три числа: светлоту L (от 0% — чёрный, до 100% — белый), насыщенность C (от 0 — серый, примерно до 0.37 — самый яркий) и оттенок H — угол на цветовом круге от 0 до 360:

<style>
  .swatch { display: inline-block; width: 90px; padding: 24px 0; text-align: center; color: white; }
</style>
 
<div class="swatch" style="background: oklch(60% 0.2 25);">красный</div>
<div class="swatch" style="background: oklch(60% 0.2 145);">зелёный</div>
<div class="swatch" style="background: oklch(60% 0.2 260);">синий</div>

Устройство похоже на hsl(), только порядок другой: сначала светлота, в конце оттенок.

Почему не hsl()

Светлота в hsl() — математическая, а не та, что видит глаз. При одинаковых 50% жёлтый выглядит почти белым, а синий — тёмным. В oklch() одинаковая светлота действительно выглядит одинаково:

<style>
  .row { display: flex; gap: 4px; margin-bottom: 4px; }
  .row div { flex: 1; padding: 12px 0; text-align: center; }
</style>
 
<div class="row">
  <div style="background: hsl(60 100% 50%);">hsl</div>
  <div style="background: hsl(120 100% 50%);">hsl</div>
  <div style="background: hsl(240 100% 50%);">hsl</div>
</div>
<div class="row">
  <div style="background: oklch(75% 0.15 100);">oklch</div>
  <div style="background: oklch(75% 0.15 145);">oklch</div>
  <div style="background: oklch(75% 0.15 260);">oklch</div>
</div>

В верхнем ряду текст на синем почти не читается, в нижнем все три цвета одинаково светлые.

Палитра из одного оттенка

Раз светлота честная, палитру получают, меняя только первое число. Оттенок вынесен в переменную — поменяйте его, и вся шкала перекрасится:

<style>
  .palette { --hue: 260; display: flex; }
  .palette div { flex: 1; height: 40px; }
</style>
 
<div class="palette">
  <div style="background: oklch(95% 0.03 var(--hue));"></div>
  <div style="background: oklch(80% 0.1 var(--hue));"></div>
  <div style="background: oklch(65% 0.15 var(--hue));"></div>
  <div style="background: oklch(50% 0.15 var(--hue));"></div>
  <div style="background: oklch(35% 0.1 var(--hue));"></div>
</div>

Смешивание: color-mix()

color-mix() смешивает два цвета в заданной пропорции. Первым аргументом указывают, в каком пространстве смешивать, — обычно in oklch. Так получают оттенок для наведения из фирменного цвета:

<style>
  :root { --brand: royalblue; }
  .btn { padding: 8px 16px; border: none; color: white; background: var(--brand); }
  .btn:hover { background: color-mix(in oklch, var(--brand), black 25%); }
  .soft { padding: 8px; margin-top: 8px; background: color-mix(in oklch, var(--brand) 15%, white); }
</style>
 
<button class="btn">Наведите на кнопку</button>
<div class="soft">Бледный фон из того же цвета</div>

Относительные цвета

Относительный синтаксис берёт готовый цвет, раскладывает его на части l, c и h и собирает новый. Каждую часть можно оставить или изменить через calc():

<style>
  :root { --brand: oklch(55% 0.18 260); }
  .box { display: inline-block; width: 100px; padding: 16px 0; text-align: center; color: white; }
</style>
 
<div class="box" style="background: var(--brand);">основной</div>
<div class="box" style="background: oklch(from var(--brand) calc(l + 0.2) c h);">светлее</div>
<div class="box" style="background: oklch(from var(--brand) l c calc(h + 180));">напротив</div>
<div class="box" style="background: oklch(from var(--brand) l c h / 40%);">прозрачный</div>

Поменяйте --brand — все производные цвета пересчитаются. oklch() и color-mix() работают во всех основных браузерах с 2023 года, относительный синтаксис — с 2024 года.

Частая ошибка

Светлота без знака процента. В oklch() светлоту можно писать процентами или числом от 0 до 1. Запись oklch(70 0.15 250) означает не 70%, а 70 — больше единицы, и цвет становится белым:

<style>
  div { padding: 12px; margin-bottom: 4px; border: 1px solid silver; }
</style>
 
<div style="background: oklch(70 0.15 250);">oklch(70 0.15 250) — белый</div>
<div style="background: oklch(70% 0.15 250);">oklch(70% 0.15 250) — голубой</div>
<div style="background: oklch(0.7 0.15 250);">oklch(0.7 0.15 250) — тоже голубой</div>

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.