CSS Color Module Level 4
CSS Color Module Level 4
W3C First Public Working Draft,
05 July 2016
This version:
Latest version:
Editor's Draft:
Feedback:
www-style@w3.org
with subject line “
[css-color]
… message topic …
” (
archives
Issue Tracking:
Inline In Spec
Editors:
Tab Atkins Jr.
Google
Chris Lilley
W3C
Former Editor:
L. David Baron
Mozilla Corporation
W3C
MIT
ERCIM
Keio
Beihang
). W3C
liability
trademark
and
document use
rules apply.
Abstract
This specification describes CSS

values and properties for foreground color and group opacity.
CSS
is a language for describing the rendering of structured documents
(such as HTML and XML)
on screen, on paper, in speech, etc.
Status of this document
This section describes the status of this document at the time of
its publication. Other documents may supersede this document. A list of
current W3C publications and the latest revision of this technical report
can be found in the
W3C technical reports
index at http://www.w3.org/TR/.
This document is a
First Public Working Draft
Publication as a First Public Working Draft does not imply endorsement by the W3C
Membership. This is a draft document and may be updated, replaced or
obsoleted by other documents at any time. It is inappropriate to cite this
document as other than work in progress.
The (
archived
) public
mailing list
www-style@w3.org
(see
instructions
) is preferred
for discussion of this specification. When sending e-mail, please put the
text “css-color” in the subject, preferably like this:
“[css-color]
…summary of comment…
This document was produced by the
CSS Working Group
(part of
the
Style Activity
).
This document was produced by a group operating under the
5 February
2004 W3C Patent Policy
. W3C maintains a
public list of any patent disclosures
made in
connection with the deliverables of the group; that page also includes
instructions for disclosing a patent. An individual who has actual
knowledge of a patent which the individual believes contains
Essential
Claim(s)
must disclose the information in accordance with
section
6 of the W3C Patent Policy
This document is governed by the
1 September 2015 W3C Process Document
1.
Introduction
This section is not normative.
This module describes CSS properties which allow authors to specify the foreground color and opacity of the text content of an element.
This module also describes in detail the CSS

value type.
It not only defines the color-related properties and values that
already exist in
CSS1
and
CSS2
, but also defines new
properties and values.
2.
Foreground Color: the
color
property
Name:
color
Value:

Initial:
UA-defined, see prose
Applies to:
all elements
Inherited:
yes
Percentages:
N/A
Media:
visual
Computed value:
an RGBA color
Animation type:
discrete
This property describes the foreground fill color of an element’s text content.
In addition, it provides the value that
currentcolor
resolves to.
If the
currentcolor
keyword is set on the
color
property itself, it is treated as
color: inherit
The initial value of this property is
black
There are several different ways to syntactically specify a given color.
For example, to specify lime green:
em
color
lime
/* color keyword */
em
color
rgb
25
);
/* RGB range 0-255 */
em
color
rgb
.0,100.0,0.0); } /* RGB range 0%-100% */

The

type is defined in a later section.
3.
Representing sRGB Colors: the

type
CSS colors in the sRGB color space are represented by a triplet of values—
red, green, and blue—
identifying a point in the sRGB color space
[SRGB]
This is an internationally-recognized, device-independent color space,
and so is useful for specifying colors that will be displayed on a computer screen,
but is also useful for specifying colors on other types of devices, like printers.
(See
[COLORIMETRY]
.)
Additionally, every color is accompanied by an alpha component,
indicating how transparent it is,
and thus how much of the backdrop one can see behind the color.
The components are also sometimes called "channels".
Each channel has a minimum and maximum value,
and can take any value between those two.
While all colors share an underlying storage format,
CSS contains several syntaxes for
specifying

values.
Some directly specify the sRGB color,
such as the
rgb()
and
rgba()
functions
and the hex notation.
Others are more human-friendly to write and understand,
and are converted to an sRGB color by CSS,
such as the
hsl()
and
hsla()
functions,
or the long list of named colors defined by CSS.
In total, the definition of

is:











currentcolor

