Spec-Zone.ru › CSS

Функция CSS `oklab()`

Базовая поддержка Широко доступна

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и во многих версиях браузеров. Она доступна во всех браузерах с мая 2023 года.

Функциональная запись oklab() задаёт цвет в цветовом пространстве Oklab, которое пытается имитировать восприятие цвета человеческим глазом.

Oklab — перцептивное цветовое пространство, полезное для следующих задач:

  • Преобразование изображения в оттенки серого без изменения его светлоты.
  • Изменение насыщенности цветов с сохранением воспринимаемых пользователем оттенка и светлоты.
  • Создание плавных и равномерных цветовых градиентов (при ручной интерполяции, например, в элементе <canvas>).

oklab() использует декартову систему координат в цветовом пространстве Oklab — оси a и b. Она может представлять более широкий диапазон цветов, чем RGB, включая цвета широкого цветового охвата и P3. Если нужна полярная цветовая система с цветностью и оттенком, используйте oklch().

Синтаксис

/* Absolute values */
oklab(40.1% 0.1143 0.045);
oklab(59.69% 0.1007 0.1191);
oklab(59.69% 0.1007 0.1191 / 0.5);

/* Relative values */
oklab(from green l a b / 0.5)
oklab(from #123456 calc(l + 0.1) a b / calc(alpha * 0.9))
oklab(from hsl(180 100% 50%) calc(l - 0.1) a b)

Значения

Ниже описаны допустимые значения для абсолютных и относительных цветов.

Синтаксис абсолютного значения

oklab(L a b[ / A])

Параметры:

L
<number> от 0 до 1, <percentage> от 0% до 100% или ключевое слово none (в данном случае эквивалентное 0%). Это значение задаёт воспринимаемую светлоту цвета. Число 0 соответствует 0% (чёрному цвету), а число 1 — 100% (белому цвету).
a
<number> от -0.4 до 0.4, <percentage> от -100% до 100% или ключевое слово none (в данном случае эквивалентное 0%). Это значение задаёт положение цвета на оси a в цветовом пространстве Oklab, определяющей, насколько цвет зелёный (в направлении -0.4) или красный (в направлении +0.4). Обратите внимание, что эти значения знаковые (могут быть положительными и отрицательными) и теоретически не ограничены, поэтому можно задавать значения за пределами диапазона ±0.4 (±100%). На практике значения не могут превышать ±0.5.
b
<number> от -0.4 до 0.4, <percentage> от -100% до 100% или ключевое слово none (в данном случае эквивалентное 0%). Это значение задаёт положение цвета на оси b в цветовом пространстве Oklab, определяющей, насколько цвет синий (в направлении -0.4) или жёлтый (в направлении +0.4). Обратите внимание, что эти значения знаковые (могут быть положительными и отрицательными) и теоретически не ограничены, поэтому можно задавать значения за пределами диапазона ±0.4 (±100%). На практике значения не могут превышать ±0.5.
A Необязательно
<alpha-value>, задающее значение альфа-канала цвета: число 0 соответствует 0% (полной прозрачности), а 1 — 100% (полной непрозрачности). Кроме того, ключевое слово none можно использовать, чтобы явно указать отсутствие альфа-канала. Если значение канала A явно не указано, по умолчанию оно равно 100%. Если значение указано, перед ним ставится косая черта (/).

Примечание: Дополнительные сведения о влиянии none см. в разделе Отсутствующие компоненты цвета.

Синтаксис относительного значения

oklab(from <color> L a b[ / A])

Параметры:

from <color>
При задании относительного цвета всегда используется ключевое слово from, за которым следует значение color, представляющее исходный цвет. Это исходный цвет, на основе которого задаётся относительный цвет. В качестве исходного можно использовать любой допустимый синтаксис color, в том числе другой относительный цвет.
L
<number> от 0 до 1, <percentage> от 0% до 100% или ключевое слово none (в данном случае эквивалентное 0%). Это значение задаёт светлоту результирующего цвета. Число 0 соответствует 0% (чёрному цвету), а число 1 — 100% (белому цвету).
a
<number> от -0.4 до 0.4, <percentage> от -100% до 100% или ключевое слово none (в данном случае эквивалентное 0%). Это значение задаёт положение результирующего цвета на оси a в цветовом пространстве Oklab, определяющей, насколько цвет зелёный (в направлении -0.4) или красный (в направлении +0.4). Обратите внимание, что эти значения знаковые (могут быть положительными и отрицательными) и теоретически не ограничены, поэтому можно задавать значения за пределами диапазона ±0.4 (±100%). На практике значения не могут превышать ±0.5.
b
<number> от -0.4 до 0.4, <percentage> от -100% до 100% или ключевое слово none (в данном случае эквивалентное 0%). Это значение задаёт положение результирующего цвета на оси b в цветовом пространстве Oklab, определяющей, насколько цвет синий (в направлении -0.4) или жёлтый (в направлении +0.4). Обратите внимание, что эти значения знаковые (могут быть положительными и отрицательными) и теоретически не ограничены, поэтому можно задавать значения за пределами диапазона ±0.4 (±100%). На практике значения не могут превышать ±0.5.
A Необязательно
<alpha-value>, задающее значение альфа-канала результирующего цвета: число 0 соответствует 0% (полной прозрачности), а 1 — 100% (полной непрозрачности). Кроме того, ключевое слово none можно использовать, чтобы явно указать отсутствие альфа-канала. Если значение канала A явно не указано, по умолчанию оно равно значению альфа-канала исходного цвета. Если значение указано, перед ним ставится косая черта (/).

Определение компонентов каналов результирующего относительного цвета

При использовании синтаксиса относительного цвета внутри функции oklab() браузер преобразует исходный цвет в эквивалентный цвет Oklab (если он ещё не задан в этом формате). Цвет задаётся тремя отдельными значениями цветовых каналов — l (светлота), a (ось зелёный/красный) и b (ось синий/жёлтый), — а также значением альфа-канала (alpha). Эти значения каналов доступны внутри функции и используются при задании значений каналов результирующего цвета:

  • Значение канала l преобразуется в <number> от 0 до 1 включительно.
  • Значения каналов a и b преобразуются каждое в <number> от -0.4 до 0.4 включительно.
  • Значение канала alpha преобразуется в <number> от 0 до 1 включительно.

При задании относительного цвета разные каналы результирующего цвета можно выразить несколькими способами. Ниже рассмотрим несколько примеров.

В первых двух примерах ниже используется синтаксис относительного цвета. Однако первый пример задаёт тот же цвет, что и исходный, а второй — цвет, никак не связанный с исходным. По сути, они не создают относительные цвета! Вряд ли вы будете использовать их в реальном коде — вместо этого, скорее всего, зададите абсолютное значение цвета. Мы включили эти примеры, чтобы начать изучение синтаксиса относительного цвета oklab().

Начнём с исходного цвета hsl(0 100% 50%) (эквивалентного red). Следующая функция задаёт тот же цвет, что и исходный: в качестве значений результирующих каналов используются значения каналов l, a и b исходного цвета (0.627966, 0.22488 и 0.125859):

oklab(from hsl(0 100% 50%) l a b)

Результирующий цвет этой функции — oklab(0.627966 0.22488 0.125859).

В следующей функции используются абсолютные значения каналов результирующего цвета, поэтому она задаёт совершенно другой цвет, не основанный на исходном:

oklab(from hsl(0 100% 50%) 42.1% 0.165 -0.101)

В приведённом выше случае результирующий цвет — oklab(0.421 0.165 -0.101).

Следующая функция создаёт относительный цвет на основе исходного:

oklab(from hsl(0 100% 50%) l -0.3 b)

Этот пример:

  • Преобразует исходный цвет hsl() в эквивалентный цвет oklab() — oklab(0.627966 0.22488 0.125859).
  • Задаёт для каналов L и b результирующего цвета значения каналов L и b эквивалента исходного цвета oklab() — соответственно 0.627966 и 0.125859.
  • Задаёт для канала a результирующего цвета новое значение, не основанное на исходном: -0.3.

Итоговый результирующий цвет — oklab(0.627966 -0.3 0.125859).

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

В рассмотренных до этого момента примерах альфа-каналы исходного и результирующего цветов явно не задавались. Если альфа-канал результирующего цвета не указан, по умолчанию используется то же значение, что и для альфа-канала исходного цвета. Если альфа-канал исходного цвета не указан (и это не относительный цвет), по умолчанию используется 1. Поэтому в приведённых выше примерах значения альфа-каналов исходного и результирующего цветов равны 1.

Рассмотрим примеры с заданными значениями альфа-каналов исходного и результирующего цветов. В первом примере значение альфа-канала результирующего цвета совпадает со значением альфа-канала исходного, а во втором задаётся другое значение, не связанное со значением альфа-канала исходного цвета.

oklab(from hsl(0 100% 50% / 0.8) l a b / alpha)
/* Computed output color: oklab(0.627966 0.22488 0.125859 / 0.8) */

oklab(from hsl(0 100% 50% / 0.8) l a b / 0.5)
/* Computed output color: oklab(0.627966 0.22488 0.125859 / 0.5) */

В следующем примере исходный цвет hsl() снова преобразуется в эквивалент oklab() — oklab(0.627966 0.22488 0.125859). К значениям L, a, b и A применяются вычисления calc(), в результате чего получается цвет oklab(0.827966 0.14488 -0.0741406 / 0.9):

oklab(from hsl(0 100% 50%) calc(l + 0.2) calc(a - 0.08) calc(b - 0.2) / calc(alpha - 0.1))

Примечание: Значения каналов исходного цвета преобразуются в значения <number>, поэтому при использовании их в вычислениях нужно прибавлять к ним числа, даже если для канала обычно допускаются <percentage>, <angle> или значения других типов. Например, сложение <percentage> с <number> не работает.

Формальный синтаксис

<oklab()> = 
  oklab( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ / [<alpha-value> | none] ]? )

