(Issue)
This proposal adds Sass support for several new CSS color spaces defined in CSS Color Level 4 – including access to non-RGB color models and colors outside the sRGB gamut.
Table of Contents ¶
Background ¶
This section is non-normative.
When working with color on the web, there are a few important terms:
- A color model is a mathematical approach to representing colors and their relationships. Historically, RGB has been the dominant color model for both computer monitors and web browsers. Lately, CIELab and OKLab models have shown significant benefits by providing a more perceptually uniform distribution of colors, so that similar mathematical adjustments achieve visually similar results.
- A color space is the result of projecting a color model into a coordinate
system. In CSS, each color format describes a specific (and often unique)
color space. For example,
rgb()
projects the RGB color model into a cubic coordinate system, andhsl()
projects the same model into a cylindrical (polar-angle) space. Different spaces will have different benefits when adjusting or interpolating colors for different purposes. - A color gamut is the full range of colors that can be described in a color space. Historically, all CSS spaces have been limited to the same sRGB gamut. However, modern computer monitors often support wider gamuts like display-p3.
New CSS Color Spaces ¶
The CSS Color Level 4 specification defines a number of new color spaces, each with its own syntax, but representing both new color models and wider color gamuts.
CSS color manipulation & interpolation functions will use the OKLab color space by default, unless otherwise defined for specific functions, or unless legacy behavior needs to be maintained. The CIE model will act a central reference for moving between spaces. Both models can be accessed in either cubic (LAB) or cylindrical (LCH) space:
OKlab()
improves the perceptual uniformity of CIE LABOKlch()
improves the perceptual uniformity of CIE LCH- (CIE)
lab()
is a cubic projection, using linear coordinates (likergb()
) - (CIE)
lch()
is cylindrical, using polar angles for hue (likehsl()
)
The new color()
function provides access to a number of less common spaces.
The CIE XYZ spaces act as a central reference for conversion, with a gamut that
covers all human-visible colors.
color(<space> <x> <y> <z> / <a>)
:xyz-d50
(D50 reference white)xyz-d65
(D65 reference white)xyz
(Default D65 reference white)
The remaining spaces are all extensions of the RGB color model, providing wider gamuts, improved bit-depth precision, or removed gamma-encoding:
color(sRGB <r> <g> <b> / <a>)
provides more bit depth precision when accessing the current sRGB gamut of colors.color(sRGB-linear <r> <g> <b> / <a>)
provides the same sRGB gamut, without gamma-encoding (using a linear-light transfer function).color(<space> <r> <g> <b> / <a>)
provides access to wider gamuts, such as:display-p3
(common on modern displays)a98-rgb
prophoto-rgb
rec2020
Since the display-p3
color space represents a common space for wide-gamut
monitors, that is likely to be one of the more popular color spaces for authors
who simply want access to a wider range of colors – and don’t require the
improved uniformity of manipulation or ease-of-use provided by CIE & OK spaces.
The sRGB
syntax is also useful as a way to ‘opt out’ of legacy color handling
for RGB colors.
Missing & Powerless Color Components ¶
CSS Color Level 4 also adds support for ‘missing’ & ‘powerless’
color components. For example, when converting a grayscale color to a
polar-angle space like hsl
, the resulting hue
is unknown. Similarly, at the
extremes of lightness
(eg black
or white
), both hue
and saturation
become ‘powerless’ – changing them has no impact.
This can now be represented in CSS & Sass by using a value of none
, so that
the color white
becomes effectively hsl(none none 100%)
. The none
value
is treated as 0
in most cases, but when interpolating two colors, a none
value takes it’s value from the other color involved.
This also allows interpolating specific channels of a color. For example,
any color can be moved towards ‘grayscale’ by mixing it with the color
oklch(none 0% none)
.
Color Conversion and Gamut Mapping ¶
The CSS Color Level 4 specification defines algorithms for conversion between all the new and existing color spaces. Still, since some spaces provide access to wider gamuts than others, it is possible for a color defined or manipulated in one color space to be ‘out-of-gamut’ when converted to another space.
There are various possible ways to ‘map’ an out-of-gamut color to its nearest in-gamut relative, and the spec provides some advice on how that can be done. In order to avoid data-loss, it’s often best to leave gamut-mapping as a detail for the browser to manage, based on the gamut of the display. Still, it would be good for Sass to provide some explicit gamut-mapping tools for authors to use when converting newer color-systems into backwards-compatible output.
The primary approach is to reduce the chroma
value of a color in OKlch
space, until it is reasonably ‘close’, and then clamping channel values in the
destination color space. Chroma reduction helps avoid more noticeable shifts in
lightness
and hue
, while the final clamping helps avoid dramatic chroma
shifts when a more subtle movement is possible.
Browser Support ¶
WebKit/Safari is already shipping support for all these new color spaces, and Gecko/Firefox has released some early drafts behind an experimental flag. These features are also included as a goal of [Interop 2022][interop], which makes them likely to roll out in all browsers by the end of the year.
Summary ¶
This section is non-normative.
This proposal defines global (un-prefixed) Sass support for all of the
color functions in CSS Color Level 4 (hwb()
, lab()
/lch()
,
oklab()
/oklch()
, color()
). All (new and existing) color functions are
also extended to support both:
- An awareness of multiple color spaces and gamuts where appropriate
none
values (explicitly set, or generated during conversion/interpolation)
Additionally, this proposal provides new functions in the sass color module for inspecting a color’s space, as well as converting & gamut-mapping across different spaces.
Design Decisions ¶
Because all previously-available CSS color spaces provided the same gamut of colors using the same color model, both CSS & Sass have considered them interchangeable, converting between them silently, and using RGB/a internally. In order to move forward while maintaining backwards compatibility, both CSS & Sass will need to maintain some legacy handling for these legacy colors, while providing a way to opt into the new defaults used by newer color syntax.
The proposed solution in CSS is that:
- Legacy colors in legacy functions continue to use
srgb
space - If new color syntax is involved, the default interpolation space is
oklch
- Individual functions can override the default, if a different space is better suited to the specific task
- Individual functions can also provide authors with a syntax to select the interpolation space explicitly
CSS serialization converts all hex, rgb(a), hsl(a), hwb, and named colors
to their rgb(a) equivalent, as part of a shared srgb
space. However:
hsl
andhwb
remain distinct spaces for interpolation functions to use.- the
color(srgb …)
syntax is also part ofsrgb
space, but has higher bit depth, and opts out of legacy interpolation behavior.
We have attempted to match this behavior.
Definitions ¶
Color ¶
A color is an object with several parts:
-
A string color space
-
An ordered list of channel values as defined by that [color space][].
-
A numeric alpha value which can be safely clamped in the
0-1
or0%-100%
range. Values outside that range are allowed, but meaningless. -
A boolean is-legacy to indicate a legacy color.
Legacy Color ¶
Both Sass and CSS have similar legacy behavior that relies on all colors being interchangeable as part of a shared
srgb
color space. While the new color formats will opt users into new default behavior, some legacy color formats behave differently for the sake of backwards-compatibility.
Colors that are defined using the CSS color names, hex syntax, rgb()
,
rgba()
, hsl()
, hsla()
, or hwb()
– along with colors that result from
legacy interpolation – are considered legacy colors. All legacy colors use
the srgb
color space, with red
, green
, and blue
channels. The output of
a legacy color is not required to match the input syntax.
Color Space ¶
Every color is stored internally as part of a defined color space. Each space
has a name, and an ordered list of associated channels that can be accessed and
manipulated in that space. Each channel value can be any number, or the keyword
none
.
Bounded channels have a clearly-defined range that can be mapped to percentage values and scaled, even if those channels are not clamped to the range given.
This follows the CSS specification, which defines percentage-mapping onto several channels that are technically unbounded. However, some channels (marked below) are percentage-mapped without a clear boundary for scaling.
Legacy colors are converted to srgb
internally, with any
missing channels (specified using the none
keyword) set to 0
.
The color spaces and their channels are:
srgb
(RGB):red
(bounded [0,1] or [0,255], depending on host syntax)green
(bounded [0,1] or [0,255], depending on host syntax)blue
(bounded [0,1] or [0,255], depending on host syntax)
hwb
(RGB):hue
(polar angle)whiteness
(bounded percentage)blackness
(bounded percentage)
hsl
(RGB):hue
(polar angle)saturation
(bounded percentage)lightness
(bounded percentage)
srgb-linear
(RGB):red
(bounded [0,1])green
(bounded [0,1])blue
(bounded [0,1])
display-p3
(RGB):red
(bounded [0,1])green
(bounded [0,1])blue
(bounded [0,1])
a98-rgb
(RGB):red
(bounded [0,1])green
(bounded [0,1])blue
(bounded [0,1])
prophoto-rgb
(RGB):red
(bounded [0,1])green
(bounded [0,1])blue
(bounded [0,1])
rec2020
(RGB):red
(bounded [0,1])green
(bounded [0,1])blue
(bounded [0,1])
xyz
:x
(percentage-mapped0% = 0.0, 100% = 1.0
)y
(percentage-mapped0% = 0.0, 100% = 1.0
)z
(percentage-mapped0% = 0.0, 100% = 1.0
)
xyz-d50
:x
(percentage-mapped0% = 0.0, 100% = 1.0
)y
(percentage-mapped0% = 0.0, 100% = 1.0
)z
(percentage-mapped0% = 0.0, 100% = 1.0
)
xyz-d65
:x
(percentage-mapped0% = 0.0, 100% = 1.0
)y
(percentage-mapped0% = 0.0, 100% = 1.0
)z
(percentage-mapped0% = 0.0, 100% = 1.0
)
lab
:lightness
(percentage-mapped0% = 0.0, 100% = 100.0
)a
(percentage-mapped-100% == -125, 100% == 125
)b
(percentage-mapped-100% == -125, 100% == 125
)
lch
:lightness
(percentage-mapped0% = 0.0, 100% = 100.0
)chroma
(percentage-mapped0% = 0, 100% = 150
)hue
(polar angle)
oklab
:lightness
(percentage-mapped0% = 0.0, 100% = 1.0
)a
(percentage-mapped-100% = -0.4, 100% = 0.4
)b
(percentage-mapped-100% = -0.4, 100% = 0.4
)
oklch
:lightness
(percentage-mapped0% = 0.0, 100% = 1.0
)chroma
(percentage-mapped0% = 0.0, 100% = 0.4
)hue
(polar angle)
Predefined Color Spaces ¶
‘Predefined color spaces’ can be described using the
color()
function.
The predefined RGB spaces are:
srgb-linear
display-p3
a98-rgb
prophoto-rgb
rec2020
The predefined XYZ spaces are:
xyz
xyz-d50
xyz-d65
Missing Components ¶
In some cases, a color can have one or more missing components (channel or
alpha values). Missing components are represented by the keyword none
. When
interpolating between colors, the missing component is replaced by the value
of that same component in the other color. In all other cases, the missing
value is treated as 0
.
Powerless Components ¶
In some color spaces, it is possible for a channel value to become ‘powerless’
in certain circumstances. If a powerless channel value is produced as the
result of color-space conversion, then that value is considered to be
missing, and is replaced by the keyword none
.
-
hsl
:-
If the
saturation
value is0%
, then thehue
channel is powerless. -
If the
lightness
value is either0%
or100%
, then both thehue
andsaturation
values are powerless.
-
-
hwb
:- If the combined
whiteness
andblackness
values (after normalization) are equal to100%
, then thehue
channel is powerless.
- If the combined
-
lab
/oklab
:- If the
lightness
value is0%
, then both thea
andb
channels are powerless.
The current spec has an open issue to determine if high values of
lightness
(whites) should make thea
andb
values powerless. - If the
-
lch
/oklch
:-
If the
chroma
value is 0%, then thehue
channel is powerless. -
If the
lightness
value is0%
, then both thehue
andchroma
channels are powerless.
The current spec has an open issue to determine if high values of
lightness
(whites) should make thehue
andchroma
values powerless. -
Color Gamuts ¶
A color gamut is a range of colors that can be displayed by a given device, or described in a given color space. The predefined RGB gamuts are:
srgb
display-p3
a98-rgb
prophoto-rgb
rec2020
There are several color spaces that are associated with the srgb
gamut:
srgb-linear
hwb
hsl
All other color spaces describe unknown or theoretically infinite gamuts.
Color Interpolation Method ¶
<x><pre>
**ColorInterpolationMethod** ::= 'in' (
  RectangularColorSpace
  | PolarColorSpace HueInterpolationMethod?
  )