Some operations work differently on
achromatic
colors.
An
achromatic
color is a shade of gray:
in the RGB colorspace,
a color is
achromatic
if the red, green, and blue channels are all the same value;
in the HSL colorspace,
a color is
achromatic
if the saturation is
0%
in the HWB colorspace,
a color is
achromatic
if the sum of the whiteness and blackness is at least
100%
3.1.
Notes On Using Colors
Although colors can add significant amounts of information to
documents and make them more readable, color by itself should not be the sole
means to convey important information. Please consider the
W3C Web Content Accessibility Guidelines
[WCAG20]
when including color in your documents.
1.4.1 Use of Color:
Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element
3.2.
Colors in sRGB
Colors specified in CSS, HTML, and untagged images are in the sRGB color space (
[SRGB]
).
This is not yet reliably implemented across implementations, though it has been shown to be implementable. Implementing it compatibly may require notifying plugins to treat untagged colors in the same way to avoid issues with colors not matching each other within a page.
An
untagged image
is an image that is not explicitly assigned a color profile, as defined by the image format.
Note that this rule does not apply to videos, since untagged video should be presumed to be in CCIR 601.
Really? Isn’t HD video in Rec.709? Shouldn’t video be consistent with images?
Or do implementations really do this differently?
4.
RGB Colors
There are several methods of directly specifying a color in terms of its RGBA channels.
4.1.
The RGB functions:
rgb()
and
rgba()
The
rgb()
function defines an RGB color by specifying the red, green, and blue channels directly.
Its syntax is:
rgb()
= rgb(

#{3}
rgba()
= rgba(

#{3}







The three

s specify the red, green, and blue channels of the color, respectively.
0%
represents the minimum value for that color channel in the sRGB gamut,
and
100%
represents the maximum value.

is equivalent to a

but with a different range:
again represents the minimum value for the color channel,
but
255
represents the maximum.
These values come from the fact that many graphics engines store the color channels internally as a single byte,
which can hold integers between 0 and 255.
However, the CSS syntax allows full

s,
not just

s,
for authoring convenience.
Some devices can output colors technically outside of the sRGB gamut,
represented by channels with values less than
0%
or greater than
100%
For this reason, values outside of the 0%-100% range are allowed,
but are clamped to the device’s gamut.)
The transfer function is undefined outside the range 0% to 100%.
The final argument, the

, specifies the alpha of the color.
If given as a

, the useful range of the value is
(representing a fully transparent color)
to
(representing a fully opaque color).
If given as a

0%
represents a fully transparent color,
while
100%
represents a fully opaque color.
Values outside these ranges are not invalid,
but are clamped to the ranges defined here at computed-value time.
If omitted, it defaults to
100%
4.2.
The RGB hexadecimal notations:
#RRGGBB
The CSS
hex color
notation allows a color to be specified by giving the channels as hexadecimal numbers,
which is similar to how colors are often written directly in computer code.
It’s also shorter than writing the same color out in
rgb()
notation.
The syntax of a

is a

token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
In other words, a hex color is written as a hash character, "#",
followed by some number of digits 0-9 or letters a-f
(the case of the letters doesn’t matter -
#00ff00
is identical to
#00FF00
).
The number of hex digits given determines how to decode the hex notation into an RGB color:
6 digits
The first pair of digits, interpreted as a hexadecimal number,
specifies the red channel of the color,
where
00
represents the minimum value
and
ff
(255 in decimal) represents the maximum.
The next pair of digits, interpreted in the same way,
specifies the green channel,
and the last pair specifies the blue.
The alpha channel of the color is fully opaque.
In other words,
#00ff00
represents the same color as
rgb(0, 255, 0)
(a lime green).
8 digits
The first 6 digits are interpreted identically to the 6-digit notation.
The last pair of digits, interpreted as a hexadecimal number,
specifies the alpha channel of the color,
where
00
represents a fully transparent color
and
ff
represent a fully opaque color.
In other words,
#0000ffcc
represents the same color as
rgba(0, 0, 100%, 80%)
(a slightly-transparent blue).
3 digits
This is a shorter variant of the 6-digit notation.
The first digit, interpreted as a hexadecimal number,
specifies the red channel of the color,
where
represents the minimum value
and
represents the maximum.
The next two digits represent the green and blue channels, respectively,
in the same way.
The alpha channel of the color is fully opaque.
This syntax is often explained by saying that it’s identical to a 6-digit notation obtained by "duplicating" all of the digits.
For example, the notation
#123
specifies the same color as the notation
#112233
This method of specifying a color has lower "resolution" than the 6-digit notation;
there are only 4096 possible colors expressible in the 3-digit hex syntax,
as opposed to approximately 17 million in 6-digit hex syntax.
4 digits
This is a shorter variant of the 8-digit notation,
"expanded" in the same way as the 3-digit notation is.
The first digit, interpreted as a hexadecimal number,
specifies the red channel of the color,
where
represents the minimum value
and
represents the maximum.
The next three digits represent the green, blue, and alpha channels, respectively.
5.
Named Colors
In addition to the various numeric syntaxes for

s,
CSS defines a large set of
named colors
that can be used instead,
so that common colors can be written and read more easily.

is written as an

accepted anywhere a

is.
As usual for CSS-defined

s,
all of these keywords are case-insensitive.
16 of CSS’s named colors come from HTML originally:
aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, white, and yellow.
Most of the rest
come from one version of the X11 color system,
used in Unix-derived systems to specify colors for the console.
(Two special color values,
transparent
and
currentcolor
are specially defined in their own sections.)
Note: The history of the X11 color system is interesting,
and was excellently summarized by
Alex Sexton in his talk “Peachpuffs and Lemonchiffons”
The following table defines all of the opaque named colors,
by giving equivalent numeric specifications in the other color syntaxes.
Named
Numeric
Color name
Hex rgb
Decimal
aliceblue
#f0f8ff
240,248,255
antiquewhite
#faebd7
250,235,215
aqua
#00ffff
0,255,255
aquamarine
#7fffd4
127,255,212
azure
#f0ffff
240,255,255
beige
#f5f5dc
245,245,220
bisque
#ffe4c4
255,228,196
black
#000000
0,0,0
blanchedalmond
#ffebcd
255,235,205
blue
#0000ff
0,0,255
blueviolet
#8a2be2
138,43,226
brown
#a52a2a
165,42,42
burlywood
#deb887
222,184,135
cadetblue
#5f9ea0
95,158,160
chartreuse
#7fff00
127,255,0
chocolate
#d2691e
210,105,30
coral
#ff7f50
255,127,80
cornflowerblue
#6495ed
100,149,237
cornsilk
#fff8dc
255,248,220
crimson
#dc143c
220,20,60
cyan
#00ffff
0,255,255
darkblue
#00008b
0,0,139
darkcyan
#008b8b
0,139,139
darkgoldenrod
#b8860b
184,134,11
darkgray
#a9a9a9
169,169,169
darkgreen
#006400
0,100,0
darkgrey
#a9a9a9
169,169,169
darkkhaki
#bdb76b
189,183,107
darkmagenta
#8b008b
139,0,139
darkolivegreen
#556b2f
85,107,47
darkorange
#ff8c00
255,140,0
darkorchid
#9932cc
153,50,204
darkred
#8b0000
139,0,0
darksalmon
#e9967a
233,150,122
darkseagreen
#8fbc8f
143,188,143
darkslateblue
#483d8b
72,61,139
darkslategray
#2f4f4f
47,79,79
darkslategrey
#2f4f4f
47,79,79
darkturquoise
#00ced1
0,206,209
darkviolet
#9400d3
148,0,211
deeppink
#ff1493
255,20,147
deepskyblue
#00bfff
0,191,255
dimgray
#696969
105,105,105
dimgrey
#696969
105,105,105
dodgerblue
#1e90ff
30,144,255
firebrick
#b22222
178,34,34
floralwhite
#fffaf0
255,250,240
forestgreen
#228b22
34,139,34
fuchsia
#ff00ff
255,0,255
gainsboro
#dcdcdc
220,220,220
ghostwhite
#f8f8ff
248,248,255
gold
#ffd700
255,215,0
goldenrod
#daa520
218,165,32
gray
#808080
128,128,128
green
#008000
0,128,0
greenyellow
#adff2f
173,255,47
grey
#808080
128,128,128
honeydew
#f0fff0
240,255,240
hotpink
#ff69b4
255,105,180
indianred
#cd5c5c
205,92,92
indigo
#4b0082
75,0,130
ivory
#fffff0
255,255,240
khaki
#f0e68c
240,230,140
lavender
#e6e6fa
230,230,250
lavenderblush
#fff0f5
255,240,245
lawngreen
#7cfc00
124,252,0
lemonchiffon
#fffacd
255,250,205
lightblue
#add8e6
173,216,230
lightcoral
#f08080
240,128,128
lightcyan
#e0ffff
224,255,255
lightgoldenrodyellow
#fafad2
250,250,210
lightgray
#d3d3d3
211,211,211
lightgreen
#90ee90
144,238,144
lightgrey
#d3d3d3
211,211,211
lightpink
#ffb6c1
255,182,193
lightsalmon
#ffa07a
255,160,122
lightseagreen
#20b2aa
32,178,170
lightskyblue
#87cefa
135,206,250
lightslategray
#778899
119,136,153
lightslategrey
#778899
119,136,153
lightsteelblue
#b0c4de
176,196,222
lightyellow
#ffffe0
255,255,224
lime
#00ff00
0,255,0
limegreen
#32cd32
50,205,50
linen
#faf0e6
250,240,230
magenta
#ff00ff
255,0,255
maroon
#800000
128,0,0
mediumaquamarine
#66cdaa
102,205,170
mediumblue
#0000cd
0,0,205
mediumorchid
#ba55d3
186,85,211
mediumpurple
#9370db
147,112,219
mediumseagreen
#3cb371
60,179,113
mediumslateblue
#7b68ee
123,104,238
mediumspringgreen
#00fa9a
0,250,154
mediumturquoise
#48d1cc
72,209,204
mediumvioletred
#c71585
199,21,133
midnightblue
#191970
25,25,112
mintcream
#f5fffa
245,255,250
mistyrose
#ffe4e1
255,228,225
moccasin
#ffe4b5
255,228,181
navajowhite
#ffdead
255,222,173
navy
#000080
0,0,128
oldlace
#fdf5e6
253,245,230
olive
#808000
128,128,0
olivedrab
#6b8e23
107,142,35
orange
#ffa500
255,165,0
orangered
#ff4500
255,69,0
orchid
#da70d6
218,112,214
palegoldenrod
#eee8aa
238,232,170
palegreen
#98fb98
152,251,152
paleturquoise
#afeeee
175,238,238
palevioletred
#db7093
219,112,147
papayawhip
#ffefd5
255,239,213
peachpuff
#ffdab9
255,218,185
peru
#cd853f
205,133,63
pink
#ffc0cb
255,192,203
plum
#dda0dd
221,160,221
powderblue
#b0e0e6
176,224,230
purple
#800080
128,0,128
rebeccapurple
#663399
102,51,153
red
#ff0000
255,0,0
rosybrown
#bc8f8f
188,143,143
royalblue
#4169e1
65,105,225
saddlebrown
#8b4513
139,69,19
salmon
#fa8072
250,128,114
sandybrown
#f4a460
244,164,96
seagreen
#2e8b57
46,139,87
seashell
#fff5ee
255,245,238
sienna
#a0522d
160,82,45
silver
#c0c0c0
192,192,192
skyblue
#87ceeb
135,206,235
slateblue
#6a5acd
106,90,205
slategray
#708090
112,128,144
slategrey
#708090
112,128,144
snow
#fffafa
255,250,250
springgreen
#00ff7f
0,255,127
steelblue
#4682b4
70,130,180
tan
#d2b48c
210,180,140
teal
#008080
0,128,128
thistle
#d8bfd8
216,191,216
tomato
#ff6347
255,99,71
turquoise
#40e0d0
64,224,208
violet
#ee82ee
238,130,238
wheat
#f5deb3
245,222,179
white
#ffffff
255,255,255
whitesmoke
#f5f5f5
245,245,245
yellow
#ffff00
255,255,0
yellowgreen
#9acd32
154,205,50
Note: this list of colors and their definitions is a superset of the list of
named colors defined by SVG 1.1
For historical reasons, this is also referred to as the X11 color set.
5.1.
The
transparent
keyword
The keyword
transparent
specifies a transparent black color;
that is, a color with its red, green, and blue channels all set to the minimum value
and its alpha channel set to full transparency,
equivalent to
rgba(0, 0, 0, 0)
It is a type of

5.2.
The
currentcolor
keyword
The keyword
currentcolor
takes its value from the value of the
color
property on the same element.
This happens at
used-value time
which means that if the value is inherited,
it’s inherited as
currentcolor
not as the value of the
color
property,
so descendants will use their
own
color
property to resolve it.
If
currentcolor
is used as the value of the
color
property,
it instead takes its value from the inherited value of the
color
property.
Here’s a simple example showing how to use the
currentcolor
keyword:
.foo
color
red
background-color
currentcolor
This is equivalent to writing:
.foo
color
red
background-color
red
For example, the
text-emphasis-color
property
[CSS3-TEXT-DECOR]
whose initial value is
currentcolor
by default matches the text color
even as the
color
property changes across elements.
><
em
Some
strong
really
strong
emphasized text.
em
style
color
black
em
text
emphasis
dot
strong
color
red
style
In the above example, the emphasis marks would be black over the text "Some" and "emphasized text",
but red over the text "really".
Note: Multi-word keywords in CSS usually separate their component words with hyphens.
currentcolor
doesn’t, because it was originally introduced in SVG
as a special attribute value spelled "currentColor",
rather than a CSS value.
Only later did CSS pick it up,
at which point the capitalization stopped mattering,
as CSS keywords are case-insensitive.
6.
HSL Colors:
hsl()
and
hsla()
functions
The RGB system for specifying colors,
while convenient for machines and graphic libraries,
is often regarded as very difficult for humans to gain an intuitive grasp on.
It’s not easy to tell, for example,
how to alter an RGB color to produce a lighter variant of the same hue.
There are several other color schemes possible.
One such is the HSL color scheme,
which is much more intuitive to use,
but still maps easily back to RGB colors.
HSL colors are specified as a triplet of hue, saturation, and lightness.
The syntax of the
hsl()
function is:
hsl()
= hsl(



hsla()
= hsla(







The first argument specifies the hue.
Hue is represented as an angle of the color circle
(the rainbow, twisted around into a circle).
The angle
0deg
represents red
(as does
360deg
720deg
, etc.),
and the rest of the hues are spread around the circle,
so
120deg
represents green,
240deg
represents blue, etc.
Because this value is so often given in degrees,
the argument can also be given as a number,
which is interpreted as a number of degrees.
The next two arguments are the saturation and lightness, respectively.
For saturation,
100%
is a fully-saturated, bright color,
and
0%
is a fully-unsaturated gray.
For lightness,
50%
represents the "normal" color,
while
100%
is white and
0%
is black.
If the saturation or lightness is less than
0%
or the lightness is greater than
100%
they are clipped to those values before being converted to an RGB color.
Some output devices may support saturations greater than
100%
just as they support RGB values greater than
100%
If the saturation exceeds the output device’s gamut,
it must be clipped to that device’s gamut before being converted to an RGB color.
This clipping
should
preserve the hue of the color
(that is, it’s shouldn’t be the same thing as clipping an RGB component to the device’s gamut),
but this specification does not define how to do so.
The final argument specifies the alpha channel of the color.
It’s interpreted identically to the fourth argument of the
rgba()
function.
If omitted, it defaults to
100%
For example, an ordinary red,
the same color you would see from the keyword
red
or the hex notation
#f00
is represented in HSL as
hsl(0, 100%, 50%)
The advantage of HSL over RGB is that it is far more intuitive:
one can guess at the colors they want,
and then tweak.
It is also easier to create sets of matching colors
(by keeping the hue the same and varying the saturation and lightness).
For example, the following colors can all be generated off of the basic "green" hue,
just by varying the other two arguments:
hsl(120, 100%, 50%)
lime green
hsl(120, 100%, 25%)
dark green
hsl(120, 100%, 75%)
light green
hsl(120, 75%, 85%)
pastel green
6.1.
Converting HSL colors to RGB colors
Converting an HSL color to RGB is straightforward mathematically.
Here’s a simple implementation of the conversion algorithm in JavaScript.
For simplicity, this algorithm assumes that the hue has been normalized to
a number in the half-open range [0, 6),
and the saturation and lightness have been normalized to the range [0, 1].
It returns an array of three numbers
representing the red, green, and blue channels of the colors,
normalized to the range [0, 1].
function
hslToRgb
hue
sat
light
if
light
<=
var
t2
light
sat
);
else
var
t2
light
sat
light
sat
);
var
t1
light
t2
var
hueToRgb
t1
t2
hue
);
var
hueToRgb
t1
t2
hue
);
var
hueToRgb
t1
t2
hue
);
return
];
function
hueToRgb
t1
t2
hue
if
hue
hue
+=
if
hue
>=
hue
-=
if
hue
return
t2
t1
hue
t1
else
if
hue
return
t2
else
if
hue
return
t2
t1
hue
t1
else
return
t1
6.2.
Examples of HSL colors
The tables below illustrate a wide range of possible HSL colors.
Each table represents one hue,
selected at 30° intervals,
to illustrate the common "core" hues:
red,
yellow,
green,
cyan,
blue,
magenta,
and the six intermediary colors between these.
In each table, the X axis represents the saturation
while the Y axis represents the lightness.
0° Reds
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
30° Red-Yellows (=Oranges)
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
60° Yellows
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
90° Yellow-Greens
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
120° Greens
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
150° Green-Cyans
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
180° Cyans
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
210° Cyan-Blues
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
240° Blues
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
270° Blue-Magentas
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
300° Magentas
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
330° Magenta-Reds
Saturation
100%
75%
50%
25%
0%
100%
88%
75%
63%
50%
38%
25%
13%
0%
7.
HWB Colors:
hwb()
function
HWB (short for Hue-Whiteness-Blackness) is another method of specifying colors,
similar to HSL, but often even easier for humans to work with.
It describes colors with a starting hue,
then a degree of whiteness and blackness to mix into that base hue.
Many color-pickers are based on the HWB color system,
due to its intuitiveness.
This is a screenshot of Chrome’s color picker,
shown when a user activates an
input
type
"color"
The outer wheel is used to select the hue,
then the relative amounts of white and black are selected by clicking on the inner triangle.
The syntax of the
hwb()
function is:
hwb()
= hwb(




The first argument specifies the hue,
and is interpreted identically to
hsl()
The second argument specifies the amount of white to mix in,
as a percentage from
0%
(no whiteness) to
100%
(full whiteness).
Similarly, the third argument specifies the amount of black to mix in,
also from
0%
(no blackness) to
100%
(full blackness).
Values outside of these ranges make the function invalid.
If the sum of these two arguments is greater than 100%,
then at computed-value time they are normalized to add up to 100%,
with the same relative ratio.
The fourth argument specifies the alpha channel of the color.
It’s interpreted identically to the fourth argument of the
rgba()
function.
If omitted, it defaults to
100%
The resulting color can be thought of conceptually as a mixture of paint in the chosen hue,
white paint, and black paint,
with the relative amounts of each determined by the percentages.
If white+black is equal to
100%
(after normalization),
it defines an
achromatic
color,
or some shade of gray,
without any hint of the chosen hue.
7.1.
Converting HWB colors to RGB colors
Converting an HWB color to RGB is straightforward,
and related to how one converts HSL to RGB.
The following Javascript implementation of the algorithm assumes that the white and black components have already been normalized,
so their sum is no larger than 100%,
and have been converted into numbers in the range [0,1].
function
hwbToRgb
hue
white
black
var
rgb
hslToRgb
hue
);
for
var
++
rgb
*=
white
black
);
rgb
+=
white
return
rgb
7.2.
Examples of HWB Colors
0° Reds
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
30° Red-Yellows (Oranges)
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
60° Yellows
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
90° Yellow-Greens
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
120° Greens
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
150° Green-Cyans
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
180° Cyans
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
210° Cyan-Blues
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
240° Blues
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
270° Blue-Magentas
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
300° Magentas
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
330° Magenta-Reds
0%
20%
40%
60%
80%
100%
0%
20%
40%
60%
80%
100%
8.
Device-independent Colors: Lab and LCH
Physical measurements of a color are typically expressed in a color
space created in 1976 by the
CIE
, Lab. Color conversions from one device
to another also use Lab as an intermediate step. Derived from
human vision experiments, Lab represents the entire range of
color that humans can see.
Lab is a rectangular coordinate system with a central Lightness axis.
L=0 is deep black (no light at all) while L=100 is white (D50 white,
a standardized daylight spectrum with a color
temperature of 5000K). Usefully, L=50 is mid gray, by design: the
Lab color space is intended to be
perceptually uniform
The a and b axes convey hue; positive values along the a axis are red
while negative values are the complementary color, green. Similarly
positive values along the b axis are yellow and negative are the
complementary blue/violet. Desaturated colors have small values
of a and b and are close to the L axis; saturated colors lie far from
the L axis.
D50 is also the whitepoint used for the profile connection space in
ICC color interconversion, the values used in image editors which offer
Lab editing, and the value used by physical measurement devices such as
spectrometers, when they report measured colors in Lab. Conversion from
colors specified using other white points is called a chromatic adaptation
transform, which models the changes in the human visual system as we adapt
to a new lighting condition. The Bradford algorithm is the industry standard
chromatic adaptation transform, and is easy to calculate as it is a
simple matrix multiplication.
In Lab if two colors have the same L value, they appear
to have the same visual lightness – regardless of how different
their hues are. This is different from HSL, where for example blue (#00F)
and yellow (#FF0) have the same HSL lightness despite yellow being obviously
far lighter than blue.
LCH has the same L axis as Lab, but uses polar coordinates C (chroma)
and H (hue). C is the geometric distance from the L axis and H
is the angle, in degrees, from the positive a axis.
The Lightness axis in Lab should not be confused with the L axis in HSL.
For example, in HSL, the sRGB colors blue (#00F) and yellow (#FF0)
have the same value of L even though visually, blue is much darker. In
Lab, if two colors have the same measured L value, they have
identical visual lightness. HSL and related polar RGB models were
developed to give similar usability benefits for RGB that LCH gave
to Lab.
8.1.
Specifying Lab and LCH: the lab() and lch() functional notations
CSS allows colors to be directly expressed in Lab and LCH.
lab()
= lab(




The first argument specifies the CIE Lightness, the second argument is a and the third is b.
L is constrained to the range [0, 100] while a and b are signed values and
theoretically unbounded (but in practice do not exceed ±160).
There is an optional fourth alpha value, separated by a comma.
lch()
= lch(




The first argument specifies the CIE Lightness, the second argument is C and the third is H.
L is constrained to the range [0, 100]. C is an unsigned number, theoretically unbounded
(but in practice does not exceed 230).
H is constrained to the range [0, 360).
There is an optional fourth alpha value, separated by a comma.
Need to define handling for out of range numbers.
Clip L, wrap H? Have also seen L up to 400, specifically
for high dynamic range situations.
Need to decide what, if anything, to do
for high dynamic range on luminance.
8.2.
Converting sRGB colors to Lab colors
Conversion from sRGB to Lab requires several steps, although in practice all
but the first step are linear calculations and can be combined.
Convert from sRGB to linear-light sRGB (undo gamma correction)
Convert from linear sRGB to CIE XYZ
Convert from a D65 whitepoint (used by sRGB) to the D50 whitepoint used
in Lab, with the Bradford transform
Convert D50-adapted XYZ to Lab
There is sample JavaScript code for this conversion in
Sample
code for color conversions
section.
8.3.
Converting Lab colors to sRGB colors
Conversion from Lab to sRGB also requires multiple steps, and again in practice all
but the last step are linear calculations and can be combined.
Convert Lab to (D50-adapted) XYZ
Convert from a D50 whitepoint (used by Lab) to the D65 whitepoint used
in sRGB, with the Bradford transform
Convert from (D65-adapted) CIE XYZ to linear sRGB
Convert from linear-light sRGB to sRGB (do gamma correction)
8.4.
Converting Lab colors to LCH colors
Conversion to LCH is trivial:
H = atan2(b, a)
C = sqrt(a^2 + b^2)
L is the same
8.5.
Converting LCH colors to Lab colors
Conversion to Lab is trivial:
a = C cos(H)
b = C sin(H)
L is the same
9.
Specifying Grays: the
gray()
functional notation
As decided at San Francisco, this syntax is an alias to Lab with a=b=0.
Grays are fully desaturated colors. The
gray()
functional notation simplifies
specifying this common set of colors, so that only a single numerical parameter
is required, and so that gray(50%) is a visual mid-gray (perceptually equidistant
between black and white).
gray()
= gray(


The first argument specifies the shade of gray, equal to the CIE Lightness,
while the second optional argument specifies the alpha channel of the gray.
9.1.
Converting gray colors to sRGB colors
Conversion from gray to sRGB requires multiple steps; in practice all
but the last step are linear calculations and can be combined.
Convert to Lab by setting L to the gray value, a and b to 0
Convert Lab to XYZ
Adapt from D50 to D65 (Bradford transform)
Convert from (D65-adapted) CIE XYZ to linear sRGB
Convert from linear-light sRGB to sRGB (do gamma correction)
10.
Profiled, Device-dependent Colors
When the measured physical characteristics (such as the chromaticities of the
primary colors it uses, or the colors produced in response to a given set of inputs)
of a color space or a color-producing device are known, it is said to be
characterised
This characterization information is stored in a
profile
. The most common type of
color profile is defined by the International Color Consortium (ICC)
[ICC]
If in addition adjustments have
been made so that a device meets calibration targets such as white point, neutrality of greys,
predictability and consistency of tone response, then it is said to be
calibrated
CSS allows colors to be specified by reference to a color profile. This could be for example a
calibrated CMYK printer, or an RGB colorspace (such as ProPhoto ,
widely used by
photographers), or any other color or monochrome output defice which has been characterized.
In addition, for conveninnce, CSS provides two predefined RGB color spaces - DCI P3
[DCI-P3]
which is a wide gamut space typical of current wide-gamut monitors, and
Rec.2020 [
[Rec.2020]
which is a ultra-wide
gamut space capable of representing almost all visible real-world colors. Both are broadcast industry standards.
This example specifies four profiled colors: for a standard CMYK press, for a wide-gamut
seven-ink printer, for ProPhoto RGB, and for the P3 standard RGB space.
color(swopc, 0 206 190 77);
color(indigo, 24 160 86 42 0 18 31);
color(prophoto, 233 150 122);
color(P3, 97 253 36);
All but the predefined colorpace example also need a matching
profile
at-rule somewhere
in the stylesheet, to connect the name with the profile data.
@color-profile swopc {
src: url('http://example.org/swop-coated.icc'');}
@color-profile indigo {
src: url('http://example.org/indigo-seven.icc'');}
profile prophoto {
src: url('http://example.org/prophoto.icc'');}
color() fallback should be like font list fallback, as decided at San Francisco. Recursive?
10.1.
Specifying profiled colors: the
color()
function
The color function takes an indentifier as the first parameter, followed by either as many
numerical parameters as are needed (three for an RGB colorspace, four for CMYK,
one for greyscale, and so on) or a quoted string (for named color profiles).
An optional, comma-separated alpha value is also supported.
The identifier is either one of the predefined spaces
p3
or
rec2020
) or the name of a profile. An optional fallback may be specified
(an sRGB color, or indeed another color() function).
Decided at San Francisco to add a larger set of common predefined spaceslike AdobeRGB, ProPhoto RGB, and so on. Also coated and uncoated swop, etc, etc.
color()
= color(



] [


If too many numbers are supplied, the first ones are used and the rest are silently ignored.
If too few numbers are supplied, unspecified numbers are considered to be zero.
This is convenient particularly for multichannel printers where the additional inks
are spot colors or varnishes and not used for most colors.
Further define a fallback color, as decided at San Francisco.
Can be an sRGB fallback or indeed another color() function.
Need to add choice of quoted string or number+, to allow
for named color profiles.
10.2.
Predefined colorspaces: dci-p3 and rec2020.
These two colorspaces are indicated by using the predefined identifiers
dci-p3
or
rec2020
in the color function. No
<@color-profile>
at-rule is needed for these
predefined names; if one is supplied, it will be ignored.
The dci-p3
[DCI-P3]
colorspace has the following characteristics:
Red chromaticity
x=0.680 y=0.320
Green chromaticity
x=0.265 y=0.690
Blue chromaticity
x=0.150 y=0.060
White chromaticity
x=0.3127 y=0.3290 (D65)
Transfer function
1/2.6
The defining spec for dci-p3 is not freely available. It costs USD 240.
There is a Wikipedia article, which is non-authoritative and of unknown accuracy
(particularly for the transfer function and viewing conditions).
DCI transfer function for P3 is gamma 1/2.6 while Apple P3 displays use gamma 1/2.2.
The rec2020
[Rec.2020]
colorspace has the following characteristics:
Red chromaticity
x=0.708 y=0.292
Green chromaticity
x=0.170 y=0.797
Blue chromaticity
x=0.131 y=0.046
White chromaticity
x=0.3127 y=0.3290 (D65)
Transfer function
see below
rec2020 transfer function has the same form as the one for sRGB, but with
the constants at higher precision to cope with 10 or 12-bit components:
4.5
Math
pow
0.45
);
Where α=1.09929682680944 and β=0.018053968510807
10.2.1.
Converting predefined colorspaces to Lab
For both predefined color spaces, conversion to Lab requires several steps,
although in practice all but the first step are linear calculations and can be combined.
Convert from gamma-corrected RGB to linear-light RGB (undo gamma correction)
Convert from linear RGB to CIE XYZ
Convert from a D65 whitepoint (used by both dci-p3 and rec2020) to the D50 whitepoint used
in Lab, with the Bradford transform
Convert D50-adapted XYZ to Lab
Canvas proposes adding a 16bit half-float
linear
rec2020 space
10.2.2.
Converting Lab to predefined colorspaces
Conversion from Lab to dci-p3 or rec2020 also requires multiple steps, and again in practice all
but the last step are linear calculations and can be combined.
Convert Lab to (D50-adapted) XYZ
Convert from a D50 whitepoint (used by Lab) to the D65 whitepoint used
in sRGB, with the Bradford transform
Convert from (D65-adapted) CIE XYZ to linear RGB
Convert from linear-light RGB to RGB (do gamma correction)
Implementations may choose to implement these steps in some other way (for example,
using an ICC profile with relative colorimetric rendering intent) provided the results
are the same for colors inside the source and destination gamuts.
10.3.
Specifying a color profile: the
color-profile
at-rule
The
@color-profile
rule is a group rule. It consists of the at-keyword
'@color-profile' followed by a name, followed by a group rule body.
In a very similar way to the
<@font-face.
at-rule, the
<@color-profile>
at-rule has a name (which will be used inside the stylesheet),
and a descriptor to point to the actual
data (
src
, just like
src
in font-face.) The
src
descriptor takes a url() as it’s value.
Same-origin and CORS for src.
local() to use locally installed profiles. Profile stack
like font-face rather than a single url. Avoid flash of uncalibrated color.
A third, optional descriptor defines the
rendering intent
to use when mapping colors
from a larger to a smaller gamut.
This descriptor is only needed if the profile linked to has data for multiple rendering intents.
There are four values for rendering intent
[ICC]
relative-colorimetric
Media-relative colorimetric is required to leave source colors that fall
inside the destination medium gamut unchanged relative to the respective
media white points. Source colors that are out of the destination medium
gamut are mapped to colors on the gamut boundary using a variety of
different methods.
Note: the media-relative colorimetric rendering intent is
often used with black point compensation, where the source medium black point
is mapped to the destination medium black point as well.
This method must map the source white point to the desination white point. If
black point compensation is in use, the source black point must also be
mapped to the destination black point. Adaptation algorithms should be used
to adjust for the change in white point. Relative relationships of colors
inside both source and destination gamuts should be preserved. Relative
relationships of colors outside the destination gamut may be changed.
absolute-colorimetric
ICC-absolute colorimetric is required to leave source colors that fall
inside the destination medium gamut unchanged relative to the adopted
white (a perfect reflecting diffuser). Source colors that are out of the
destination medium gamut are mapped to colors on the gamut boundary using a
variety of different methods. This method produces the most accurate
color matching of in-gamut colors, but will result in highlight clipping
if the destination medium white point is lower than the source medium
white point. For this reason it is recommended for use only in applications
that need exact color matching and where highlight clipping is not a concern.
This method MUST disable white point matching and black point matching when
converting colors. In general, this option is not recommended except
for testing purposes.
perceptual
This method is often the preferred choice for images, especially when there are
substantial differences between the source and destination (such as a screen display
image reproduced on a reflection print). It takes the colors of the source image
and re-optimizes the appearance for the destination medium using proprietary
methods. This re-optimization may result in colors within both the source
and destination gamuts being changed, although perceptual transforms are
supposed to maintain the basic artistic intent of the original in the
reproduction. They will not attempt to correct errors in the source image.
With v2 ICC profiles there is no specified perceptual reference medium,
which can cause interoperability problems. When v2 ICC profiles are used it may
be safer to use the media-relative colorimetric rendering intent with black
point compensation, instead of the perceptual rendering intent, unless the
specific source and destination profiles to be used have been checked to ensure
the combination produces the desired result.
This method should maintain relative color values among the pixels as they
are mapped to the target device gamut. This method may change pixel values
that were originally within the target device gamut, in order to avoid
hue shifts and discontinuities and to preserve as much as possible the
overall appearance of the scene.
saturation
This option was created to preserve the relative saturation (chroma) of the original,
and to keep solid colors pure. However, it experienced interoperability problems like
the perceptual intent, and as solid color preservation is not amenable to a reference
medium solution using v4 profiles does not solve the problem. Use of this rendering intent
is not recommended unless the specific source and destination profiles to be used have
been checked to ensure the combination produces the desired result.
This option should preserve the relative saturation (chroma) values of the original
pixels. Out of gamut colors should be converted to colors that have the same saturation
but fall just inside the gamut.
RESOLVED: Do black point compensation when converting from
profile to another. This will depend on the rendering intent and
is mentioned there already. Does that suffice? What about black
point compensation for the flare correction built into sRGB?
FIX ME: MISSING
11.
Working Color Space
Resolved at San Francisco to add a working-color-space at-rule, which
affects the entire document. Compositing, interpolation, blending use this.
Initial value is sRGB. linear-sRGB, p3, rec2020, and lab were also discussed as values.
Chris to read the canvas spec to see what it does there, particularly for the
optimal
value.
12.
Device-dependent CMYK Colors: the
device-cmyk()
function
While screens typically display colors directly with RGB pixels,
printers often represent colors in different ways.
In particular, one of the most common print-based ways of representing colors is with CMYK:
a combination of cyan, magenta, yellow, and black which yields a particular color on that device.
The
device-cmyk()
function allows authors to specify a color in this way:
device-cmyk()
= device-cmyk(

#{4}





The arguments of the
device-cmyk()
function specify the cyan, magenta, yellow, and black components, in order,
as a number between 0 and 1 or a percentage between 0% and 100%.
These two usages are equivalent, and map to each other linearly.
Values less than 0 or 0%, or greater than 1 or 100%,
are not invalid;
instead, they are clamped to 0/0% or 1/100%.
The fifth argument specifies the alpha channel of the color.
It’s interpreted identically to the fourth argument of the
rgba()
function.
If omitted, it defaults to
100%
The sixth argument specifies the fallback color,
used when the user agent doesn’t know how to accurately transform the CMYK color to RGB.
If omitted, it defaults to the CMYK color
naively converted to RGBA
RESOLVED: If you accurately describe the output device’s color
profile in an @color-profile rule then a sane
implementation will not alter your colors so this is
sufficient as a replacement for device-cmyk in general
and provides a good RGB fallback automatically.
Typically, print-based applications will actually store the used colors as CMYK,
and send them to the printer in that form.
Unfortunately, CSS cannot do that;
various CSS features require an RGB color,
so that compositing/blending/etc. can be done.
As such, CMYK colors must be converted to an equivalent RGB color.
This is not trivial, like the conversion from HSL or HWB to RGB;
the precise conversion depends on the precise characteristics of the output device.
If the user agent has information about the output device such that it believes it can accurately convert the CMYK color to a correct RGB color,
the computed value of the
device-cmyk()
function must be that RGBA color.
Otherwise, the computed value must be the fallback color.
For example, the following colors are equivalent
(under the default conversion listed above):
color:
device-cmyk(0,
81%,
81%,
30%);
color:
rgb(178,
34,
34);
color:
firebrick;
Note: these colors might not match precisely
if the browser knows a more precise conversion between CMYK and RGB colors.
It’s recommended that if authors use
any
CMYK colors in their document,
that they use
only
CMYK colors in their document
to avoid any color-matching difficulties.
12.1.
Converting Between Uncalibrated CMYK and RGB-Based Colors
This section now needs to clearly distinguish between calibrated (icc-based) color on the one hand, and uncalibrated device-cmyk on the other. This particularly affects conversion to and from RGB.
While most colors defined in this specification are directly compatible with RGBA,
and thus can be mechanically and consistently converted back and forth with it,
CMYK colors are not directly compatible;
a given CMYK color
will map to various RGBA colors
depending on the physical characteristics of the output device.
Ideally, the user agent will be aware of the output device’s color profiles for RGBA and CMYK.
If this is true,
then the user agent must convert between CMYK and RGBA colors (and vice versa)
by first converting the color into an appropriate device-independent color space,
such as CIELab,
and then converting into the output color space,
using the appropriate color profiles for each operation.
This is not always possible, however.
In that case, the user agent must use the following naive conversion algorithms.
To
naively convert from CMYK to RGBA
If a fallback color was specified,
return that color
(converting it to RGB as well, if necessary).
Otherwise:
red
min
cyan
black
black
green
min
magenta
black
black
blue
min
yellow
black
black
Alpha is same as for input color.
To
naively convert from RGBA to CMYK
black
max
red
green
blue
cyan
red
black
black
),
or
if
black
is
magenta
green
black
black
),
or
if
black
is
yellow
blue
black
black
),
or
if
black
is
alpha is the same as the input color
fallback color must be set to the input color
13.
Modifying Colors: the
color-mod()
function
When specifying a color scheme for a site,
one often wants a color that is close to another color,
but slightly different.
This becomes more important when CSS Variables are used,
where an author may wish to define a "base" color,
and then produce an array of slightly modified colors to use elsewhere.
The
color-mod()
function takes an existing color,
and applies zero or more "color adjusters" to it,
which specify how to manipulate the color in some way.
Several of the color adjusters straightforwardly manipulate the color
as an RGB, HSL, or HWB color,
as if you’d specified a color in the appropriate syntax with one argument slightly modified.
Others perform more complex manipulations of the color,
such as blending it
or finding contrasting colors.
Additionally, the
color-mod()
function defines a new, more intuitive syntax for specifying named colors,
based on
CNS
Actually add the CNS thing.
color-mod()
= color( [




[red(
green(
blue(
alpha(
a(] ['+'
'-']


] )
[red(
green(
blue(
alpha(
a(] '*'

rgb( ['+'
'-'] [


{3}
rgb( ['+'
'-']

rgb( '*'

[hue(
h(] ['+'
'-'
'*']

[saturation(
s(] ['+'
'-'
'*']

[lightness(
l(] ['+'
'-'
'*']

[whiteness(
w(] ['+'
'-'
'*']

[blackness(
b(] ['+'
'-'
'*']

tint(

shade(

blend(


[rgb
hsl
hwb]
blenda(


[rgb
hsl
hwb]
contrast(

The first argument specifies the
base color
If a

is given,
the
base color
is the HSL color with the given

, 100% saturation, and 50% lightness
(in other words, the fully-saturated color with the given hue).
After the
base color
zero or more

s can be specified.
Each

modifies the color in some way,
passing a new
base color
to the next

in the list.
The same

can be specified more than once in the list,
such as
color(red s(- 10%) s(- 10%))
each instance just modifies the color appropriately
(in this case, producing
hsl(0deg, 80%, 50%)
).
There are several classes of

with various effects,
defined in the following sections.
The computed value of a
color-mod()
function is the color produced by applying all the

s to the
base color
Note: While scaling can be specified without any spaces,
like
lightness(*150%)
adding/subtracting must be done with spaces after the +/-,
or else the +/- will be interpreted as part of the number
by the CSS parser.
An
achromatic
color doesn’t have a unique hue,
so some

s that would make the color no longer
achromatic
(such as
s(50%)
have special behavior for
achromatic
colors,
as described in each adjuster’s description.
However, it is possible for, within the space of a single
color-mod()
function,
for the
base color
to be chromatic,
an adjuster to make it
achromatic
and a following adjuster to make it chromatic again,
with an author having the reasonable expectation that the hue is maintained.
To allow this,
during the evaluation of a
color-mod()
function’s

s,
rather than storing intermediate colors as a 4-tuple of red, green, blue, and alpha,
as usual for CSS colors,
intermediate colors must be stored as a
5-tuple of red, green, blue, alpha, and hue angle
where the hue angle may be null for some colors and after some operations.
Whenever an operation interprets an
achromatic
color in HSL or HWB space,
if the color has a non-null hue angle,
that hue must be used for the color’s HSL/HWB interpretation.
(Individual operations define how to handle null hue angles.)
If the
base color
is
achromatic
the hue angle is initially null.
For example, here’s a possible
color-mod()
function that lightens and brightens the
base color
color(X
w(+
20%)
s(+
20%))
If X is a color like
blue
this works in the expected way -
after each operation,
the color is still chromatic
(and the return value is
#33f
).
On the other hand, if X is a greenish gray like
#787
which is represented in HWB as
hwb(120deg, 44%, 50%)
the first operation will boost the sum of white and black to greater than
100%
making it an
achromatic
gray
#8f8f8f
, to be specific).
However, the
color-mod()
function remembers that the hue of the color was originally
120deg
so when the second operation saturates the color,
it will result in a greenish-gray again
hsl(120deg, 20%, 56%)
, slightly lighter and brighter than the original color, which is what was intended).
More possibilities:
Muted colors.
Closure CSS Compiler computes a muted color from a FG and BG color:
take the FG’s hue,
drop the FG saturation some amount,
average FG and BG lightness.
I want more use-cases and visual examples of this being used.
Inverting a color. Use-cases?
Is this just done by inverting the r/g/b channels?
Is the
contrast()
adjuster what people really mean when they ask for invert?
Warmer/cooler. How to define? What’s warmer, red or yellow? What’s cooler, blue or green?
13.1.
RGBA Adjustment
The most basic set of

s modify the color’s channels directly,
altering the amount of red, green, blue, or alpha in the color.
[red( | green( | blue( | alpha( | a(] ['+' | '-']? [


] )
[red( | green( | blue( | alpha( | a(]

Sets or adjust the red, blue, green, or alpha channels of the
base color
If there is no operator,
the given channel is set to the given value.
If the operator is
or
the given channel is interpreted as the matching type (

or

and then incremented or decremented by the given value.
If the operator is
the given channel is multipled by the given value.
rgb( ['+' | '-']? [


]{3} )
Adjusts the
base color
in the red, green, and blue channels simultaneously.
All three channels are interpreted as the matching type (

or

and then incremented or decremented by the given values,
with the first value adjusting the red channel,
the second value adjusting the green channel,
and the third value adjusting the blue channel.
rgb( ['+' | '-']

Identical to the previous clause,
except that the adjustments to the three channels are specified in hexadecimal format;
the

is interpreted as a
hex color
then the red, green, and blue channels of the color
are applied as adjustments to the
base color
For example, in
color(red rgb(+ #004400))
the
base color
is
red
#ff0000
).
The red and blue channels aren’t adjusted at all
(those channels in the given color are both 0),
and the green channel is increased by 44
16
resulting in a final color of
#ff4400
rgb(

The red, green, and blue channels of the
base color
are multiplied by the given value.
All

s in this section,
except for
alpha()
and
a()
set the hue angle to
null
if the resulting color is
achromatic
13.2.
HSL/HWB Adjustment
The
hsl()
and
hwb()
functions provide alternative ways to specify colors numerically,
intended to be easier and more intuitive for humans.
Similarly, the
color-mod()
function allows a color to be adjusted in these "virtual channels".
[hue( | h(] ['+' | '-' |
]?

Sets or adjusts the hue of the
base color
when
base color
is interpreted as an HSL color.
If there is no operator,
the hue is set to the given value,
regardless of what the hue angle was previously.
Otherwise,
the hue is incremented or decremented, as appropriate,
by the given value.
If the
hue angle is null
the adjuster instead does nothing.
[saturation( | s(] ['+' | '-' |
]?

[lightness( | l(] ['+' | '-' |
]?

[whiteness( | w(] ['+' | '-' |
]?

[blackness( | b(] ['+' | '-' |
]?

Sets or adjusts the saturation, lightness, whiteness, or blackness of the
base color
when
base color
is interpreted as an HSL or HWB color, as appropriate.
If there is no operator,
the given channel is set to the given value.
If the operator is
or
the given channel is incremented or decremented by the given value.
If the operator is
the given channel is multiplied by the given value.
If the
hue angle is null
the operation is
s()
or
saturation()
and the adjuster would make the saturation greater than
0%
it instead does nothing.
If the
hue angle is null
the operation is
w()
white()
b()
, or
black()
and the adjuster would make the sum of whiteness and blackness less than 100%,
it additionally adjusts the opposite HWB channel
to make the sum equal to 100%.
(That is,
color(white w(- 20%))
would represent the same color as
hwb(0, 80%, 20%)
.)
13.3.
Tints and Shades: the
tint
and
shade
adjusters
While the
color-mod()
function does allow HWB adjustment of colors,
the peculiarities of how HWB is defined make it more difficult than it should be to just define a lighter or darker version of a color.
The
tint
and
shade
adjusters fix this,
by simply mixing the
base color
with white or black.
''tint(

)''
Mixes the
base color
with pure white to produce a lighter version of the
base color
Specifying a

less than
0%
or greater than
100%
is a syntax error,
and makes the function invalid.
Linearly interpolate the red, green, and blue channels of the
base color
with the red, green, and blue channels of pure white (
rgb(255,255,255)
),
where
0%
returns the
base color
and
100%
returns pure white.
Note:
tint(X%)
is identical to
blend(white X% rgb)
''shade(

)''
Mixes the
base color
with pure black to produce a darker version of the
base color
Identical to the previous clause,
except the
base color
is mixed with pure black (
rgb(0,0,0)
) rather than pure white.
13.4.
Color Blending: the
blend
and
blenda
adjusters
The
tint()
and
shade()
adjusters are common cases of the more general
blend()
adjuster,
which mixes the
base color
with an arbitrary color.
''blend(


[rgb | hsl | hwb]? )''
Mixes the
base color
with the given color to produce an intermediate color.
Specifying a

less than
0%
or greater than
100%
is a syntax error,
and makes the function invalid.
The final argument specifies which color space to blend the colors in,
defaulting to
rgb
if not specified.
Both the
base color
and the given color are interpreted as colors in the given color space,
then the components are blended.
For example,
color(yellow blend(blue 50%))
blends yellow (
#ffff00
) with blue (
#0000ff
) equally,
resulting in
#808080
, a medium gray.
On the other hand,
color(yellow blend(blue 50% hsl))
blends the same colors in HSL space,
where yellow is
hsl(60, 100%, 50%)
and blue is
hsl(240, 100%, 50%)
which results in
hsl(150, 100%, 50%)
, a fully-saturated shade of green.
To determine the resulting color,
interpret the
base color
and the given color in the appropriate color space
(RGB, HSL, or HWB).
Linearly interpolate each of the channels of the colors according to the given

where
0%
produces the specified

and
100%
produces the
base color
If the color space is
hsl
or
hwb
interpolate the hue channel either clockwise or counterclockwise,
whichever results in a shorter "path" between the two hue angles.
If the two hue angles are on opposite sides of the hue circle
(separated by 180 degrees),
take the clockwise path.
If the
hue angle is null
for one of the colors but not the other,
treat the null hue angle as being equal to the non-null hue angle for the purpose of this adjuster.
If both hue angles are
null
the resulting color’s hue angle is
null
as well.
Note: The choice of how to transition when the difference is
180deg
is arbitrary,
and was chosen merely to provide an unambiguous answer.
To achieve counter-clockwise behavior,
adjust either color’s hue angle by a small amount toward the desired direction.
For example, blending
yellow
(hue angle
60deg
) with 50%
purple
(hue angle
300deg
results in
red
(hue angle
0deg
),
not
cyan
(hue angle
180deg
),
even though
60
50
300
50
==
180
because the distance between the two colors when moving counter-clockwise is only 120 degrees,
as opposed to 240 degrees when going clockwise.
''blenda(


[rgb | hsl | hwb]? )''
Identical to the previous clause,
except it pays attention to the alpha channel of the two colors
blend()
just preserves the alpha channel of the
base color
).
Let
be the specified

rescaled to the range [-1,1],
where
0%
maps to -1 and
100%
maps to 1.
Let
be the difference of the alpha channels of the
base color
and the specified

also rescaled to the range [-1,1],
where
-100%
0%
base color
alpha and
100%
specified color alpha) maps to -1
and
100%
maps to 1.
If
== -1
let
new weight
equal
Otherwise, let
new weight
equal
) / (1 +
Reinterpret
new weight
as a percentage in the range [0%, 100%],
where -1 maps to
0%
and 1 maps to
100%
Calculate the result color as if
blend()
had been specified,
using the
new weight
percentage instead of the specified

and set the alpha channel of the result color to the average of the alpha channels of the
base color
and the specified

This blends the two colors in a way that pays attention to alpha,
similar to how compositing does.
Is there a better formula?
The current one was determined empirically to give good results,
but isn’t motivated by any theory.
Should we swap the defaults,
so
blend()
does the alpha blending,
and another name (or maybe another parameter) ignores alpha like
blend()
currently does?
Check with definitions in CSS compositing and blending module.
13.5.
Guaranteeing Adequate Contrast: the
contrast
adjuster
Guaranteeing that foreground and background colors contrast sufficiently is important,
but even if one knows the mathematical definition of "appropriate contrast",
it’s not trivial to calculate and figure out whether two arbitrary colors are good enough.
The
contrast()
adjuster makes this easy,
automatically computing a color that is sufficiently contrasting with the
base color
to satisfy accessibility guidelines.
''contrast(

? )''
Finds a color that contrasts with the
base color
suffficiently to satisfy accessibility guidelines,
using the definition of "contrast" given by
WCAG 2.0 Guideline 1.4.3
The

specifies the desired similarity between the
base color
and the returned color.
0%
will return the
minimum-contrast color
(the closest color to the
base color
that still contrasts sufficiently),
while
100%
will return the
maximum-contrast color
(white or black, whichever contrasts the
base color
more)
Specifying a value less than
0%
or greater than
100%
is invalid and a syntax error.
If omitted, the

defaults to
100%
Compute the
luminance
of the
base color
If it’s less than .5,
the
maximum-contrast color
is
hwb(X, 100%, 0%)
where X is the hue angle of the
base color
Otherwise,
the
maximum-contrast color
is
hwb(X, 0%, 100%)
where X is the hue angle of the
base color
Note: In other words, the
maximum-contrast color
is either white or black,
but with the hue set up correctly for the next step’s linear interpolation.
Looking only at colors that are linear interpolations in HWB space (a la the
blend()
adjuster) between the
base color
and the
maximum-contrast color
find the color with the smallest
contrast ratio
with the
base color
that is greater than 4.5.
This is the
minimum-contrast color
If there is no color with contrast ratio greather than 4.5,
return the
maximum-contrast color
immediately.
Note: 4.5 is the contrast ratio required by WCAG for Level AA contrast.
Note: Using this method, the contrast ratio will be monotonically non-increasing
as you go from the
maximum-contrast color
to the
base color
so a simple binary search will identify the
minimum-contrast color
in a small number of iterations.
Blend the
minimum-contrast color
and
maximum-contrast color
according to the specified

as if ''color(
maximum-contrast color
blend(
minimum-contrast color

hwb))'' were specified.
Return the blended color.
To compute the
luminance
of a color:
The code below is only for sRGB, and duplicates the
more general code in the conversions appendix.
Scale the red, green, and blue channels of the color to the range [0,1].
For each channel,
if the channel’s value is less than or equal to 0.03928,
set the channel’s value to
channel
12.92
Otherwise, set the channel’s value to
((
channel
0.055
1.055
2.4
Note: This reverses the logarithmic power scaling of the sRGB gamut,
so the value of the channel is linear with respect to the amount of light produced.
The luminance is:
0.2126
0.7152
0.0722
where R, G, and B are the adjusted red, green, and blue channels from the previous step.
Note: The luminance of a color within the sRGB gamut is contained within the range [0,1],
where black is 0 and white is 1.
To compute the
contrast ratio
of two colors:
Compute the
luminance
of both colors.
The contrast ratio is:
L1
0.05
L2
0.05
where L1 is the larger of the two luminances, and L2 is the smaller.
Note: The contrast ratio of two colors is contained within the range [1,21],
where two identical colors are 1 and the ratio of white and black is 21.
14.
Transparency: the
opacity
property
Opacity can be thought of as a postprocessing operation.
Conceptually, after the element (including its descendants) is rendered into an RGBA offscreen image,
the opacity setting specifies how to blend the offscreen rendering into
the current composite rendering.
See
simple alpha compositing
for details.
Name:
opacity
Value:

Initial:
Applies to:
all elements
Inherited:
no
Percentages:
N/A
Media:
visual
Computed value:
The specified value, clamped to the range [0,1].
Animation type:
discrete

The opacity to be applied to the element.
It is interpreted identically to its definition in
rgba()
except that the resulting opacity is applied to the entire element,
rather than a particular color.
The
opacity
property applies the specified opacity to the element
as a whole
including its contents,
rather than applying it to each descendant individually.
This means that, for example,
an opaque child occluding part of the element’s background will continue to do so even when
opacity
is less than 1,
but the element and child as a whole will show the underlying page through themselves.
If
opacity
has a value less than 1,
the element forms a
stacking context
for its children.
This means that any content outside of it cannot be layered in z-order between pieces of content inside of it,
and vice versa.
If the element is in a context where the
z-index
property applies,
the
auto
value is treated as
for the element.
See
section 9.9
and
Appendix E
of
[CSS21]
for more information on stacking contexts.
The rules in this paragraph do not apply to SVG elements,
since SVG has its own
rendering model
[SVG11]
, Chapter 3).
14.1.
Simple alpha compositing
When drawing, implementations must handle alpha
according to the rules in
Section 14.2 Simple alpha compositing
of
[SVG11]
(If the
color-interpolation
or
color-rendering
properties mentioned in that section
are not implemented or do not apply, implementations must act as though they have their initial values.)
15.
Preserving Colors in Different-Capability Devices: the
color-adjust
property
On most monitors,
the color choices that authors make have no significant difference
in terms of how the device performs;
displaying a document with a white background or a black background is approximately equally easy.
However, some devices have limitations and other qualities that make this assumption untrue.
For example,
printers tend to print on white paper;
a document with a white background thus has to spend no ink on drawing that background,
while a document with a black background will have to expend a large amount of ink filling in the background color.
This tends to look fairly bad,
and sometimes has deleterious physical effects on the paper,
not to mention the vastly increased printing cost from expending the extra ink.
Even fairly small differences,
such as coloring text black versus dark gray,
can be quite different when printing,
as it switches from using a single black ink
to a mixture of cyan, magenta, and yellow ink,
resulting in higher ink usage and lower resolution.
As a result, in some circumstances user agents will alter the styles an author specifies in some particular context,
adjusting them to be more appropriate for the output device
and to accommodate what they assume the user would prefer.
However, in some cases the document may be using colors in important, well-thought-out ways that the user would appreciate,
and so the document would like some way to hint to the user agent that it might want to respect the page’s color choices.
The
color-adjust
property controls this.
Name:
color-adjust
Value:
economy
exact
Initial:
economy
Applies to:
all elements
Inherited:
yes
Percentages:
N/A
Media:
visual
Computed value:
as specified
Animation type:
discrete
The
color-adjust
property provides a hint to the user-agent about how it should treat color and style choices
that might be expensive or generally unwise on a given device,
such as using light text on a dark background in a printed document.
If user agents allow users to control this aspect of the document’s display,
the user preference
must
be respected more strongly
than the hint provided by
color-adjust
It has the following values:
economy
The user agent should make adjustments to the page’s styling
as it deems necessary and prudent for the output device.
For example, if the document is being printed,
a user agent might ignore any backgrounds
and adjust text color to be sufficiently dark,
to minimize ink usage.
exact
This value indicates that the page is using color and styling on the specified element
in a way which is important and significant,
and which should not be tweaked or changed except at the user’s request.
For example,
a mapping website offering printed directions
might "zebra-stripe" the steps in the directions,
alternating between white and light gray backgrounds.
Losing this zebra-striping and having a pure-white background
would make the directions harder to read with a quick glance
when distracted in a car.
16.
Default Style Rules
The following stylesheet is informative, not normative. This style sheet could be used by an implementation as part of its default styling of HTML4, XHTML1, XHTML1.1, XHTML Basic, and other XHTML Family documents.
html
color
black
/* traditional desktop user agent colors for hyperlinks */
:link
color
blue
:visited
color
purple
The default background of the root element must be
transparent
The default color of the canvas (the surface on which the document is painted)
is UA-dependent,
but is recommended to be
white
especially if the above
color
rules are used.
17.
Sample code for color conversions
// sRGB-related functions
function
lin_sRGB
RGB
// convert an array of sRGB values in the range 0.0 - 1.0
// to linear light (un-companded) form.
// https://en.wikipedia.org/wiki/SRGB
return
RGB
map
function
val
if
val
0.04045
return
val
12.92
return
Math
pow
((
val
0.055
1.055
2.4
);
});
function
gam_sRGB
RGB
// convert an array of linear-light sRGB values in the range 0.0-1.0
// to gamma corrected form
// https://en.wikipedia.org/wiki/SRGB
return
RGB
map
function
val
if
val
0.0031308
return
1.055
Math
pow
val
2.4
0.055
return
12.92
val
});
function
lin_sRGB_to_XYZ
rgb
// convert an array of linear-light sRGB values to CIE XYZ
// using sRGB’s own white, D65 (no chromatic adaptation)
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
var
math
matrix
([
0.4124564
0.3575761
0.1804375
],
0.2126729
0.7151522
0.0721750
],
0.0193339
0.1191920
0.9503041
]);
return
math
multiply
rgb
).
valueOf
();
function
XYZ_to_lin_sRGB
XYZ
// convert XYZ to linear-light sRGB
var
math
matrix
([
3.2404542
1.5371385
0.4985314
],
0.9692660
1.8760108
0.0415560
],
0.0556434
0.2040259
1.0572252
]);
return
math
multiply
XYZ
).
valueOf
();
// DCI P3-related functions
function
lin_P3
RGB
// convert an array of DCI P3 RGB values in the range 0.0 - 1.0
// to linear light (un-companded) form.
return
RGB
map
function
val
return
Math
pow
val
2.6
);
});
function
gam_P3
RGB
// convert an array of linear-light P3 RGB in the range 0.0-1.0
// to gamma corrected form
return
RGB
map
function
val
return
Math
pow
val
2.6
);
});
function
lin_P3_to_XYZ
rgb
// convert an array of linear-light P3 values to CIE XYZ
// using D65 (no chromatic adaptation)
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
var
math
matrix
([
0.4865709486482162
0.26566769316909306
0.1982172852343625
],
0.2289745640697488
0.6917385218365064
0.079286914093745
],
0.0000000000000000
0.04511338185890264
1.043944368900976
]);
// 0 was computed as -3.972075516933488e-17
return
math
multiply
rgb
).
valueOf
();
function
XYZ_to_lin_P3
XYZ
// convert XYZ to linear-light P3
var
math
matrix
([
2.493496911941425
0.9313836179191239
0.40271078445071684
],
0.8294889695615747
1.7626640603183463
0.023624685841943577
],
0.03584583024378447
0.07617238926804182
0.9568845240076872
]);
return
math
multiply
XYZ
).
valueOf
();
//Rec.2020-related functions
function
lin_2020
RGB
// convert an array of Rec.2020 RGB values in the range 0.0 - 1.0
// to linear light (un-companded) form.
const
1.09929682680944
const
0.018053968510807
return
RGB
map
function
val
if
val
4.5
return
val
4.5
return
Math
pow
((
val
2.4
);
});
//check with standard this really is 2.4 and 1/2.4, not 0.45 was wikipedia claims
function
gam_2020
RGB
// convert an array of linear-light Rec.2020 RGB in the range 0.0-1.0
// to gamma corrected form
const
1.09929682680944
const
0.018053968510807
return
RGB
map
function
val
if
val
return
Math
pow
val
2.4
);
return
4.5
val
});
function
lin_2020_to_XYZ
rgb
// convert an array of linear-light rec.2020 values to CIE XYZ
// using D65 (no chromatic adaptation)
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
var
math
matrix
([
0.6369580483012914
0.14461690358620832
0.1688809751641721
],
0.2627002120112671
0.6779980715188708
0.05930171646986196
],
0.000000000000000
0.028072693049087428
1.060985057710791
]);
// 0 is actually calculated as 4.994106574466076e-17
return
math
multiply
rgb
).
valueOf
();
function
XYZ_to_lin_2020
XYZ
// convert XYZ to linear-light rec.2020
var
math
matrix
([
1.7166511879712674
0.35567078377639233
0.25336628137365974
],
0.6666843518324892
1.6164812366349395
0.01576854581391113
],
0.017639857445310783
0.042770613257808524
0.9421031212354738
]);
return
math
multiply
XYZ
).
valueOf
();
// Chromatic adaptation
function
D65_to_D50
XYZ
// Bradford chromatic adaptation from D65 to D50
// The matrix below is the result of three operations:
// - convert from XYZ to retinal cone domain
// - scale components from one reference white to another
// - convert back to XYZ
// http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
var
math
matrix
([
1.0478112
0.0228866
0.0501270
],
0.0295424
0.9904844
0.0170491
],
0.0092345
0.0150436
0.7521316
]);
return
math
multiply
XYZ
).
valueOf
();
function
D50_to_D65
XYZ
// Bradford chromatic adaptation from D50 to D65
var
math
matrix
([
0.9555766
0.0230393
0.0631636
],
0.0282895
1.0099416
0.0210077
],
0.0122982
0.0204830
1.3299098
]);
return
math
multiply
XYZ
).
valueOf
();
// Lab and LCH
function
XYZ_to_Lab
XYZ
// Assuming XYZ is relative to D50, convert to CIE Lab
// from CIE standard, which now defines these as a rational fraction
var
216
24389
// 6^3/29^3
var
24389
27
// 29^3/3^3
var
white
0.9642
1.0000
0.8249
];
// D50 reference white
// compute xyz, which is XYZ scaled relative to reference white
var
xyz
XYZ
map
((
value
=>
value
white
]);
// now compute f
var
xyz
map
value
=>
value
Math
cbrt
value
value
16
116
);
return
116
])
16
// L
500
]),
// a
200
])
// b
];
function
Lab_to_XYZ
Lab
// Convert Lab to D50-adapted XYZ
var
24389
27
// 29^3/3^3
var
216
24389
// 6^3/29^3
var
white
0.9642
1.0000
0.8249
];
// D50 reference white
var
[];
// compute f, starting with the luminance-related term
Lab
16
116
Lab
500
];
Lab
200
// compute xyz
var
xyz
Math
pow
],
Math
pow
],
116
16
Lab
Math
pow
((
Lab
16
116
Lab
Math
pow
],
Math
pow
],
116
16
];
// Compute XYZ by scaling xyz by reference white
return
xyz
map
((
value
=>
value
white
]);
function
Lab_to_LCH
Lab
// Convert to polar form
return
Lab
],
// L is still L
Math
sqrt
Math
pow
Lab
],
Math
pow
Lab
],
)),
// Chroma
Math
atan2
Lab
],
Lab
])
180
Math
PI
// Hue, in degrees
];
function
LCH_to_Lab
LCH
// Convert from polar form
return
LCH
],
// L is still L
LCH
Math
cos
LCH
Math
PI
180
),
// a
LCH
Math
sin
LCH
Math
PI
180
// b
];
Appendix A: Deprecated CSS System Colors
Earlier versions of CSS defined several additional named color keywords,
the