<alpha-value> = 
  <number> |
  <percentage>

Примеры

Изменение светлоты

В следующем примере показан эффект изменения значений светлоты, оси a и оси b в функции oklab().

HTML

<div data-color="red-dark"></div>
<div data-color="red"></div>
<div data-color="red-light"></div>

<div data-color="green-dark"></div>
<div data-color="green"></div>
<div data-color="green-light"></div>

<div data-color="blue-dark"></div>
<div data-color="blue"></div>
<div data-color="blue-light"></div>

CSS

body {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
div {
  height: 50px;
  flex: 0 0 28%;
  border: 1px solid black;
}
[data-color="red-dark"] {
  background-color: oklab(0.05 0.4 0.4);
}
[data-color="red"] {
  background-color: oklab(0.5 0.4 0.4);
}
[data-color="red-light"] {
  background-color: oklab(0.95 0.4 0.4);
}

[data-color="green-dark"] {
  background-color: oklab(5% -100% 0.4);
}
[data-color="green"] {
  background-color: oklab(50% -100% 0.4);
}
[data-color="green-light"] {
  background-color: oklab(95% -100% 0.4);
}

[data-color="blue-dark"] {
  background-color: oklab(0.05 -0.3 -0.4);
}
[data-color="blue"] {
  background-color: oklab(0.5 -0.3 -0.4);
}
[data-color="blue-light"] {
  background-color: oklab(0.95 -0.3 -0.4);
}

Результат

Изменение непрозрачности

В следующем примере показан эффект изменения значения A (альфа-канала) в функции oklab(). Элементы red и red-alpha накладываются на элемент #background-div, чтобы продемонстрировать эффект прозрачности. Непрозрачность элемента red-alpha, равная 0.4, делает его более прозрачным, чем элемент red.

HTML

<div id="background-div">
  <div data-color="red"></div>
  <div data-color="red-alpha"></div>
</div>

CSS

div {
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 5px;
  display: inline-block;
  border: 1px solid black;
}
#background-div {
  background-color: lightblue;
  width: 150px;
  height: 40px;
}
[data-color="red"] {
  background-color: oklab(0.628 0.225 0.126);
}
[data-color="red-alpha"] {
  background-color: oklab(0.628 0.225 0.126 / 0.4);
}

