Функция 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);
}
Результат
Результат:
Спецификации
Совместимость с браузерами
| Настольные | Мобильные | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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