s,
which were meant to take their value from operating system themes.
These color names have been
deprecated
, however,
as they are insufficient for their original purpose
(making website elements look like their native OS counterparts),
and represent a security risk,
as it makes it easier for a webpage to "spoof" a native OS dialog.
User agents must support these keywords,
but should map them to "default" values,
not based on the user’s OS settings
(for example, mapping all the "background" colors to white and "foreground" colors to black).
Authors must not use these keywords.
ActiveBorder
Active window border.
ActiveCaption
Active window caption.
AppWorkspace
Background color of multiple document interface.
Background
Desktop background.
ButtonFace
The face background color for 3-D elements that appear 3-D due to
one layer of surrounding border.
ButtonHighlight
The color of the border facing the light source for 3-D elements
that appear 3-D due to one layer of surrounding border.
ButtonShadow
The color of the border away from the light source for 3-D elements
that appear 3-D due to one layer of surrounding border.
ButtonText
Text on push buttons.
CaptionText
Text in caption, size box, and scrollbar arrow box.
GrayText
Grayed (disabled) text. This color is set to #000 if
the current display driver does not support a solid gray color.
Highlight
Item(s) selected in a control.
HighlightText
Text of item(s) selected in a control.
InactiveBorder
Inactive window border.
InactiveCaption
Inactive window caption.
InactiveCaptionText
Color of text in an inactive caption.
InfoBackground
Background color for tooltip controls.
InfoText
Text color for tooltip controls.
Menu background.
MenuText
Text in menus.
Scrollbar
Scroll bar gray area.
ThreeDDarkShadow
The color of the darker (generally outer) of the two borders away
from the light source for 3-D elements that appear 3-D due to two
concentric layers of surrounding border.
ThreeDFace
The face background color for 3-D elements that appear 3-D due to
two concentric layers of surrounding border.
ThreeDHighlight
The color of the lighter (generally outer) of the two borders facing
the light source for 3-D elements that appear 3-D due to two
concentric layers of surrounding border.
ThreeDLightShadow
The color of the darker (generally inner) of the two borders facing
the light source for 3-D elements that appear 3-D due to two
concentric layers of surrounding border.
ThreeDShadow
The color of the lighter (generally inner) of the two borders away
from the light source for 3-D elements that appear 3-D due to two
concentric layers of surrounding border.
Window
Window background.
WindowFrame
Window frame.
WindowText
Text in windows.
Acknowledgments
Thanks to Brad Pettit both for writing up color-profiles, and for implementing it. Thanks to Steven Pemberton for his write up on HSL colors.
Thanks especially to the feedback from Marc Attinasi, Bert Bos, Joe Clark, fantasai, Patrick Garies, Tony Graham, Ian Hickson, Susan Lesch, Alex LeDonne, Cameron McCormack, Krzysztof Maczyński, Chris Moschini, Chris Murphy, Christoph Päper, David Perrell, Jacob Refstrup, Dave Singer, Jonathan Stanley, Andrew Thompson, Russ Weakley, Etan Wexler, David Woolley, Boris Zbarsky, Steve Zilles, the XSL FO subgroup of the XSL working group, and all the rest of the
www-style
community.
And thanks to Chris Lilley for being the resident CSS Color expert.
Changes
Changes from Colors 3
rgb()
and
rgba()
functions now accept