Результат

Изменение цветовых осей

В этом примере показан эффект задания значений a и b функции oklab() в крайних и средних точках осей a и b соответственно. Ось a проходит от зелёного (-0.4) до красного (0.4), а ось b — от жёлтого (-0.4) до синего (0.4).

HTML

<div data-color="red-yellow"></div>
<div data-color="red-zero"></div>
<div data-color="red-blue"></div>

<div data-color="zero-yellow"></div>
<div data-color="zero-zero"></div>
<div data-color="zero-blue"></div>

<div data-color="green-yellow"></div>
<div data-color="green-zero"></div>
<div data-color="green-blue"></div>

CSS

С помощью CSS-свойства background-color мы изменяем значения a и b функции цвета oklab() вдоль осей a и b, показывая эффекты максимальных, средних и минимальных значений для каждой оси.

body {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
}
div {
  height: 50px;
  flex: 0 0 28%;
  border: 1px solid black;
}
/* a-axis max, variable b-axis */
[data-color="red-yellow"] {
  background-color: oklab(0.5 0.4 0.4);
}
[data-color="red-zero"] {
  background-color: oklab(0.5 0.4 0);
}
[data-color="red-blue"] {
  background-color: oklab(0.5 0.4 -0.4);
}

/* a-axis center, variable b-axis */
[data-color="zero-yellow"] {
  background-color: oklab(0.5 0 0.4);
}
[data-color="zero-zero"] {
  background-color: oklab(0.5 0 0);
}
[data-color="zero-blue"] {
  background-color: oklab(0.5 0 -0.4);
}