**RectangularColorSpace** ::= 'srgb'
  | 'srgb-linear'
  | 'lab'
  | 'oklab'
  | 'xyz'
  | 'xyz-d50'
  | 'xyz-d65'
**PolarColorSpace** ::= 'hsl'
  | 'hwb'
  | 'lch'
  | 'oklch'
**HueInterpolationMethod** ::= (
  'shorter'
  | 'longer'
  | 'increasing'
  | 'decreasing'
  | 'specified'
  ) 'hue'
</pre></x>
Different color interpolation methods provide different advantages. For that reason, individual color procedures and functions (the host syntax) can establish their own color interpolation defaults, or provide a syntax for authors to explicitly choose the method that best fits their need.
The host syntax for a given interpolation procedure is the color syntax or function that instigates that interpolation. When selecting a color interpolation method:
-
If the host syntax defines what method to use use, use the specified method.
-
Otherwise, if all the colors involved are legacy colors, use
srgb
. -
Otherwise, use
oklab
.
Hue Interpolation Methods ¶
When interpolating between polar-angle hue channels, there are multiple ‘directions’ the interpolation could move, following different logical rules.
The hue interpolation methods below are defined in
CSS Color Level 4. Unless the type of hue interpolation is
the value specified
, both angles need to be constrained to [0, 360)
prior
to interpolation.
One way to do this is
n = ((n % 360) + 360) % 360
.
When no hue interpolation method is given, the default is shorter
.
Procedures ¶
Converting a Color ¶
Colors can be converted from one [color space][] to another. Algorithms for
color conversion are defined in the CSS Color Level 4
specification. Each algorithm takes a color origin-color
, and a string
target-space
, and returns a color output-color
.
The algorithms are:
For additional details, see the Sample code for color conversions.
Gamut Mapping ¶
Some color spaces describe limited color gamuts. If a color is ‘out of gamut’ for a particular space (most often because of conversion from a larger-gamut color-space), it can be useful to ‘map’ that color to the nearest available ‘in-gamut’ color. Gamut mapping is the process of finding an in-gamut color with the least objectionable change in visual appearance.
Gamut mapping in Sass follows the CSS gamut mapping algorithm.
This procedure accepts a color origin
in the color space origin color space
,
and a destination color space destination
. It returns the result of a
CSS gamut map procedure, which is a color in the destination
color
space.
This algorithm implements a relative colorimetric intent, and colors inside the destination gamut are unchanged.
Parsing Color Components ¶
This procedure accepts an input
parameter to parse, along with a space
parameter representing the [color space][] if known. It throws common parse
errors if necessary, and returns either null
(if the input
contains special
CSS values), or a list of parsed values. The return value is in the format
<color-space>? (<channel>+) / <alpha>
, where the color space is included in
the return value if it was not passed in initially.
This supports both the known color formats like
hsl()
andrgb()
, where the space is determined by the function, as well as the syntax ofcolor()
, where the space is included as one of the input arguments (and may be a user-defined space).
The procedure is:
-
If
input
is a special variable string, returnnull
. -
Let
include-space
be true ifspace
is undefined, and false otherwise. -
If
input
is a bracketed list, or a list with a separator other than ‘slash’ or ‘space’, throw an error. -
If
input
is a slash-separated list:-
If
input
doesn’t have exactly two elements, throw an error. -
Otherwise, let
components
be the first element andalpha
the second element ofinput
.
-
-
Otherwise:
-
Let
components
be an unbracketed space separated list of all except the last element ofinput
. -
If the last element of
input
is an unquoted string that contains/
:-
Let
split-last
be the result callingstring.split()
with the last element ofinput
as the string to split, and/
as the separator. -
If there are not two items in
split-last
, throw an error. -
If either item in
split-last
can be coerced to a number, replace the current value of the item with the resulting number value. -
Let
alpha
be the second element insplit-last
, and append the first element ofsplit-last
tocomponents
.
This solves for a legacy handling of
/
in Sass that would produce an unquoted string when the alpha value is a css function such asvar()
or when either value is the keywordnone
. -
-
Otherwise, if the last element of
input
has preserved its status as two slash-separated numbers:- Let
alpha
be the number after the slash, and append the number before the slash tocomponents
.
- Let
-
Otherwise, append the last element of
input
tocomponents
-
-
If
components
is undefined or an empty list, throw an error. -
If
components
is a special variable string:- Let
channels
be the value ofcomponents
.
- Let
-
Otherwise:
-
If
components
is not an unbracketed space-separated list, throw an error. -
If
space
is undefined, letspace
be the first element incomponents
, and letchannels
be an unbracketed space-separated list with the remaining elements fromcomponents
. -
Otherwise, let
channels
be the value ofcomponents
. -
If
space
is not a string, throw an error. -
Let
expected
be the number of channels inspace
ifspace
is a known color-space, and null otherwise. -
If
expected
is not null, andchannels
has more thanexpected
elements, throw an error. -
If any element of channels is not either a number, a special variable string, a special number string, or the keyword
none
, throw an error.
-
-
If
alpha
is undefined, letalpha
be1
. -
Otherwise, If
alpha
is not a special number string:-
If
alpha
is a number, setalpha
to the result of percent-convertingalpha
with a max of 1. -
Otherwise, if
alpha
is not the keywordnone
, throw an error.
-
-
If
space
orchannels
is a special variable string, or ifalpha
is a special number string, or ifspace
is not a known [color space][], returnnull
.Unknown color spaces are valid in CSS, but should not be treated as color objects for the sake of Sass manipulation.
-
If any element of
channels
is a special number string, returnnull
.Doing this late in the process allows us to throw any obvious syntax errors, even for colors that can’t be fully resolved on the server.
-
If
expected
is not null, and the length ofchannels
is not equal toexpected
, throw an error.Once special values have been handled, any colors remaining should have exactly the expected number of channels.
-
If
include-space
is true, letparsed
be an unbracketed space-separated list withspace
as the first element, andchannels
as the second. -
Otherwise, let
parsed
be the value ofchannels
. -
Return an unbracketed slash-separated list with
parsed
as the first element, andalpha
as the second.This results in valid CSS color-value output, while also grouping space, channels, and alpha as separate elements in nested lists. Alternately, we could allow
parsed
to be a single flat list, even when the color-space is included?
Normalizing Hue ¶
This process accepts a hue
angle, and boolean convert-none
arguments. It
returns the hue normalized to degrees when possible, and converting none
to
0
when requested. Otherwise it throws an error for invalid hue
.
-
If the value of
hue
isnone
:-
If
convert-none
istrue
, return0
. -
Otherwise, return
hue
without changes.
-
-
Return the result of converting
hue
todeg
allowing unitless.Normalizing the result into a half-open range of
[0,360)
might also be possible here, but is potentially a lossy transformation.
Interpolating Colors ¶
This procedure accepts two color arguments (color1
and color2
), an
optional [color interpolation method][] method
, and a percentage weight
for color1
in the mix. It returns a new color mix
that represents the
appropriate mix of input colors.
-
If either
color1
orcolor2
is not a color, throw an error. -
If
weight
is undefined, setweight
to50%
. -
Otherwise, if
weight
is not a percentage -
If
method
is undefined:- Let
interpolation-space
besrgb
ifcolor1
andcolor2
are both legacy colors, andoklab
otherwise.
- Let
-
Otherwise, if
method
is not a color interpolation method, throw an error. -
Otherwise:
-
Let
interpolation-space
be the [color space][] specified inmethod
. -
If
interpolation-space
is a PolarColorSpace, letinterpolation-arc
be the hue interpolation method specified inmethod
.
-
-
For each
color
ofcolor1
andcolor2
:-
Set
color
to the results of convertingcolor
intointerpolation-space
. -
If any
component
ofcolor
isnone
, setcomponent
to the value of the corresponding component in the other color.If both values are
none
, the interpolation result for that component will also benone
. -
Set
color
to the result of premultiplyingcolor
.
-
todo: finish this process
Premultiply Transparent Colors ¶
When the colors being interpolated are not fully opaque, they are transformed
into premultiplied color values. This process accepts a single color
and
updates the channel values if necessary, returning a new color with
premultiplied channels.
-
If the
color
has analpha
value of 1, returncolor
unchanged. -
Otherwise, for each
channel
incolor
:-
If either the
alpha
value, or thechannel
value isnone
, or thechannel
represents a polar-anglehue
, keep the original value ofchannel
. -
Otherwise, set
channel
to the result of multiplying thechannel
value by thealpha
value.
-
-
Return the resulting
color
with premultiplied channels.
The same process can be run in reverse, to un-premultiply the channels of a
given color
:
-
If the
color
has analpha
value of 1, returncolor
unchanged. -
Otherwise, for each
channel
incolor
:-
If either the
alpha
value, or thechannel
value is 0 ornone
, or thechannel
represents a polar-anglehue
, keep the original value ofchannel
. -
Otherwise, set
channel
to the result of dividing the premultipliedchannel
value by thealpha
value.
-
-
Return the resulting
color
with un-premultiplied channels.
New Color Module Functions ¶
These new functions are part of the built-in sass:color
module.
space()
¶
-
space($color)
-
If
$color
is not a color, throw an error. -
Return a quoted string with the name of
$color
s associated [color space][].
-
to-space()
¶
-
to-space($color, $space)
-
If
$color
is not a color, throw an error. -
Let
origin-space
be the result of callingspace($color)
. -
If
origin-space
equals-equals$space
, return$color
.This allows unknown spaces, as long as they match the origin space.
-
If
$space
is not a [color space][], throw an error. -
Return the result of converting the
origin-color
$color
to thetarget-space
$space
.
-
is-legacy()
¶
-
is-legacy($color)
-
If
$color
is not a color, throw an error. -
Return
true
if$color
is a legacy color, orfalse
otherwise.
-
is-powerless()
¶
-
is-powerless($color, $channel, $space)
-
If
$color
is not a valid color, throw an error. -
If
$space
is null:- Let
color
be the value ofcolor
, and letspace
be the result of callingspace($color)
.
- Let
-
Otherwise:
- Let
color
be the result of callingto-space($color, $space)
, and letspace
be the value of$space
.
- Let
-
If
$channel
is not the name of a channel in the color-spacespace
, throw an error. -
Return
true
if the channel$channel
is powerless incolor
, otherwise returnfalse
.
-
is-in-gamut()
¶
-
is-in-gamut($color, $space)
-
If
$color
is not a color, throw an error. -
Let
space
be the value of$space
if specified, or the result of callingspace($color)
otherwise. -
If
space
is not a valid [color space][], throw an error. -
Let
gamut
be the color gamut associated withspace
if an association is defined, or the value ofspace
otherwise. -
Let
color
be the result of callingto-space($color, space)
. -
For all bounded channels in
space
, if the associated channel value in$color
is outside the bounded range, returnfalse
. -
Otherwise, return
true
.
-
to-gamut()
¶
-
to-gamut($color, $space)
-
If
$color
is not a color, throw an error. -
Let
origin-space
be the result of callingspace($color)
otherwise. -
Let
target-space
be the value of$space
if specified, or the value oforigin-space
otherwise. -
If
target-space
is not a valid [color space][], throw an error. -
Return the result of gamut mapping with
$color
as theorigin
color,origin-space
as theorigin color space
, andtarget-space
as thedestination
color space.
-
channel()
¶
-
channel($color, $channel, $space)
-
If
$space
is null:- Let
space
be the result of callingspace($color)
, and letcolor
be the value of$color
.
- Let
-
Otherwise:
- Let
color
be the result of callingto-space($color, $space)
, and letspace
be the value of$space
.
- Let
-
If
space
is a known [color space][], letchannels
be a map of channel names defined forspace
, and their corresponding values incolor
, or a map with 1-indexed number keys and their corresponding values incolor
otherwise. -
Let
value
be the result of callingmap.get(channels, $channel)
. -
If
value
isnull
, throw an error. -
Otherwise, return
value
.
-
New Global Functions ¶
These new CSS functions are provided globally.
hwb()
¶
-
hwb($channels)
-
Let
components
be the result of parsing$channels
in anhwb
space. -
If
components
is null, return a plain CSS function string with the name"hwb"
and the argument$channels
. -
Let
channels
be the first element andalpha
the second element ofcomponents
. -
Let
hue
,whiteness
, andblackness
be the three elements ofchannels
. -
Set
hue
to the result of normalizinghue
withconvert-none
set tofalse
. -
For each
channel
ofwhiteness
andblackness
, ifchannel
is notnone
:-
If
channel
doesn’t have unit%
, throw an error. -
Set
channel
to the result of clampingchannel
between0%
and100%
.Clamping happens before relative scaling
-
-
If
whiteness + blackness > 100%
with values ofnone
treated as0
:-
If
whiteness
is not none, setwhiteness
towhiteness / (whiteness + blackness) * 100%
. -
If
blackness
is not none, setblackness
toblackness / (whiteness + blackness) * 100%
.
-
-
Return a legacy color in the
hwb
space, with the givenhue
,whiteness
, andblackness
channels, andalpha
value.
-
lab()
¶
-
lab($channels)
-
Let
components
be the result of parsing$channels
in anlab
space. -
If
components
is null, return a plain CSS function string with the name"lab"
and the argument$channels
. -
Let
channels
be the first element andalpha
the second element ofcomponents
. -
Let
lightness
,a
, andb
be the three elements ofchannels
. -
If any of
lightness
,a
, orb
is a number with a unit other than%
, throw an error. -
If
lightness
is a number less than0
, setlightness
to0%
. -
Return a color in the
lab
[color space][], with the givenlightness
,a
, andb
channels, andalpha
value.
-
lch()
¶
-
lch($channels)
-
Let
components
be the result of parsing$channels
in anlch
space. -
If
components
is null, return a plain CSS function string with the name"lab"
and the argument$channels
. -
Let
channels
be the first element andalpha
the second element ofcomponents
. -
Let
lightness
,chroma
, andhue
be the three elements ofchannels
. -
If
chroma
orlightness
is a number with a unit other than%
, throw an error. -
For each
channel
inchroma
andlightness
, ifchannel
is a number less than0
, setchannel
to0%
. -
Set
hue
to the result of normalizinghue
withconvert-none
set tofalse
. -
Return a color in the
lch
[color space][], with the givenlightness
,chroma
, andhue
channels, andalpha
value.
-
oklab()
¶
-
oklab($channels)
-
Let
components
be the result of parsing$channels
in anoklab
space. -
If
components
is null, return a plain CSS function string with the name"lab"
and the argument$channels
. -
Let
channels
be the first element andalpha
the second element ofcomponents
. -
Let
lightness
,a
, andb
be the three elements ofchannels
. -
If any of
lightness
,a
, orb
is a number with a unit other than%
, throw an error. -
If
lightness
is a number less than0
, setlightness
to0%
. -
Return a color in the
oklab
[color space][], with the givenlightness
,a
, andb
channels, andalpha
value.
-
oklch()
¶
-
oklch($channels)
-
Let
components
be the result of parsing$channels
in anoklch
space. -
If
components
is null, return a plain CSS function string with the name"lab"
and the argument$channels
. -
Let
channels
be the first element andalpha
the second element ofcomponents
. -
Let
lightness
,chroma
, andhue
be the three elements ofchannels
. -
If
chroma
orlightness
is a number with a unit other than%
, throw an error. -
For each
channel
inchroma
andlightness
, ifchannel
is a number less than0
, setchannel
to0%
. -
Set
hue
to the result of normalizinghue
withconvert-none
set tofalse
. -
Return a color in the
oklch
[color space][], with the givenlightness
,chroma
, andhue
channels, andalpha
value.
-
color()
¶
-
color($description)
-
Let
components
be the result of parsing$description
with undefined space. -
If
components
is null, return a plain CSS function string with the name"color"
and the argument$description
. -
Let
color
be the first element andalpha
the second element ofcomponents
. -
Let
space
be the first element andchannels
the second element ofcolor
. -
If
space
is not a predefined color space, throw an error,.Custom spaces have already been output as CSS functions.
-
For each
channel
element ofchannels
, ifchannel
is a number:-
If
channel
has a unit other than%
, throw an error. -
If
channel
is a percentage, setchannel
to the result ofchannel / 100%
. -
If
space
is a predefined RGB space, setchannel
to the result of clampingchannel
between0
and1
.
-
-
Return a color in the
space
[color space][], with the givenchannels
andalpha
value.
-
Modified Color Module Functions ¶
mix()
¶
mix($color1, $color2,
$weight: 50%, $method: null)
-
If either
$color1
or$color2
is not a color, throw an error. -
If
$weight
is not a percentage between0%
and100%
, throw an error. -
If
$space
is not a [color space][] ornull
, throw an error. -
Let
space
be the value of$space
if$space
is notnull
, and the result of callingspace($color1)
otherwise. -
Let
color1
be the result of calling$color