rather than

hsl()
and
hsla()
functions now accept

as well as

for hues.
All uses of

now accept

as well as

4 and 8-digit hex colors have been added, to specify transparency.
Several brand new features have been added:
gray()
function, for specifying grays compactly. (And maybe allowing specification via luminance.)
hwb()
function, for specifying colors in the HWB notation.
color-mod()
function, for manipulating colors.
lab()
and
lch
functions, for device-independent color
color()
function and
profile
at-rule, for profiled device-dependent color.
device-cmyk()
function, for specifying uncalibrated colors in an output-device-specific CMYK colorspace.
Addition of named color
rebeccapurple
Conformance
Document conventions
Conformance requirements are expressed with a combination of
descriptive assertions and RFC 2119 terminology. The key words “MUST”,
“MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
“RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
document are to be interpreted as described in RFC 2119.
However, for readability, these words do not appear in all uppercase
letters in this specification.
All of the text of this specification is normative except sections
explicitly marked as non-normative, examples, and notes.
[RFC2119]
Examples in this specification are introduced with the words “for example”
or are set apart from the normative text with
class="example"
like this:
This is an example of an informative example.
Informative notes begin with the word “Note” and are set apart from the
normative text with
class="note"
, like this:
Note, this is an informative note.
Advisements are normative sections styled to evoke special attention and are
set apart from other normative text with