/* a-axis min, variable b-axis */
[data-color="green-yellow"] {
  background-color: oklab(0.5 -0.4 0.4);
}
[data-color="green-zero"] {
  background-color: oklab(0.5 -0.4 0);
}
[data-color="green-blue"] {
  background-color: oklab(0.5 -0.4 -0.4);
}

Результат

Левый столбец соответствует жёлтому концу (-0.4) оси b, а правый — синему концу (0.4). В верхней строке показаны цвета на красном конце оси a (-0.4), а в нижней — на зелёном конце (0.4). Средние столбец и строка соответствуют средним точкам каждой оси; ячейка в центре — серая: в ней нет красного, зелёного, жёлтого или синего, а значения обеих осей равны 0.

Линейные градиенты вдоль осей a и b

В этом примере линейные градиенты демонстрируют изменение значений функции oklab() вдоль оси a (от красного к зелёному) и вдоль оси b (от жёлтого к синему). На каждом изображении с градиентом одна ось остаётся неизменной, а значения другой оси постепенно изменяются от низких к высоким.

<div data-color="red-to-green-yellow">
  <span>red</span><span>`b`= -0.4 (yellow)</span><span>green</span>
</div>
<div data-color="red-to-green-zero">
  <span>red</span><span>no yellow or blue</span><span>green</span>
</div>
<div data-color="red-to-green-blue">
  <span>red</span><span>`b`= 0.4 (blue)</span><span>green</span>
</div>

<div data-color="yellow-to-blue-red">
  <span>yellow</span><span>`a` = -0.4 (red)</span><span>blue</span>
</div>
<div data-color="yellow-to-blue-zero">
  <span>yellow</span><span>no red or green</span><span>blue</span>
</div>
<div data-color="yellow-to-blue-green">
  <span>yellow</span><span>`a` = 0.4 (green)</span><span>blue</span>
</div>

CSS

div {
  height: 50px;
  padding: 5px;
  margin: 5px;
  border: 1px solid black;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
span {
  background-color: #ffffffcc;
  padding: 3px;
}
/* a-axis gradients */
[data-color="red-to-green-yellow"] {
  background-image: linear-gradient(to right, oklab(50% 0.4 0.4), oklab(50% -0.4 0.4));
}
[data-color="red-to-green-zero"] {
  background-image: linear-gradient(to right, oklab(50% 0.4 0), oklab(50% -0.4 0));
}
[data-color="red-to-green-blue"] {
  background-image: linear-gradient(to right, oklab(50% 0.4 -0.4), oklab(50% -0.4 -0.4));
}

/* b-axis gradients */
[data-color="yellow-to-blue-red"] {
  background-image: linear-gradient(to right, oklab(50% 0.4 0.4), oklab(50% 0.4 -0.4));
}
[data-color="yellow-to-blue-zero"] {
  background-image: linear-gradient(to right, oklab(50% 0 0.4), oklab(50% 0 -0.4));
}
[data-color="yellow-to-blue-green"] {
  background-image: linear-gradient(to right, oklab(50% -0.4 0.4),oklab(50% -0.4 -0.4));
}

Результат

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

В этом примере для трёх элементов <div> задаются разные цвета фона. Для среднего элемента используется неизменённый --base-color, а для левого и правого — осветлённый и затемнённый варианты этого --base-color.

Эти варианты задаются с помощью относительных цветов: пользовательское свойство --base-color передаётся в функцию oklab(), а в результирующих цветах изменяется канал светлоты для достижения нужного эффекта с помощью функции calc(). Для осветлённого цвета к каналу светлоты прибавляется 0.15 (15%), а для затемнённого из канала светлоты вычитается 0.15 (15%).

<div id="container">
  <div class="item" id="one"></div>
  <div class="item" id="two"></div>
  <div class="item" id="three"></div>
</div>

CSS

#container {
  display: flex;
  width: 100vw;
  height: 100vh;
  box-sizing: border-box;
}