, like
this:
UAs MUST provide an accessible alternative.
Conformance classes
Conformance to this specification
is defined for three conformance classes:
style sheet
CSS
style sheet
renderer
UA
that interprets the semantics of a style sheet and renders
documents that use them.
authoring tool
UA
that writes a style sheet.
A style sheet is conformant to this specification
if all of its statements that use syntax defined in this module are valid
according to the generic CSS grammar and the individual grammars of each
feature defined in this module.
A renderer is conformant to this specification
if, in addition to interpreting the style sheet as defined by the
appropriate specifications, it supports all the features defined
by this specification by parsing them correctly
and rendering the document accordingly. However, the inability of a
UA to correctly render a document due to limitations of the device
does not make the UA non-conformant. (For example, a UA is not
required to render color on a monochrome monitor.)
An authoring tool is conformant to this specification
if it writes style sheets that are syntactically correct according to the
generic CSS grammar and the individual grammars of each feature in
this module, and meet all other conformance requirements of style sheets
as described in this module.
Requirements for Responsible Implementation of CSS
The following sections define several conformance requirements
for implementing CSS responsibly,
in a way that promotes interoperability in the present and future.
Partial Implementations
So that authors can exploit the forward-compatible parsing rules to assign fallback values,
CSS renderers
must
treat as invalid
(and
ignore as appropriate
any at-rules, properties, property values, keywords, and other syntactic constructs
for which they have no usable level of support
In particular, user agents
must not
selectively ignore
unsupported property values and honor supported values in a single multi-value property declaration:
if any value is considered invalid (as unsupported values must be),
CSS requires that the entire declaration be ignored.
Implementations of Unstable and Proprietary Features
To avoid clashes with future stable CSS features,
the CSSWG recommends
following best practices
for the implementation of
unstable
features and
proprietary extensions
to CSS.
Implementations of CR-level Features
Once a specification reaches the Candidate Recommendation stage,
implementers should release an
unprefixed
implementation
of any CR-level feature they can demonstrate
to be correctly implemented according to spec,
and should avoid exposing a prefixed variant of that feature.
To establish and maintain the interoperability of CSS across
implementations, the CSS Working Group requests that non-experimental
CSS renderers submit an implementation report (and, if necessary, the
testcases used for that implementation report) to the W3C before
releasing an unprefixed implementation of any CSS features. Testcases
submitted to W3C are subject to review and correction by the CSS
Working Group.
Further information on submitting testcases and implementation reports
can be found from on the CSS Working Group’s website at
Questions should be directed to the
public-css-testsuite@w3.org
mailing list.
Index
Terms defined by this specification
achromatic
, in §3
ActiveBorder
, in §Unnumbered section
ActiveCaption
, in §Unnumbered section
aliceblue
, in §5

, in §4.1
antiquewhite
, in §5
AppWorkspace
, in §Unnumbered section
aqua
, in §5
aquamarine
, in §5
azure
, in §5
Background
, in §Unnumbered section
beige
, in §5
bisque
, in §5
black
, in §5
blanchedalmond
, in §5
blue
, in §5
blueviolet
, in §5
brown
, in §5
burlywood
, in §5
ButtonFace
, in §Unnumbered section
ButtonHighlight
, in §Unnumbered section
ButtonShadow
, in §Unnumbered section
ButtonText
, in §Unnumbered section
cadetblue
, in §5
CaptionText
, in §Unnumbered section
chartreuse
, in §5
chocolate
, in §5

, in §12
color()
, in §10.1

, in §3
color
, in §2
color-adjust
, in §15

, in §13
color-mod()
, in §13
@color-profile
, in §10.3
contrast ratio
, in §13.5
coral
, in §5
cornflowerblue
, in §5
cornsilk
, in §5
crimson
, in §5
currentcolor
, in §5.2
cyan
, in §5
darkblue
, in §5
darkcyan
, in §5
darkgoldenrod
, in §5
darkgray
, in §5
darkgreen
, in §5
darkgrey
, in §5
darkkhaki
, in §5
darkmagenta
, in §5
darkolivegreen
, in §5
darkorange
, in §5
darkorchid
, in §5
darkred
, in §5
darksalmon
, in §5
darkseagreen
, in §5
darkslateblue
, in §5
darkslategray
, in §5
darkslategrey
, in §5
darkturquoise
, in §5
darkviolet
, in §5
deeppink
, in §5
deepskyblue
, in §5

, in §Unnumbered section
device-cmyk()
, in §12
dimgray
, in §5
dimgrey
, in §5
dodgerblue
, in §5
economy
, in §15
exact
, in §15
firebrick
, in §5
FIX ME: MISSING
, in §10.3
floralwhite
, in §5
forestgreen
, in §5
fuchsia
, in §5
gainsboro
, in §5
ghostwhite
, in §5
gold
, in §5
goldenrod
, in §5
gray
, in §5
gray()
, in §9
GrayText
, in §Unnumbered section
green
, in §5
greenyellow
, in §5
grey
, in §5

, in §4.2
hex color
, in §4.2
Highlight
, in §Unnumbered section
HighlightText
, in §Unnumbered section
honeydew
, in §5
hotpink
, in §5
hsl()
, in §6
hsla()
, in §6

, in §6
hue angle is null
, in §13
hwb()
, in §7
InactiveBorder
, in §Unnumbered section
InactiveCaption
, in §Unnumbered section
InactiveCaptionText
, in §Unnumbered section
indianred
, in §5
indigo
, in §5
InfoBackground
, in §Unnumbered section
InfoText
, in §Unnumbered section
ivory
, in §5
khaki
, in §5
lab()
, in §8.1
lavender
, in §5
lavenderblush
, in §5
lawngreen
, in §5
lch()
, in §8.1
lemonchiffon
, in §5
lightblue
, in §5
lightcoral
, in §5
lightcyan
, in §5
lightgoldenrodyellow
, in §5
lightgray
, in §5
lightgreen
, in §5
lightgrey
, in §5
lightpink
, in §5
lightsalmon
, in §5
lightseagreen
, in §5
lightskyblue
, in §5
lightslategray
, in §5
lightslategrey
, in §5
lightsteelblue
, in §5
lightyellow
, in §5
lime
, in §5
limegreen
, in §5
linen
, in §5
luminance
, in §13.5
magenta
, in §5
maroon
, in §5
mediumaquamarine
, in §5
mediumblue
, in §5
mediumorchid
, in §5
mediumpurple
, in §5
mediumseagreen
, in §5
mediumslateblue
, in §5
mediumspringgreen
, in §5
mediumturquoise
, in §5
mediumvioletred
, in §5
, in §Unnumbered section
MenuText
, in §Unnumbered section
midnightblue
, in §5
mintcream
, in §5
mistyrose
, in §5
moccasin
, in §5
naively converted to CMYK
, in §12.1
naively converted to RGBA
, in §12.1
naively convert from CMYK to RGBA
, in §12.1
naively convert from RGBA to CMYK
, in §12.1

, in §5
named color
, in §5
navajowhite
, in §5
navy
, in §5
null
, in §13
oldlace
, in §5
olive
, in §5
olivedrab
, in §5
opacity
, in §14
orange
, in §5
orangered
, in §5
orchid
, in §5
palegoldenrod
, in §5
palegreen
, in §5
paleturquoise
, in §5
palevioletred
, in §5
papayawhip
, in §5
peachpuff
, in §5
peru
, in §5
pink
, in §5
plum
, in §5
powderblue
, in §5
purple
, in §5
rebeccapurple
, in §5
red
, in §5
rendering intent
, in §10.3
rgb()
, in §4.1
rgba()
, in §4.1

, in §4.1
rosybrown
, in §5
royalblue
, in §5
saddlebrown
, in §5
salmon
, in §5
sandybrown
, in §5
Scrollbar
, in §Unnumbered section
seagreen
, in §5
seashell
, in §5
sienna
, in §5
silver
, in §5
skyblue
, in §5
slateblue
, in §5
slategray
, in §5
slategrey
, in §5
snow
, in §5
springgreen
, in §5
src
, in §10.3
steelblue
, in §5
tan
, in §5
teal
, in §5
thistle
, in §5
ThreeDDarkShadow
, in §Unnumbered section
ThreeDFace
, in §Unnumbered section
ThreeDHighlight
, in §Unnumbered section
ThreeDLightShadow
, in §Unnumbered section
ThreeDShadow
, in §Unnumbered section
tomato
, in §5
transparent
, in §5.1
turquoise
, in §5
untagged image
, in §3.2
violet
, in §5
wheat
, in §5
white
, in §5
whitesmoke
, in §5
Window
, in §Unnumbered section
WindowFrame
, in §Unnumbered section
WindowText
, in §Unnumbered section
yellow
, in §5
yellowgreen
, in §5
Terms defined by reference
[css-position-3]
defines the following terms:
auto
stacking context
z-index
[css-syntax-3]
defines the following terms:

[CSS3-TEXT-DECOR]
defines the following terms:
text-emphasis-color
[css-values]
defines the following terms:





{a}
[filters-1]
defines the following terms:
contrast()
[mediaqueries-4]
defines the following terms:

[selectors-4]
defines the following terms:
[SVG2]
defines the following terms:
color-interpolation
color-rendering
References
Normative References
[CSS-POSITION-3]
Rossen Atanassov; Arron Eicholz.
CSS Positioned Layout Module Level 3
. 17 May 2016. WD. URL:
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin.
CSS Syntax Module Level 3
. 20 February 2014. CR. URL:
[CSS-VALUES]
Tab Atkins Jr.; Elika Etemad.
CSS Values and Units Module Level 3
. 11 June 2015. CR. URL:
[CSS21]
Bert Bos; et al.
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification
. 7 June 2011. REC. URL:
[DCI-P3]
RP 431-2, D-Cinema Quality – Reference Projector and Environment for the Display of DCDM in Review Rooms and Theaters. 2011.
[FILTERS-1]
Filter Effects Level 1 URL:
[ICC]
ICC.1:2010 (Profile version 4.3.0.0)
. December 2010. URL:
[MEDIAQUERIES-4]
Florian Rivoal; Tab Atkins Jr..
Media Queries Level 4
. 23 June 2016. WD. URL:
[Rec.2020]
Recommendation ITU-R BT.2020-2: Parameter values for ultra-high definition television systems for production and international programme exchange
. October 2015. URL:
[RFC2119]
S. Bradner.
Key words for use in RFCs to Indicate Requirement Levels
. March 1997. Best Current Practice. URL:
[SELECTORS-4]
Selectors Level 4 URL:
[SRGB]
Multimedia systems and equipment - Colour measurement and management - Part 2-1: Colour management - Default RGB colour space - sRGB.
IEC 61966-2-1 (1999-10). ISBN: 2-8318-4989-6 - ICS codes: 33.160.60, 37.080 - TC 100 - 51 pp. URL:
[SVG11]
Erik Dahlström; et al.
Scalable Vector Graphics (SVG) 1.1 (Second Edition)
. 16 August 2011. REC. URL:
[SVG2]
Nikos Andronikos; et al.
Scalable Vector Graphics (SVG) 2
. 15 September 2015. WD. URL:
Informative References
[COLORIMETRY]
Colorimetry, Second Edition. 15 February 1986.
[CSS3-TEXT-DECOR]
Elika Etemad; Koji Ishii.
CSS Text Decoration Module Level 3
. 1 August 2013. CR. URL:
[WCAG20]
Ben Caldwell; et al.
Web Content Accessibility Guidelines (WCAG) 2.0
. 11 December 2008. REC. URL:
Property Index
Name
Value
Initial
Applies to
Inh.
%ages
Media
Anim­ation type
Com­puted value
color

UA-defined, see prose
all elements
yes
N/A
visual
discrete
an RGBA color
opacity

all elements
no
N/A
visual
discrete
The specified value, clamped to the range [0,1].
color-adjust
economy | exact
economy
all elements
yes
N/A
visual
discrete
as specified
Issues Index
Really? Isn’t HD video in Rec.709? Shouldn’t video be consistent with images?
Or do implementations really do this differently?
The transfer function is undefined outside the range 0% to 100%.
Need to define handling for out of range numbers.
Clip L, wrap H? Have also seen L up to 400, specifically
for high dynamic range situations.
Need to decide what, if anything, to do
for high dynamic range on luminance.
As decided at San Francisco, this syntax is an alias to Lab with a=b=0.
color() fallback should be like font list fallback, as decided at San Francisco. Recursive?
Decided at San Francisco to add a larger set of common predefined spaceslike AdobeRGB, ProPhoto RGB, and so on. Also coated and uncoated swop, etc, etc.
Further define a fallback color, as decided at San Francisco.
Can be an sRGB fallback or indeed another color() function.
Need to add choice of quoted string or number+, to allow
for named color profiles.
The defining spec for dci-p3 is not freely available. It costs USD 240.
There is a Wikipedia article, which is non-authoritative and of unknown accuracy
(particularly for the transfer function and viewing conditions).
DCI transfer function for P3 is gamma 1/2.6 while Apple P3 displays use gamma 1/2.2.
Canvas proposes adding a 16bit half-float
linear
rec2020 space
Same-origin and CORS for src.
local() to use locally installed profiles. Profile stack
like font-face rather than a single url. Avoid flash of uncalibrated color.
RESOLVED: Do black point compensation when converting from
profile to another. This will depend on the rendering intent and
is mentioned there already. Does that suffice? What about black
point compensation for the flare correction built into sRGB?
Resolved at San Francisco to add a working-color-space at-rule, which
affects the entire document. Compositing, interpolation, blending use this.
Initial value is sRGB. linear-sRGB, p3, rec2020, and lab were also discussed as values.
Chris to read the canvas spec to see what it does there, particularly for the
optimal
value.
RESOLVED: If you accurately describe the output device’s color
profile in an @color-profile rule then a sane
implementation will not alter your colors so this is
sufficient as a replacement for device-cmyk in general
and provides a good RGB fallback automatically.
This section now needs to clearly distinguish between calibrated (icc-based) color on the one hand, and uncalibrated device-cmyk on the other. This particularly affects conversion to and from RGB.
Actually add the CNS thing.
More possibilities:
Muted colors.
Closure CSS Compiler computes a muted color from a FG and BG color:
take the FG’s hue,
drop the FG saturation some amount,
average FG and BG lightness.
I want more use-cases and visual examples of this being used.
Inverting a color. Use-cases?
Is this just done by inverting the r/g/b channels?
Is the
contrast()
adjuster what people really mean when they ask for invert?
Warmer/cooler. How to define? What’s warmer, red or yellow? What’s cooler, blue or green?
This blends the two colors in a way that pays attention to alpha,
similar to how compositing does.
Is there a better formula?
The current one was determined empirically to give good results,
but isn’t motivated by any theory.
Should we swap the defaults,
so
blend()
does the alpha blending,
and another name (or maybe another parameter) ignores alpha like
blend()
currently does?
Check with definitions in CSS compositing and blending module.
The code below is only for sRGB, and duplicates the
more general code in the conversions appendix.
#propdef-color
Referenced in:
2.
Foreground Color: the color property
(2)
(3)
5.2.
The currentcolor keyword
(2)
(3)
(4)
(5)
(6)
16.
Default Style Rules
#typedef-color
Referenced in:
1.
Introduction
2.
Foreground Color: the color property
(2)
(3)
3.
Representing sRGB Colors: the type
(2)
(3)
5.
Named Colors
(2)
12.
Device-dependent CMYK Colors: the device-cmyk() function
13.
Modifying Colors: the color-mod() function
(2)
(3)
13.4.
Color Blending: the blend and blenda adjusters
(2)
(3)
(4)
(5)
#achromatic
Referenced in:
3.
Representing sRGB Colors: the type
(2)
(3)
(4)
7.
HWB Colors: hwb() function
13.
Modifying Colors: the color-mod() function
(2)
(3)
(4)
(5)
(6)
(7)
13.1.
RGBA Adjustment
#funcdef-rgb
Referenced in:
3.
Representing sRGB Colors: the type
(2)
4.1.
The RGB functions: rgb() and rgba()
(2)
4.2.
The RGB hexadecimal notations: #RRGGBB
Changes from Colors 3
#funcdef-rgba
Referenced in:
3.
Representing sRGB Colors: the type
(2)
4.1.
The RGB functions: rgb() and rgba()
6.
HSL Colors: hsl() and hsla() functions
7.
HWB Colors: hwb() function
12.
Device-dependent CMYK Colors: the device-cmyk() function
14.
Transparency: the opacity property
Changes from Colors 3
#typedef-rgb-component
Referenced in:
4.1.
The RGB functions: rgb() and rgba()
(2)
(3)
#typedef-alpha-value
Referenced in:
4.1.
The RGB functions: rgb() and rgba()
(2)
6.
HSL Colors: hsl() and hsla() functions
7.
HWB Colors: hwb() function
8.1. Specifying Lab and LCH: the lab() and lch() functional notations
(2)
9.
Specifying Grays: the gray() functional notation
10.1. Specifying profiled colors: the color() function
12.
Device-dependent CMYK Colors: the device-cmyk() function
14.
Transparency: the opacity property
(2)
Changes from Colors 3
#hex-color
Referenced in:
13.1.
RGBA Adjustment
#typedef-hex-color
Referenced in:
3.
Representing sRGB Colors: the type
#typedef-named-color
Referenced in:
3.
Representing sRGB Colors: the type
5.1.
The transparent keyword
#valdef-color-black
Referenced in:
2.
Foreground Color: the color property
#valdef-color-blue
Referenced in:
13.
Modifying Colors: the color-mod() function
#valdef-color-cyan
Referenced in:
13.4.
Color Blending: the blend and blenda adjusters
#valdef-color-purple
Referenced in:
13.4.
Color Blending: the blend and blenda adjusters
#valdef-color-rebeccapurple
Referenced in:
Changes from Colors 3
#valdef-color-red
Referenced in:
6.
HSL Colors: hsl() and hsla() functions
13.1.
RGBA Adjustment
13.4.
Color Blending: the blend and blenda adjusters
#valdef-color-white
Referenced in:
16.
Default Style Rules
#valdef-color-yellow
Referenced in:
13.4.
Color Blending: the blend and blenda adjusters
#valdef-color-transparent
Referenced in:
5.
Named Colors
5.1.
The transparent keyword
16.
Default Style Rules
#valdef-color-currentcolor
Referenced in:
2.
Foreground Color: the color property
(2)
5.
Named Colors
5.2.
The currentcolor keyword
(2)
(3)
(4)
(5)
(6)
#funcdef-hsl
Referenced in:
3.
Representing sRGB Colors: the type
(2)
6.
HSL Colors: hsl() and hsla() functions
(2)
7.
HWB Colors: hwb() function
13.2.
HSL/HWB Adjustment
Changes from Colors 3
#funcdef-hsla
Referenced in:
3.
Representing sRGB Colors: the type
(2)
6.
HSL Colors: hsl() and hsla() functions
Changes from Colors 3
#typedef-hue
Referenced in:
6.
HSL Colors: hsl() and hsla() functions
(2)
7.
HWB Colors: hwb() function
13.
Modifying Colors: the color-mod() function
(2)
(3)
#funcdef-hwb
Referenced in:
3.
Representing sRGB Colors: the type
7.
HWB Colors: hwb() function
(2)
13.2.
HSL/HWB Adjustment
Changes from Colors 3
#funcdef-lab
Referenced in:
Changes from Colors 3
#funcdef-gray
Referenced in:
3.
Representing sRGB Colors: the type
9.
Specifying Grays: the gray() functional notation
(2)
Changes from Colors 3
#funcdef-color
Referenced in:
10.1. Specifying profiled colors: the color() function
Changes from Colors 3
#funcdef-device-cmyk
Referenced in:
3.
Representing sRGB Colors: the type
12.
Device-dependent CMYK Colors: the device-cmyk() function
(2)
(3)
(4)
Changes from Colors 3
#typedef-cmyk-component
Referenced in:
12.
Device-dependent CMYK Colors: the device-cmyk() function
#naively-convert-from-cmyk-to-rgba
Referenced in:
12.
Device-dependent CMYK Colors: the device-cmyk() function
#funcdef-color-mod
Referenced in:
3.
Representing sRGB Colors: the type
13.
Modifying Colors: the color-mod() function
(2)
(3)
(4)
(5)
(6)
(7)
(8)
13.2.
HSL/HWB Adjustment
13.3.
Tints and Shades: the tint and shade adjusters
Changes from Colors 3
#typedef-color-adjuster
Referenced in:
13.
Modifying Colors: the color-mod() function
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
13.1.
RGBA Adjustment
(2)
#hue-angle-is-null
Referenced in:
13.1.
RGBA Adjustment
13.2.
HSL/HWB Adjustment
(2)
(3)
13.4.
Color Blending: the blend and blenda adjusters
(2)
(3)
#luminance
Referenced in:
13.5.
Guaranteeing Adequate Contrast: the contrast adjuster
(2)
#contrast-ratio
Referenced in:
13.5.
Guaranteeing Adequate Contrast: the contrast adjuster
#propdef-opacity
Referenced in:
14.
Transparency: the opacity property
(2)
(3)
(4)
#propdef-color-adjust
Referenced in:
15.
Preserving Colors in Different-Capability Devices: the color-adjust property
(2)
(3)
(4)
#typedef-deprecated-system-color
Referenced in:
3.
Representing sRGB Colors: the type