.item {
  flex: 1;
  margin: 20px;
}
:root {
  --base-color: orange;
}

#one {
  background-color: oklab(from var(--base-color) calc(l + 0.15) a b);
}

#two {
  background-color: var(--base-color);
}

#three {
  background-color: oklab(from var(--base-color) calc(l - 0.15) a b);
}

Результат

Результат:

Спецификации

Спецификация
Модуль CSS Color, уровень 5
# relative-Oklab
Модуль CSS Color, уровень 4
# ok-lab

Совместимость с браузерами

Настольные Мобильные
Chrome Edge Firefox Opera Safari Chrome Android Firefox для Android Opera Android Safari для iOS Samsung Internet WebView Android WebView для iOS
oklab
111
111
113
97
15.4
111
113
75
15.4
22.0
111
15.4
mixed_type_parameters
116
116
113
102
16.2
116
113
78
16.2
24.0
116
16.2
relative_syntax
122
119–122Значения каналов l ошибочно преобразуются в числа от 0 до 100 вместо чисел от 0 до 1. Поэтому при вычислении значений каналов необходимо задавать значения l в виде чисел-процентов без единиц измерения (например, 20 вместо 0.2). См. ошибку 40940488.
122
119–122Значения каналов l ошибочно преобразуются в числа от 0 до 100 вместо чисел от 0 до 1. Поэтому при вычислении значений каналов необходимо задавать значения l в виде чисел-процентов без единиц измерения (например, 20 вместо 0.2). См. ошибку 40940488.
128
108
105–108Значения каналов l ошибочно преобразуются в числа от 0 до 100 вместо чисел от 0 до 1. Поэтому при вычислении значений каналов необходимо задавать значения l в виде чисел-процентов без единиц измерения (например, 20 вместо 0.2). См. ошибку 40940488.
16.4
122
119–122Значения каналов l ошибочно преобразуются в числа от 0 до 100 вместо чисел от 0 до 1. Поэтому при вычислении значений каналов необходимо задавать значения l в виде чисел-процентов без единиц измерения (например, 20 вместо 0.2). См. ошибку 40940488.
128
81
79–81Значения каналов l ошибочно преобразуются в числа от 0 до 100 вместо чисел от 0 до 1. Поэтому при вычислении значений каналов необходимо задавать значения l в виде чисел-процентов без единиц измерения (например, 20 вместо 0.2). См. ошибку 40940488.
16.4
26.0
25.0–26.0Значения каналов l ошибочно преобразуются в числа от 0 до 100 вместо чисел от 0 до 1. Поэтому при вычислении значений каналов необходимо задавать значения l в виде чисел-процентов без единиц измерения (например, 20 вместо 0.2). См. ошибку 40940488.
122
119–122Значения каналов l ошибочно преобразуются в числа от 0 до 100 вместо чисел от 0 до 1. Поэтому при вычислении значений каналов необходимо задавать значения l в виде чисел-процентов без единиц измерения (например, 20 вместо 0.2). См. ошибку 40940488.
16.4

См. также

  • Тип данных <color> со списком всех способов записи цветов
  • Функции цвета lab() и oklch()
  • Использование относительных цветов
  • Модуль CSS Colors
  • Перцептивное цветовое пространство для обработки изображений на bottosson.github.io (2023)
  • Цветовой круг OKLAB на observablehq.com

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/oklab

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API