Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
3608 lines (3038 sloc) 160 KB
<pre class=metadata>
Title: CSS Color Module Level 4
Status: ED
Work Status: Exploring
ED: https://drafts.csswg.org/css-color/
TR: http://www.w3.org/TR/css-color-4/
Previous Version: http://www.w3.org/TR/2016/WD-css-color-4-20160705/
Shortname: css-color
Group: csswg
Level: 4
Editor: Tab Atkins Jr., Google, http://xanthir.com/contact, w3cid 42199
Editor: Chris Lilley, W3C, chris@w3.org, w3cid 1438
Former Editor: L. David Baron, Mozilla https://www.mozilla.org/, https://dbaron.org/, w3cid 15393
Abstract: This specification describes CSS <<color>> values and properties for foreground color and group opacity.
Repository: w3c/csswg-drafts
Inline Github Issues: title
Ignored Terms: stacking context, double, octet
</pre>
<style>
table.named-color-table thead th { text-align:center; background:black; color:white; }
table.named-color-table th, table.named-color-table td { padding: 0 .25em; }
table.named-color-table td { text-align:center; text-transform:uppercase; }
table.named-color-table td:nth-child(-n+2) { border:1px solid black; }
table.named-color-table td:nth-child(n+4) { background: silver; }
.color-table {
background: #808080;
display: table;
display: flex;
flex-flow: row wrap;
justify-content: space-around;
}
.color-table table { padding:1em; margin:0; float:left; }
.color-table td, .color-table th { font-size:smaller; }
.color-table th { white-space: pre-line; }
.color-table td { background: currentcolor; }
.color-table .white { color: white; }
</style>
<h2 id="introduction">
Introduction</h2>
<em>This section is not normative.</em>
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 <<color>> value type.
It not only defines the color-related properties and values that
already exist in <a href="https://www.w3.org/TR/CSS1">CSS1</a>, <a
href="https://www.w3.org/TR/CSS2/">CSS2</a>,
and <a href="https://www.w3.org/TR/css-color-3/">CSS Color 3</a>,
but also defines new properties and values.
<h2 id="the-color-property">
Foreground Color: the 'color' property</h2>
<pre class=propdef>
Name: color
Value: <<color>>
Initial: ''black''
Applies to: all elements
Inherited: yes
Percentages: N/A
Computed value: computed color, see <a>resolving color values</a>
Animation type: by computed value type
</pre>
This property describes the foreground fill color of an element's text content.
In addition, it provides the value that ''<color>/currentcolor'' resolves to.
There are several different ways to syntactically specify a given color.
For example, to specify lime green:
<div class="example">
<pre class="lang-css">
em { color: lime; } /* color keyword */
em { color: rgb(0 255 0); } /* RGB range 0-255 */
em { color: rgb(0% 100% 0%); } /* RGB range 0%-100% */
</pre>
</div>
<dl>
<dt><<color>>
<dd>The <<color>> type is defined in a later section.
</dl>
<p class="note">
Note: In general, this property, including its alpha component, has
no effect on "color glyphs", such as emoji in some fonts, which are
colored by a built-in palette. Some colored fonts are able to refer
to the foreground color, such as palette entry ''0xFFFF'' in COLR
table of OpenType, and ''context-fill'' value in SVG-in-OpenType. In
that case, the foreground color is set by this property, identical
to how ''<color>/currentcolor'' value works.
<h2 id='color-type'>
Representing sRGB Colors: the <<color>> type</h2>
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,
<!-- that is unlikely to be the case in future, with half floats etc being added to the OM -->
CSS contains several syntaxes for <em>specifying</em> <<color>> 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 <<color>> is:
<pre class='prod'>
<dfn>&lt;color></dfn> = <<rgb()>> | <<rgba()>> | <<hsl()>> | <<hsla()>> |
<<hwb()>> | <<gray()>> | <<device-cmyk()>> |
<<hex-color>> | <<named-color>> | currentcolor |
<<deprecated-system-color>>
</pre>
Some operations work differently on <dfn export>achromatic</dfn> colors.
An <a>achromatic</a> color is a shade of gray:
in the sRGB colorspace,
a color is <a>achromatic</a> if the red, green, and blue channels are all the same value;
in the HSL colorspace,
a color is <a>achromatic</a> if the saturation is ''0%'';
in the HWB colorspace,
a color is <a>achromatic</a> if the sum of the whiteness and blackness is at least ''100%''.
For easy reference in other specifications,
<dfn export>opaque black</dfn> is an sRGB color
with the red, green, and blue components all at their minimum value,
and the alpha component at its maximum value
(the same color as produced by ''rgb(0 0 0 / 100%)'').
<dfn export>Transparent black</dfn> is the same color,
but with the alpha component at the minimum instead
(the same color as produced by ''rgb(0 0 0 / 0%)'').
<h3 id="notes">
Notes On Using Colors</h3>
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.
<ul>
<li><a href="https://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast-without-color"><em>1.4.1 Use of Color:</em> Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element</a>
</ul>
<h3 id='sRGB'>Colors in sRGB</h3>
Colors specified in CSS, HTML, and untagged images are in the sRGB color space ([[!SRGB]]).
<p class="note">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 <dfn export>untagged image</dfn> 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 ITU.
* At below 720p, it is Recommendation ITU-R BT.601 [[!ITU-R-BT.601]]
* At 720p, it is SMPTE ST 296 (same colorimetry as 709) [[!SMPTE296]]
* At 1080p, it is Recommendation ITU-R BT.709 [[!ITU-R-BT.709]]
Issue(287):
<h2 id='resolving-color-values'>
Resolving Color values</h2>
Various properties accept <<color>> values.
Unless an exception is explicitly defined,
all such properties must <dfn export lt="resolve color values|resolving color values">resolve color values</dfn> as defined below
to determine the <a>computed value</a> and the <a>used value</a> for <<color>>.
<ul>
<li>
If ''<color>/currentcolor'' is the specified value of the 'color' property,
it is treated as if the specified value was ''inherit''.
For all other properties that accept a <<color>>,
the computed value of the ''<color>/currentcolor'' keyword is ''<color>/currentcolor'',
and the used value of ''<color>/currentcolor'' is the same as
the used value of the 'color' property on the same element.
Note: This means that if the ''<color>/currentcolor'' value is inherited,
it’s inherited as a keyword,
not as the value of the 'color' property,
so descendants will use their own 'color' property to resolve it.
<li>
The computed value and used value of ''<color>/transparent'' is ''rgba(0, 0, 0, 0)''.
Issue: Gecko disagrees, and serializes any <<color>> with an alpha channel of 0 as transparent.
No other browser does that though.
<!-- needs WPT test -->
<li>
The computed value and used value of
<a>named colors</a> (including <<deprecated-system-color>> colors),
3 and 6 digits <a>hex colors</a>,
4 and 8 digits <a>hex colors</a> with an explicitly opaque alpha channel,
comma separated ''rgb()'' colors without an alpha channel,
comma separated ''rgba()'' colors with an explicitly opaque alpha channel,
comma separated ''hsl()'' colors without an alpha channel,
and comma separated ''hsla()'' colors with an explicitly opaque alpha channel,
is the equivalent numeric value in comma separated ''rgb()'' notation omitting the alpha value.
<li>
The computed value and used value of
4 and 8 digits <a>hex colors</a> with a non opaque alpha channel,
comma separated ''rgba()'' colors with a non opaque alpha channel,
and comma separated ''hsla()'' colors with a non opaque alpha channel,
is the equivalent numeric value in comma separated ''rgba()'' notation with the alpha value.
</ul>
<div class=issue>
The above defines values that are already implemented
based on the most interoperable behavior.
We still need to define how newer syntaxes work:
* comma-less with slash separated optional alpha variants of ''rgb()'', ''rgba()'', ''hsl()'', ''hsla()''
* comma separated with optional alpha variants of ''rgb()'', ''rgba()'', ''hsl()'', ''hsla()''
* ''device-cmyk()''
* ''hwb()''
* ''lab()'' and ''lch()''
* ''gray()''
* ''color()''
</div>
Issue: Define if changing the working color space should have any impact on the above.
Issue: Various parts of the spec define
the kind of clamping that should happen to the various numeric notations
when the numbers specified are out of range,
and do so with varrying precision, sometimes saying that this happens at computed value time,
sometimes not saying when it happens,
and sometimes not saying anything at all.
Maybe this should be consolidated here.
Any future specification extending the syntax of <<color>>
must define the how to <a>resolve color values</a> for the new extensions.
<h2 id='numeric-rgb'>
RGB Colors</h2>
There are several methods of directly specifying an sRGB color in terms of its RGBA channels.
<h3 id='rgb-functions'>
The RGB functions: ''rgb()'' and ''rgba()''</h3>
The ''rgb()'' function defines an sRGB color by specifying the red, green, and blue channels directly.
Its syntax is:
<pre class='prod'>
<dfn>rgb()</dfn> = rgb( <<percentage>>{3} [ / <<alpha-value>> ]? ) |
rgb( <<number>>{3} [ / <<alpha-value>> ]? )
<dfn>&lt;alpha-value></dfn> = <<number>> | <<percentage>>
</pre>
The first three arguments 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.
A <<number>> is equivalent to a <<percentage>>,
but with a different range:
''0'' 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.
Implementations should honor the precision of the channel as authored or calculated wherever possible.
If this is not possible, the channel should be rounded to the closest value at the highest precision used,
rounding up if two values are equally close.
The final argument, the <<alpha-value>>, specifies the alpha of the color.
If given as a <<number>>, the useful range of the value is ''0''
(representing a fully transparent color)
to ''1''
(representing a fully opaque color).
If given as a <<percentage>>, ''0%'' represents a fully transparent color,
while ''100%'' represents a fully opaque color.
If omitted, it defaults to ''100%''.
Values outside these ranges are not invalid,
but are clamped to the ranges defined here at computed-value time.
For legacy reasons,
''rgb()'' also supports an alternate syntax
that separates all of its arguments with commas:
<pre class='prod'>
rgb() = rgb( <<percentage>>#{3} , <<alpha-value>>? ) |
rgb( <<number>>#{3} , <<alpha-value>>? )
</pre>
Also for legacy reasons,
an <dfn>rgba()</dfn> function also exists,
with an identical grammar and behavior to ''rgb()''.
<h3 id='hex-notation'>
The RGB hexadecimal notations: ''#RRGGBB''</h3>
The CSS <dfn export>hex color</dfn> 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 <dfn>&lt;hex-color></dfn> is a <<hash-token>> 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:
<dl>
<dt>6 digits
<dd>
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.
<div class='example'>
In other words, ''#00ff00'' represents the same color as ''rgb(0 255 0)'' (a lime green).
</div>
<dt>8 digits
<dd>
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.
<div class='example'>
In other words, ''#0000ffcc'' represents the same color as ''rgb(0 0 100% / 80%)'' (a slightly-transparent blue).
</div>
<dt>3 digits
<dd>
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 ''0'' represents the minimum value
and ''f'' 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.
<div class='example'>
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.
</div>
<dt>4 digits
<dd>
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 ''0'' represents the minimum value
and ''f'' represents the maximum.
The next three digits represent the green, blue, and alpha channels, respectively.
</dl>
<h2 id='named-colors'>
Named Colors</h2>
In addition to the various numeric syntaxes for <<color>>s,
CSS defines a large set of <dfn id="named-color" lt="named color" export>named colors</dfn> that can be used instead,
so that common colors can be written and read more easily.
A <dfn>&lt;named-color></dfn> is written as an <<ident>>,
accepted anywhere a <<color>> is.
As usual for CSS-defined <<ident>>s,
all of these keywords are case-insensitive.
The names resolve to colors in sRGB.
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 ''<color>/currentcolor'',
are specially defined in their own sections.)
Note: The history of the X11 color system is interesting,
and was excellently summarized by
<a href="https://www.youtube.com/watch?v=HmStJQzclHc">Alex Sexton in his talk “Peachpuffs and Lemonchiffons”</a>.
The following table defines all of the opaque named colors,
by giving equivalent numeric specifications in the other color syntaxes.
<table class="named-color-table" dfn-type=value dfn-for="<color>">
<thead>
<tr>
<th style="background:black">Named
<th>Numeric
<th>Color&nbsp;name
<th>Hex&nbsp;rgb
<th>Decimal
<tbody>
<tr>
<td style="background:aliceblue">&nbsp;<td style="background:#f0f8ff">&nbsp;<th scope=row><dfn>aliceblue</dfn><td>#f0f8ff<td>240 248 255
<tr>
<td style="background:antiquewhite">&nbsp;<td style="background:#faebd7">&nbsp;<th scope=row><dfn>antiquewhite</dfn><td>#faebd7<td>250 235 215
<tr>
<td style="background:aqua">&nbsp;<td style="background:#00ffff">&nbsp;<th scope=row><dfn>aqua</dfn><td>#00ffff<td>0 255 255
<tr>
<td style="background:aquamarine">&nbsp;<td style="background:#7fffd4">&nbsp;<th scope=row><dfn>aquamarine</dfn><td>#7fffd4<td>127 255 212
<tr>
<td style="background:azure">&nbsp;<td style="background:#f0ffff">&nbsp;<th scope=row><dfn>azure</dfn><td>#f0ffff<td>240 255 255
<tr>
<td style="background:beige">&nbsp;<td style="background:#f5f5dc">&nbsp;<th scope=row><dfn>beige</dfn><td>#f5f5dc<td>245 245 220
<tr>
<td style="background:bisque">&nbsp;<td style="background:#ffe4c4">&nbsp;<th scope=row><dfn>bisque</dfn><td>#ffe4c4<td>255 228 196
<tr>
<td style="background:black">&nbsp;<td style="background:#000000">&nbsp;<th scope=row><dfn>black</dfn><td>#000000<td>0 0 0
<tr>
<td style="background:blanchedalmond">&nbsp;<td style="background:#ffebcd">&nbsp;<th scope=row><dfn>blanchedalmond</dfn><td>#ffebcd<td>255 235 205
<tr>
<td style="background:blue">&nbsp;<td style="background:#0000ff">&nbsp;<th scope=row><dfn>blue</dfn><td>#0000ff<td>0 0 255
<tr>
<td style="background:blueviolet">&nbsp;<td style="background:#8a2be2">&nbsp;<th scope=row><dfn>blueviolet</dfn><td>#8a2be2<td>138 43 226
<tr>
<td style="background:brown">&nbsp;<td style="background:#a52a2a">&nbsp;<th scope=row><dfn>brown</dfn><td>#a52a2a<td>165 42 42
<tr>
<td style="background:burlywood">&nbsp;<td style="background:#deb887">&nbsp;<th scope=row><dfn>burlywood</dfn><td>#deb887<td>222 184 135
<tr>
<td style="background:cadetblue">&nbsp;<td style="background:#5f9ea0">&nbsp;<th scope=row><dfn>cadetblue</dfn><td>#5f9ea0<td>95 158 160
<tr>
<td style="background:chartreuse">&nbsp;<td style="background:#7fff00">&nbsp;<th scope=row><dfn>chartreuse</dfn><td>#7fff00<td>127 255 0
<tr>
<td style="background:chocolate">&nbsp;<td style="background:#d2691e">&nbsp;<th scope=row><dfn>chocolate</dfn><td>#d2691e<td>210 105 30
<tr>
<td style="background:coral">&nbsp;<td style="background:#ff7f50">&nbsp;<th scope=row><dfn>coral</dfn><td>#ff7f50<td>255 127 80
<tr>
<td style="background:cornflowerblue">&nbsp;<td style="background:#6495ed">&nbsp;<th scope=row><dfn>cornflowerblue</dfn><td>#6495ed<td>100 149 237
<tr>
<td style="background:cornsilk">&nbsp;<td style="background:#fff8dc">&nbsp;<th scope=row><dfn>cornsilk</dfn><td>#fff8dc<td>255 248 220
<tr>
<td style="background:crimson">&nbsp;<td style="background:#dc143c">&nbsp;<th scope=row><dfn>crimson</dfn><td>#dc143c<td>220 20 60
<tr>
<td style="background:cyan">&nbsp;<td style="background:#00ffff">&nbsp;<th scope=row><dfn>cyan</dfn><td>#00ffff<td>0 255 255
<tr>
<td style="background:darkblue">&nbsp;<td style="background:#00008b">&nbsp;<th scope=row><dfn>darkblue</dfn><td>#00008b<td>0 0 139
<tr>
<td style="background:darkcyan">&nbsp;<td style="background:#008b8b">&nbsp;<th scope=row><dfn>darkcyan</dfn><td>#008b8b<td>0 139 139
<tr>
<td style="background:darkgoldenrod">&nbsp;<td style="background:#b8860b">&nbsp;<th scope=row><dfn>darkgoldenrod</dfn><td>#b8860b<td>184 134 11
<tr>
<td style="background:darkgray">&nbsp;<td style="background:#a9a9a9">&nbsp;<th scope=row><dfn>darkgray</dfn><td>#a9a9a9<td>169 169 169
<tr>
<td style="background:darkgreen">&nbsp;<td style="background:#006400">&nbsp;<th scope=row><dfn>darkgreen</dfn><td>#006400<td>0 100 0
<tr>
<td style="background:darkgrey">&nbsp;<td style="background:#a9a9a9">&nbsp;<th scope=row><dfn>darkgrey</dfn><td>#a9a9a9<td>169 169 169
<tr>
<td style="background:darkkhaki">&nbsp;<td style="background:#bdb76b">&nbsp;<th scope=row><dfn>darkkhaki</dfn><td>#bdb76b<td>189 183 107
<tr>
<td style="background:darkmagenta">&nbsp;<td style="background:#8b008b">&nbsp;<th scope=row><dfn>darkmagenta</dfn><td>#8b008b<td>139 0 139
<tr>
<td style="background:darkolivegreen">&nbsp;<td style="background:#556b2f">&nbsp;<th scope=row><dfn>darkolivegreen</dfn><td>#556b2f<td>85 107 47
<tr>
<td style="background:darkorange">&nbsp;<td style="background:#ff8c00">&nbsp;<th scope=row><dfn>darkorange</dfn><td>#ff8c00<td>255 140 0
<tr>
<td style="background:darkorchid">&nbsp;<td style="background:#9932cc">&nbsp;<th scope=row><dfn>darkorchid</dfn><td>#9932cc<td>153 50 204
<tr>
<td style="background:darkred">&nbsp;<td style="background:#8b0000">&nbsp;<th scope=row><dfn>darkred</dfn><td>#8b0000<td>139 0 0
<tr>
<td style="background:darksalmon">&nbsp;<td style="background:#e9967a">&nbsp;<th scope=row><dfn>darksalmon</dfn><td>#e9967a<td>233 150 122
<tr>
<td style="background:darkseagreen">&nbsp;<td style="background:#8fbc8f">&nbsp;<th scope=row><dfn>darkseagreen</dfn><td>#8fbc8f<td>143 188 143
<tr>
<td style="background:darkslateblue">&nbsp;<td style="background:#483d8b">&nbsp;<th scope=row><dfn>darkslateblue</dfn><td>#483d8b<td>72 61 139
<tr>
<td style="background:darkslategray">&nbsp;<td style="background:#2f4f4f">&nbsp;<th scope=row><dfn>darkslategray</dfn><td>#2f4f4f<td>47 79 79
<tr>
<td style="background:darkslategrey">&nbsp;<td style="background:#2f4f4f">&nbsp;<th scope=row><dfn>darkslategrey</dfn><td>#2f4f4f<td>47 79 79
<tr>
<td style="background:darkturquoise">&nbsp;<td style="background:#00ced1">&nbsp;<th scope=row><dfn>darkturquoise</dfn><td>#00ced1<td>0 206 209
<tr>
<td style="background:darkviolet">&nbsp;<td style="background:#9400d3">&nbsp;<th scope=row><dfn>darkviolet</dfn><td>#9400d3<td>148 0 211
<tr>
<td style="background:deeppink">&nbsp;<td style="background:#ff1493">&nbsp;<th scope=row><dfn>deeppink</dfn><td>#ff1493<td>255 20 147
<tr>
<td style="background:deepskyblue">&nbsp;<td style="background:#00bfff">&nbsp;<th scope=row><dfn>deepskyblue</dfn><td>#00bfff<td>0 191 255
<tr>
<td style="background:dimgray">&nbsp;<td style="background:#696969">&nbsp;<th scope=row><dfn>dimgray</dfn><td>#696969<td>105 105 105
<tr>
<td style="background:dimgrey">&nbsp;<td style="background:#696969">&nbsp;<th scope=row><dfn>dimgrey</dfn><td>#696969<td>105 105 105
<tr>
<td style="background:dodgerblue">&nbsp;<td style="background:#1e90ff">&nbsp;<th scope=row><dfn>dodgerblue</dfn><td>#1e90ff<td>30 144 255
<tr>
<td style="background:firebrick">&nbsp;<td style="background:#b22222">&nbsp;<th scope=row><dfn>firebrick</dfn><td>#b22222<td>178 34 34
<tr>
<td style="background:floralwhite">&nbsp;<td style="background:#fffaf0">&nbsp;<th scope=row><dfn>floralwhite</dfn><td>#fffaf0<td>255 250 240
<tr>
<td style="background:forestgreen">&nbsp;<td style="background:#228b22">&nbsp;<th scope=row><dfn>forestgreen</dfn><td>#228b22<td>34 139 34
<tr>
<td style="background:fuchsia">&nbsp;<td style="background:#ff00ff">&nbsp;<th scope=row><dfn>fuchsia</dfn><td>#ff00ff<td>255 0 255
<tr>
<td style="background:gainsboro">&nbsp;<td style="background:#dcdcdc">&nbsp;<th scope=row><dfn>gainsboro</dfn><td>#dcdcdc<td>220 220 220
<tr>
<td style="background:ghostwhite">&nbsp;<td style="background:#f8f8ff">&nbsp;<th scope=row><dfn>ghostwhite</dfn><td>#f8f8ff<td>248 248 255
<tr>
<td style="background:gold">&nbsp;<td style="background:#ffd700">&nbsp;<th scope=row><dfn>gold</dfn><td>#ffd700<td>255 215 0
<tr>
<td style="background:goldenrod">&nbsp;<td style="background:#daa520">&nbsp;<th scope=row><dfn>goldenrod</dfn><td>#daa520<td>218 165 32
<tr>
<td style="background:gray">&nbsp;<td style="background:#808080">&nbsp;<th scope=row><dfn>gray</dfn><td>#808080<td>128 128 128
<tr>
<td style="background:green">&nbsp;<td style="background:#008000">&nbsp;<th scope=row><dfn>green</dfn><td>#008000<td>0 128 0
<tr>
<td style="background:greenyellow">&nbsp;<td style="background:#adff2f">&nbsp;<th scope=row><dfn>greenyellow</dfn><td>#adff2f<td>173 255 47
<tr>
<td style="background:grey">&nbsp;<td style="background:#808080">&nbsp;<th scope=row><dfn>grey</dfn><td>#808080<td>128 128 128
<tr>
<td style="background:honeydew">&nbsp;<td style="background:#f0fff0">&nbsp;<th scope=row><dfn>honeydew</dfn><td>#f0fff0<td>240 255 240
<tr>
<td style="background:hotpink">&nbsp;<td style="background:#ff69b4">&nbsp;<th scope=row><dfn>hotpink</dfn><td>#ff69b4<td>255 105 180
<tr>
<td style="background:indianred">&nbsp;<td style="background:#cd5c5c">&nbsp;<th scope=row><dfn>indianred</dfn><td>#cd5c5c<td>205 92 92
<tr>
<td style="background:indigo">&nbsp;<td style="background:#4b0082">&nbsp;<th scope=row><dfn>indigo</dfn><td>#4b0082<td>75 0 130
<tr>
<td style="background:ivory">&nbsp;<td style="background:#fffff0">&nbsp;<th scope=row><dfn>ivory</dfn><td>#fffff0<td>255 255 240
<tr>
<td style="background:khaki">&nbsp;<td style="background:#f0e68c">&nbsp;<th scope=row><dfn>khaki</dfn><td>#f0e68c<td>240 230 140
<tr>
<td style="background:lavender">&nbsp;<td style="background:#e6e6fa">&nbsp;<th scope=row><dfn>lavender</dfn><td>#e6e6fa<td>230 230 250
<tr>
<td style="background:lavenderblush">&nbsp;<td style="background:#fff0f5">&nbsp;<th scope=row><dfn>lavenderblush</dfn><td>#fff0f5<td>255 240 245
<tr>
<td style="background:lawngreen">&nbsp;<td style="background:#7cfc00">&nbsp;<th scope=row><dfn>lawngreen</dfn><td>#7cfc00<td>124 252 0
<tr>
<td style="background:lemonchiffon">&nbsp;<td style="background:#fffacd">&nbsp;<th scope=row><dfn>lemonchiffon</dfn><td>#fffacd<td>255 250 205
<tr>
<td style="background:lightblue">&nbsp;<td style="background:#add8e6">&nbsp;<th scope=row><dfn>lightblue</dfn><td>#add8e6<td>173 216 230
<tr>
<td style="background:lightcoral">&nbsp;<td style="background:#f08080">&nbsp;<th scope=row><dfn>lightcoral</dfn><td>#f08080<td>240 128 128
<tr>
<td style="background:lightcyan">&nbsp;<td style="background:#e0ffff">&nbsp;<th scope=row><dfn>lightcyan</dfn><td>#e0ffff<td>224 255 255
<tr>
<td style="background:lightgoldenrodyellow">&nbsp;<td style="background:#fafad2">&nbsp;<th scope=row><dfn>lightgoldenrodyellow</dfn><td>#fafad2<td>250 250 210
<tr>
<td style="background:lightgray">&nbsp;<td style="background:#d3d3d3">&nbsp;<th scope=row><dfn>lightgray</dfn><td>#d3d3d3<td>211 211 211
<tr>
<td style="background:lightgreen">&nbsp;<td style="background:#90ee90">&nbsp;<th scope=row><dfn>lightgreen</dfn><td>#90ee90<td>144 238 144
<tr>
<td style="background:lightgrey">&nbsp;<td style="background:#d3d3d3">&nbsp;<th scope=row><dfn>lightgrey</dfn><td>#d3d3d3<td>211 211 211
<tr>
<td style="background:lightpink">&nbsp;<td style="background:#ffb6c1">&nbsp;<th scope=row><dfn>lightpink</dfn><td>#ffb6c1<td>255 182 193
<tr>
<td style="background:lightsalmon">&nbsp;<td style="background:#ffa07a">&nbsp;<th scope=row><dfn>lightsalmon</dfn><td>#ffa07a<td>255 160 122
<tr>
<td style="background:lightseagreen">&nbsp;<td style="background:#20b2aa">&nbsp;<th scope=row><dfn>lightseagreen</dfn><td>#20b2aa<td>32 178 170
<tr>
<td style="background:lightskyblue">&nbsp;<td style="background:#87cefa">&nbsp;<th scope=row><dfn>lightskyblue</dfn><td>#87cefa<td>135 206 250
<tr>
<td style="background:lightslategray">&nbsp;<td style="background:#778899">&nbsp;<th scope=row><dfn>lightslategray</dfn><td>#778899<td>119 136 153
<tr>
<td style="background:lightslategrey">&nbsp;<td style="background:#778899">&nbsp;<th scope=row><dfn>lightslategrey</dfn><td>#778899<td>119 136 153
<tr>
<td style="background:lightsteelblue">&nbsp;<td style="background:#b0c4de">&nbsp;<th scope=row><dfn>lightsteelblue</dfn><td>#b0c4de<td>176 196 222
<tr>
<td style="background:lightyellow">&nbsp;<td style="background:#ffffe0">&nbsp;<th scope=row><dfn>lightyellow</dfn><td>#ffffe0<td>255 255 224
<tr>
<td style="background:lime">&nbsp;<td style="background:#00ff00">&nbsp;<th scope=row><dfn>lime</dfn><td>#00ff00<td>0 255 0
<tr>
<td style="background:limegreen">&nbsp;<td style="background:#32cd32">&nbsp;<th scope=row><dfn>limegreen</dfn><td>#32cd32<td>50 205 50
<tr>
<td style="background:linen">&nbsp;<td style="background:#faf0e6">&nbsp;<th scope=row><dfn>linen</dfn><td>#faf0e6<td>250 240 230
<tr>
<td style="background:magenta">&nbsp;<td style="background:#ff00ff">&nbsp;<th scope=row><dfn>magenta</dfn><td>#ff00ff<td>255 0 255
<tr>
<td style="background:maroon">&nbsp;<td style="background:#800000">&nbsp;<th scope=row><dfn>maroon</dfn><td>#800000<td>128 0 0
<tr>
<td style="background:mediumaquamarine">&nbsp;<td style="background:#66cdaa">&nbsp;<th scope=row><dfn>mediumaquamarine</dfn><td>#66cdaa<td>102 205 170
<tr>
<td style="background:mediumblue">&nbsp;<td style="background:#0000cd">&nbsp;<th scope=row><dfn>mediumblue</dfn><td>#0000cd<td>0 0 205
<tr>
<td style="background:mediumorchid">&nbsp;<td style="background:#ba55d3">&nbsp;<th scope=row><dfn>mediumorchid</dfn><td>#ba55d3<td>186 85 211
<tr>
<td style="background:mediumpurple">&nbsp;<td style="background:#9370db">&nbsp;<th scope=row><dfn>mediumpurple</dfn><td>#9370db<td>147 112 219
<tr>
<td style="background:mediumseagreen">&nbsp;<td style="background:#3cb371">&nbsp;<th scope=row><dfn>mediumseagreen</dfn><td>#3cb371<td>60 179 113
<tr>
<td style="background:mediumslateblue">&nbsp;<td style="background:#7b68ee">&nbsp;<th scope=row><dfn>mediumslateblue</dfn><td>#7b68ee<td>123 104 238
<tr>
<td style="background:mediumspringgreen">&nbsp;<td style="background:#00fa9a">&nbsp;<th scope=row><dfn>mediumspringgreen</dfn><td>#00fa9a<td>0 250 154
<tr>
<td style="background:mediumturquoise">&nbsp;<td style="background:#48d1cc">&nbsp;<th scope=row><dfn>mediumturquoise</dfn><td>#48d1cc<td>72 209 204
<tr>
<td style="background:mediumvioletred">&nbsp;<td style="background:#c71585">&nbsp;<th scope=row><dfn>mediumvioletred</dfn><td>#c71585<td>199 21 133
<tr>
<td style="background:midnightblue">&nbsp;<td style="background:#191970">&nbsp;<th scope=row><dfn>midnightblue</dfn><td>#191970<td>25 25 112
<tr>
<td style="background:mintcream">&nbsp;<td style="background:#f5fffa">&nbsp;<th scope=row><dfn>mintcream</dfn><td>#f5fffa<td>245 255 250
<tr>
<td style="background:mistyrose">&nbsp;<td style="background:#ffe4e1">&nbsp;<th scope=row><dfn>mistyrose</dfn><td>#ffe4e1<td>255 228 225
<tr>
<td style="background:moccasin">&nbsp;<td style="background:#ffe4b5">&nbsp;<th scope=row><dfn>moccasin</dfn><td>#ffe4b5<td>255 228 181
<tr>
<td style="background:navajowhite">&nbsp;<td style="background:#ffdead">&nbsp;<th scope=row><dfn>navajowhite</dfn><td>#ffdead<td>255 222 173
<tr>
<td style="background:navy">&nbsp;<td style="background:#000080">&nbsp;<th scope=row><dfn>navy</dfn><td>#000080<td>0 0 128
<tr>
<td style="background:oldlace">&nbsp;<td style="background:#fdf5e6">&nbsp;<th scope=row><dfn>oldlace</dfn><td>#fdf5e6<td>253 245 230
<tr>
<td style="background:olive">&nbsp;<td style="background:#808000">&nbsp;<th scope=row><dfn>olive</dfn><td>#808000<td>128 128 0
<tr>
<td style="background:olivedrab">&nbsp;<td style="background:#6b8e23">&nbsp;<th scope=row><dfn>olivedrab</dfn><td>#6b8e23<td>107 142 35
<tr>
<td style="background:orange">&nbsp;<td style="background:#ffa500">&nbsp;<th scope=row><dfn>orange</dfn><td>#ffa500<td>255 165 0
<tr>
<td style="background:orangered">&nbsp;<td style="background:#ff4500">&nbsp;<th scope=row><dfn>orangered</dfn><td>#ff4500<td>255 69 0
<tr>
<td style="background:orchid">&nbsp;<td style="background:#da70d6">&nbsp;<th scope=row><dfn>orchid</dfn><td>#da70d6<td>218 112 214
<tr>
<td style="background:palegoldenrod">&nbsp;<td style="background:#eee8aa">&nbsp;<th scope=row><dfn>palegoldenrod</dfn><td>#eee8aa<td>238 232 170
<tr>
<td style="background:palegreen">&nbsp;<td style="background:#98fb98">&nbsp;<th scope=row><dfn>palegreen</dfn><td>#98fb98<td>152 251 152
<tr>
<td style="background:paleturquoise">&nbsp;<td style="background:#afeeee">&nbsp;<th scope=row><dfn>paleturquoise</dfn><td>#afeeee<td>175 238 238
<tr>
<td style="background:palevioletred">&nbsp;<td style="background:#db7093">&nbsp;<th scope=row><dfn>palevioletred</dfn><td>#db7093<td>219 112 147
<tr>
<td style="background:papayawhip">&nbsp;<td style="background:#ffefd5">&nbsp;<th scope=row><dfn>papayawhip</dfn><td>#ffefd5<td>255 239 213
<tr>
<td style="background:peachpuff">&nbsp;<td style="background:#ffdab9">&nbsp;<th scope=row><dfn>peachpuff</dfn><td>#ffdab9<td>255 218 185
<tr>
<td style="background:peru">&nbsp;<td style="background:#cd853f">&nbsp;<th scope=row><dfn>peru</dfn><td>#cd853f<td>205 133 63
<tr>
<td style="background:pink">&nbsp;<td style="background:#ffc0cb">&nbsp;<th scope=row><dfn>pink</dfn><td>#ffc0cb<td>255 192 203
<tr>
<td style="background:plum">&nbsp;<td style="background:#dda0dd">&nbsp;<th scope=row><dfn>plum</dfn><td>#dda0dd<td>221 160 221
<tr>
<td style="background:powderblue">&nbsp;<td style="background:#b0e0e6">&nbsp;<th scope=row><dfn>powderblue</dfn><td>#b0e0e6<td>176 224 230
<tr>
<td style="background:purple">&nbsp;<td style="background:#800080">&nbsp;<th scope=row><dfn>purple</dfn><td>#800080<td>128 0 128
<tr>
<td style="background:rebeccapurple">&nbsp;<td style="background:#663399">&nbsp;<th scope=row><dfn>rebeccapurple</dfn><td>#663399<td>102 51 153
<tr>
<td style="background:red">&nbsp;<td style="background:#ff0000">&nbsp;<th scope=row><dfn>red</dfn><td>#ff0000<td>255 0 0
<tr>
<td style="background:rosybrown">&nbsp;<td style="background:#bc8f8f">&nbsp;<th scope=row><dfn>rosybrown</dfn><td>#bc8f8f<td>188 143 143
<tr>
<td style="background:royalblue">&nbsp;<td style="background:#4169e1">&nbsp;<th scope=row><dfn>royalblue</dfn><td>#4169e1<td>65 105 225
<tr>
<td style="background:saddlebrown">&nbsp;<td style="background:#8b4513">&nbsp;<th scope=row><dfn>saddlebrown</dfn><td>#8b4513<td>139 69 19
<tr>
<td style="background:salmon">&nbsp;<td style="background:#fa8072">&nbsp;<th scope=row><dfn>salmon</dfn><td>#fa8072<td>250 128 114
<tr>
<td style="background:sandybrown">&nbsp;<td style="background:#f4a460">&nbsp;<th scope=row><dfn>sandybrown</dfn><td>#f4a460<td>244 164 96
<tr>
<td style="background:seagreen">&nbsp;<td style="background:#2e8b57">&nbsp;<th scope=row><dfn>seagreen</dfn><td>#2e8b57<td>46 139 87
<tr>
<td style="background:seashell">&nbsp;<td style="background:#fff5ee">&nbsp;<th scope=row><dfn>seashell</dfn><td>#fff5ee<td>255 245 238
<tr>
<td style="background:sienna">&nbsp;<td style="background:#a0522d">&nbsp;<th scope=row><dfn>sienna</dfn><td>#a0522d<td>160 82 45
<tr>
<td style="background:silver">&nbsp;<td style="background:#c0c0c0">&nbsp;<th scope=row><dfn>silver</dfn><td>#c0c0c0<td>192 192 192
<tr>
<td style="background:skyblue">&nbsp;<td style="background:#87ceeb">&nbsp;<th scope=row><dfn>skyblue</dfn><td>#87ceeb<td>135 206 235
<tr>
<td style="background:slateblue">&nbsp;<td style="background:#6a5acd">&nbsp;<th scope=row><dfn>slateblue</dfn><td>#6a5acd<td>106 90 205
<tr>
<td style="background:slategray">&nbsp;<td style="background:#708090">&nbsp;<th scope=row><dfn>slategray</dfn><td>#708090<td>112 128 144
<tr>
<td style="background:slategrey">&nbsp;<td style="background:#708090">&nbsp;<th scope=row><dfn>slategrey</dfn><td>#708090<td>112 128 144
<tr>
<td style="background:snow">&nbsp;<td style="background:#fffafa">&nbsp;<th scope=row><dfn>snow</dfn><td>#fffafa<td>255 250 250
<tr>
<td style="background:springgreen">&nbsp;<td style="background:#00ff7f">&nbsp;<th scope=row><dfn>springgreen</dfn><td>#00ff7f<td>0 255 127
<tr>
<td style="background:steelblue">&nbsp;<td style="background:#4682b4">&nbsp;<th scope=row><dfn>steelblue</dfn><td>#4682b4<td>70 130 180
<tr>
<td style="background:tan">&nbsp;<td style="background:#d2b48c">&nbsp;<th scope=row><dfn>tan</dfn><td>#d2b48c<td>210 180 140
<tr>
<td style="background:teal">&nbsp;<td style="background:#008080">&nbsp;<th scope=row><dfn>teal</dfn><td>#008080<td>0 128 128
<tr>
<td style="background:thistle">&nbsp;<td style="background:#d8bfd8">&nbsp;<th scope=row><dfn>thistle</dfn><td>#d8bfd8<td>216 191 216
<tr>
<td style="background:tomato">&nbsp;<td style="background:#ff6347">&nbsp;<th scope=row><dfn>tomato</dfn><td>#ff6347<td>255 99 71
<tr>
<td style="background:turquoise">&nbsp;<td style="background:#40e0d0">&nbsp;<th scope=row><dfn>turquoise</dfn><td>#40e0d0<td>64 224 208
<tr>
<td style="background:violet">&nbsp;<td style="background:#ee82ee">&nbsp;<th scope=row><dfn>violet</dfn><td>#ee82ee<td>238 130 238
<tr>
<td style="background:wheat">&nbsp;<td style="background:#f5deb3">&nbsp;<th scope=row><dfn>wheat</dfn><td>#f5deb3<td>245 222 179
<tr>
<td style="background:white">&nbsp;<td style="background:#ffffff">&nbsp;<th scope=row><dfn>white</dfn><td>#ffffff<td>255 255 255
<tr>
<td style="background:whitesmoke">&nbsp;<td style="background:#f5f5f5">&nbsp;<th scope=row><dfn>whitesmoke</dfn><td>#f5f5f5<td>245 245 245
<tr>
<td style="background:yellow">&nbsp;<td style="background:#ffff00">&nbsp;<th scope=row><dfn>yellow</dfn><td>#ffff00<td>255 255 0
<tr>
<td style="background:yellowgreen">&nbsp;<td style="background:#9acd32">&nbsp;<th scope=row><dfn>yellowgreen</dfn><td>#9acd32<td>154 205 50
</table>
Note: this list of colors and their definitions is a superset of the list of <a href="https://www.w3.org/TR/SVG/types.html#ColorKeywords">named colors defined by SVG 1.1</a>.
For historical reasons, this is also referred to as the X11 color set.
<h3 id='transparent-color'>
The ''transparent'' keyword</h3>
The keyword <dfn value for="<color>">transparent</dfn> specifies a <a>transparent black</a>.
It is a type of <<named-color>>.
<h3 id='currentcolor-color'>
The ''<color>/currentcolor'' keyword</h3>
The keyword <dfn value for="<color>">currentcolor</dfn> represents value of the 'color' property on the same element.
Its <a>used values</a> is determined by <a>resolving color values</a>.
<div class='example'>
Here's a simple example showing how to use the ''<color>/currentcolor'' keyword:
<pre class="lang-css">
.foo {
color: red;
background-color: currentcolor;
}
</pre>
This is equivalent to writing:
<pre class="lang-css">
.foo {
color: red;
background-color: red;
}
</pre>
</div>
<div class='example'>
For example, the 'text-emphasis-color' property [[CSS3-TEXT-DECOR]],
whose initial value is ''<color>/currentcolor'',
by default matches the text color
even as the 'color' property changes across elements.
<pre class="language-markup">
&lt;p>&lt;em>Some &lt;strong>really&lt;/strong> emphasized text.&lt;/em>
&lt;style>
p { color: black; }
em { text-emphasis: dot; }
strong { color: red; }
&lt;/style>
</pre>
In the above example, the emphasis marks would be black over the text "Some" and "emphasized text",
but red over the text "really".
</div>
Note: Multi-word keywords in CSS usually separate their component words with hyphens.
''<color>/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.
<h2 id='the-hsl-notation'>
HSL Colors: ''hsl()'' and ''hsla()'' functions</h2>
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:
<pre class='prod'>
<dfn>hsl()</dfn> = hsl( <<hue>> <<percentage>> <<percentage>> [ / <<alpha-value>> ]? )
<dfn>&lt;hue></dfn> = <<number>> | <<angle>>
</pre>
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 are less than ''0%''
or greater than ''100%'',
they are clipped to those values before being converted to an RGB color.
The final argument specifies the alpha channel of the color.
It's interpreted identically to the fourth argument of the ''rgb()'' function.
If omitted, it defaults to ''100%''.
<div class='example'>
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(0deg 100% 50%)''.
</div>
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).
HSL colors resolve to sRGB.
<div class='example'>
For example, the following colors can all be generated off of the basic "green" hue,
just by varying the other two arguments:
<pre>
hsl(120deg 100% 50%) <span style="color:black; background:hsl(120,100%,50%);">lime green</span>
hsl(120deg 100% 25%) <span style="color:white; background:hsl(120,100%,25%);">dark green</span>
hsl(120deg 100% 75%) <span style="color:black; background:hsl(120,100%,75%);">light green</span>
hsl(120deg 75% 85%) <span style="color:black; background:hsl(120,75%,85%);">pastel green</span>
</pre>
</div>
For legacy reasons,
''hsl()'' also supports an alternate syntax
that separates all of its arguments with commas:
<pre class='prod'>
hsl() = hsl( <<hue>>, <<percentage>>, <<percentage>>, <<alpha-value>>? )
</pre>
Also for legacy reasons,
an <dfn>hsla()</dfn> function also exists,
with an identical grammar and behavior to ''hsl()''.
<h3 id='hsl-to-rgb'>
Converting HSL colors to sRGB colors</h3>
Converting an HSL color to sRGB 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].
<pre class='lang-javascript'>
function hslToRgb(hue, sat, light) {
if( light &lt;= .5 ) {
var t2 = light * (sat + 1);
} else {
var t2 = light + sat - (light * sat);
}
var t1 = light * 2 - t2;
var r = hueToRgb(t1, t2, hue + 2);
var g = hueToRgb(t1, t2, hue);
var b = hueToRgb(t1, t2, hue - 2);
return [r,g,b];
}
function hueToRgb(t1, t2, hue) {
if(hue &lt; 0) hue += 6;
if(hue >= 6) hue -= 6;
if(hue &lt; 1) return (t2 - t1) * hue + t1;
else if(hue &lt; 3) return t2;
else if(hue &lt; 4) return (t2 - t1) * (4 - hue) + t1;
else return t1;
}
</pre>
<h3 id='hsl-examples'>
Examples of HSL colors</h3>
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.
<div class="issue">The conversions in the table below are known to contain errors. They are copied from CSS Color 3, which aso had the same errors. Those colors were supposedly computed by a program in ABC. A future spec will correctly compute those colors. Meanwhile, please note that thses conversions are non-normative examples.</div>
<div style="overflow: hidden;" class="color-table">
<table>
<tr>
<th><th colspan=5>0° Reds
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#FFBFBF"><td style="color:#F7C7C7"><td style="color:#EFCFCF"><td style="color:#E7D7D7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#FF8080"><td style="color:#EF8F8F"><td style="color:#DF9F9F"><td style="color:#CFAFAF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#FF4040"><td style="color:#E75858"><td style="color:#CF7070"><td style="color:#B78787"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#FF0000"><td style="color:#DF2020"><td style="color:#BF4040"><td style="color:#9F6060"><td style="color:#808080">
<tr><th>38%
<td style="color:#BF0000"><td style="color:#A71818"><td style="color:#8F3030"><td style="color:#784848"><td style="color:#606060">
<tr><th>25%
<td style="color:#800000"><td style="color:#701010"><td style="color:#602020"><td style="color:#503030"><td style="color:#404040">
<tr><th>13%
<td style="color:#400000"><td style="color:#380808"><td style="color:#301010"><td style="color:#281818"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>30° Red-Yellows (=Oranges)
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#FFDFBF"><td style="color:#F7DFC7"><td style="color:#EFDFCF"><td style="color:#E7DFD7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#FFBF80"><td style="color:#EFBF8F"><td style="color:#DFBF9F"><td style="color:#CFBFAF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#FF9F40"><td style="color:#E79F58"><td style="color:#CF9F70"><td style="color:#B79F87"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#FF8000"><td style="color:#DF8020"><td style="color:#BF8040"><td style="color:#9F8060"><td style="color:#808080">
<tr><th>38%
<td style="color:#BF6000"><td style="color:#A76018"><td style="color:#8F6030"><td style="color:#786048"><td style="color:#606060">
<tr><th>25%
<td style="color:#804000"><td style="color:#704010"><td style="color:#604020"><td style="color:#504030"><td style="color:#404040">
<tr><th>13%
<td style="color:#402000"><td style="color:#382008"><td style="color:#302010"><td style="color:#282018"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>60° Yellows
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#FFFFBF"><td style="color:#F7F7C7"><td style="color:#EFEFCF"><td style="color:#E7E7D7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#FFFF80"><td style="color:#EFEF8F"><td style="color:#DFDF9F"><td style="color:#CFCFAF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#FFFF40"><td style="color:#E7E758"><td style="color:#CFCF70"><td style="color:#B7B787"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#FFFF00"><td style="color:#DFDF20"><td style="color:#BFBF40"><td style="color:#9F9F60"><td style="color:#808080">
<tr><th>38%
<td style="color:#BFBF00"><td style="color:#A7A718"><td style="color:#8F8F30"><td style="color:#787848"><td style="color:#606060">
<tr><th>25%
<td style="color:#808000"><td style="color:#707010"><td style="color:#606020"><td style="color:#505030"><td style="color:#404040">
<tr><th>13%
<td style="color:#404000"><td style="color:#383808"><td style="color:#303010"><td style="color:#282818"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>90° Yellow-Greens
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#DFFFBF"><td style="color:#DFF7C7"><td style="color:#DFEFCF"><td style="color:#DFE7D7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#BFFF80"><td style="color:#BFEF8F"><td style="color:#BFDF9F"><td style="color:#BFCFAF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#9FFF40"><td style="color:#9FE758"><td style="color:#9FCF70"><td style="color:#9FB787"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#80FF00"><td style="color:#80DF20"><td style="color:#80BF40"><td style="color:#809F60"><td style="color:#808080">
<tr><th>38%
<td style="color:#60BF00"><td style="color:#60A718"><td style="color:#608F30"><td style="color:#607848"><td style="color:#606060">
<tr><th>25%
<td style="color:#408000"><td style="color:#407010"><td style="color:#406020"><td style="color:#405030"><td style="color:#404040">
<tr><th>13%
<td style="color:#204000"><td style="color:#203808"><td style="color:#203010"><td style="color:#202818"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>120° Greens
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#BFFFBF"><td style="color:#C7F7C7"><td style="color:#CFEFCF"><td style="color:#D7E7D7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#80FF80"><td style="color:#8FEF8F"><td style="color:#9FDF9F"><td style="color:#AFCFAF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#40FF40"><td style="color:#58E758"><td style="color:#70CF70"><td style="color:#87B787"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#00FF00"><td style="color:#20DF20"><td style="color:#40BF40"><td style="color:#609F60"><td style="color:#808080">
<tr><th>38%
<td style="color:#00BF00"><td style="color:#18A718"><td style="color:#308F30"><td style="color:#487848"><td style="color:#606060">
<tr><th>25%
<td style="color:#008000"><td style="color:#107010"><td style="color:#206020"><td style="color:#305030"><td style="color:#404040">
<tr><th>13%
<td style="color:#004000"><td style="color:#083808"><td style="color:#103010"><td style="color:#182818"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>150° Green-Cyans
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#BFFFDF"><td style="color:#C7F7DF"><td style="color:#CFEFDF"><td style="color:#D7E7DF"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#80FFBF"><td style="color:#8FEFBF"><td style="color:#9FDFBF"><td style="color:#AFCFBF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#40FF9F"><td style="color:#58E79F"><td style="color:#70CF9F"><td style="color:#87B79F"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#00FF80"><td style="color:#20DF80"><td style="color:#40BF80"><td style="color:#609F80"><td style="color:#808080">
<tr><th>38%
<td style="color:#00BF60"><td style="color:#18A760"><td style="color:#308F60"><td style="color:#487860"><td style="color:#606060">
<tr><th>25%
<td style="color:#008040"><td style="color:#107040"><td style="color:#206040"><td style="color:#305040"><td style="color:#404040">
<tr><th>13%
<td style="color:#004020"><td style="color:#083820"><td style="color:#103020"><td style="color:#182820"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>180° Cyans
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#BFFFFF"><td style="color:#C7F7F7"><td style="color:#CFEFEF"><td style="color:#D7E7E7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#80FFFF"><td style="color:#8FEFEF"><td style="color:#9FDFDF"><td style="color:#AFCFCF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#40FFFF"><td style="color:#58E7E7"><td style="color:#70CFCF"><td style="color:#87B7B7"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#00FFFF"><td style="color:#20DFDF"><td style="color:#40BFBF"><td style="color:#609F9F"><td style="color:#808080">
<tr><th>38%
<td style="color:#00BFBF"><td style="color:#18A7A7"><td style="color:#308F8F"><td style="color:#487878"><td style="color:#606060">
<tr><th>25%
<td style="color:#008080"><td style="color:#107070"><td style="color:#206060"><td style="color:#305050"><td style="color:#404040">
<tr><th>13%
<td style="color:#004040"><td style="color:#083838"><td style="color:#103030"><td style="color:#182828"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>210° Cyan-Blues
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#BFDFFF"><td style="color:#C7DFF7"><td style="color:#CFDFEF"><td style="color:#D7DFE7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#80BFFF"><td style="color:#8FBFEF"><td style="color:#9FBFDF"><td style="color:#AFBFCF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#409FFF"><td style="color:#589FE7"><td style="color:#709FCF"><td style="color:#879FB7"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#0080FF"><td style="color:#2080DF"><td style="color:#4080BF"><td style="color:#60809F"><td style="color:#808080">
<tr><th>38%
<td style="color:#0060BF"><td style="color:#1860A7"><td style="color:#30608F"><td style="color:#486078"><td style="color:#606060">
<tr><th>25%
<td style="color:#004080"><td style="color:#104070"><td style="color:#204060"><td style="color:#304050"><td style="color:#404040">
<tr><th>13%
<td style="color:#002040"><td style="color:#082038"><td style="color:#102030"><td style="color:#182028"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>240° Blues
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#BFBFFF"><td style="color:#C7C7F7"><td style="color:#CFCFEF"><td style="color:#D7D7E7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#8080FF"><td style="color:#8F8FEF"><td style="color:#9F9FDF"><td style="color:#AFAFCF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#4040FF"><td style="color:#5858E7"><td style="color:#7070CF"><td style="color:#8787B7"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#0000FF"><td style="color:#2020DF"><td style="color:#4040BF"><td style="color:#60609F"><td style="color:#808080">
<tr><th>38%
<td style="color:#0000BF"><td style="color:#1818A7"><td style="color:#30308F"><td style="color:#484878"><td style="color:#606060">
<tr><th>25%
<td style="color:#000080"><td style="color:#101070"><td style="color:#202060"><td style="color:#303050"><td style="color:#404040">
<tr><th>13%
<td style="color:#000040"><td style="color:#080838"><td style="color:#101030"><td style="color:#181828"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>270° Blue-Magentas
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#DFBFFF"><td style="color:#DFC7F7"><td style="color:#DFCFEF"><td style="color:#DFD7E7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#BF80FF"><td style="color:#BF8FEF"><td style="color:#BF9FDF"><td style="color:#BFAFCF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#9F40FF"><td style="color:#9F58E7"><td style="color:#9F70CF"><td style="color:#9F87B7"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#8000FF"><td style="color:#8020DF"><td style="color:#8040BF"><td style="color:#80609F"><td style="color:#808080">
<tr><th>38%
<td style="color:#6000BF"><td style="color:#6018A7"><td style="color:#60308F"><td style="color:#604878"><td style="color:#606060">
<tr><th>25%
<td style="color:#400080"><td style="color:#401070"><td style="color:#402060"><td style="color:#403050"><td style="color:#404040">
<tr><th>13%
<td style="color:#200040"><td style="color:#200838"><td style="color:#201030"><td style="color:#201828"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>300° Magentas
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#FFBFFF"><td style="color:#F7C7F7"><td style="color:#EFCFEF"><td style="color:#E7D7E7"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#FF80FF"><td style="color:#EF8FEF"><td style="color:#DF9FDF"><td style="color:#CFAFCF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#FF40FF"><td style="color:#E758E7"><td style="color:#CF70CF"><td style="color:#B787B7"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#FF00FF"><td style="color:#DF20DF"><td style="color:#BF40BF"><td style="color:#9F609F"><td style="color:#808080">
<tr><th>38%
<td style="color:#BF00BF"><td style="color:#A718A7"><td style="color:#8F308F"><td style="color:#784878"><td style="color:#606060">
<tr><th>25%
<td style="color:#800080"><td style="color:#701070"><td style="color:#602060"><td style="color:#503050"><td style="color:#404040">
<tr><th>13%
<td style="color:#400040"><td style="color:#380838"><td style="color:#301030"><td style="color:#281828"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
<table>
<tr>
<th><th colspan=5>330° Magenta-Reds
<tr>
<th><th colspan=5>Saturation
<tr>
<th><th>100%<th>75%<th>50%<th>25%<th>0%
<tr><th>100%
<td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF"><td style="color:#FFFFFF">
<tr><th>88%
<td style="color:#FFBFDF"><td style="color:#F7C7DF"><td style="color:#EFCFDF"><td style="color:#E7D7DF"><td style="color:#DFDFDF">
<tr><th>75%
<td style="color:#FF80BF"><td style="color:#EF8FBF"><td style="color:#DF9FBF"><td style="color:#CFAFBF"><td style="color:#BFBFBF">
<tr><th>63%
<td style="color:#FF409F"><td style="color:#E7589F"><td style="color:#CF709F"><td style="color:#B7879F"><td style="color:#9F9F9F">
<tr><th>50%
<td style="color:#FF0080"><td style="color:#DF2080"><td style="color:#BF4080"><td style="color:#9F6080"><td style="color:#808080">
<tr><th>38%
<td style="color:#BF0060"><td style="color:#A71860"><td style="color:#8F3060"><td style="color:#784860"><td style="color:#606060">
<tr><th>25%
<td style="color:#800040"><td style="color:#701040"><td style="color:#602040"><td style="color:#503040"><td style="color:#404040">
<tr><th>13%
<td style="color:#400020"><td style="color:#380820"><td style="color:#301020"><td style="color:#281820"><td style="color:#202020">
<tr><th>0%
<td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000"><td style="color:#000000">
</table>
</div>
<h2 id='the-hwb-notation'>
HWB Colors: ''hwb()'' function</h2>
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.
HWB colors resolve to sRGB.
<figure>
<img src="images/color-picker.png">
<figcaption>
This is a screenshot of Chrome's color picker,
shown when a user activates an <code class='lang-markup'>&lt;input type="color"></code>.
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.
</figcaption>
</figure>
The syntax of the ''hwb()'' function is:
<pre class='prod'>
<dfn>hwb()</dfn> = hwb( <<hue>> <<percentage>> <<percentage>> [ / <<alpha-value>> ]? )
</pre>
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 ''rgb()'' 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 <a>achromatic</a> color,
or some shade of gray,
without any hint of the chosen hue.
<h3 id='hwb-to-rgb'>
Converting HWB colors to sRGB colors</h3>
Converting an HWB color to sRGB 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].
<pre class="lang-javascript">
function hwbToRgb(hue, white, black) {
var rgb = hslToRgb(hue, 1, .5);
for(var i = 0; i &lt; 3; i++) {
rgb[i] *= (1 - white - black);
rgb[i] += white;
}
return rgb;
}
</pre>
<h3 id='hwb-examples'>
Examples of HWB Colors</h3>
<div class='color-table'>
<table>
<tr>
<th><th colspan="6">0° Reds
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#ff0000"><td style="color:#cc0000"><td style="color:#990000"><td style="color:#660000"><td style="color:#330000"><td style="color:#000000">
<tr>
<th>20%<td style="color:#ff3333"><td style="color:#cc3333"><td style="color:#993333"><td style="color:#663333"><td style="color:#333333"><td style="color:#2a2b2b">
<tr>
<th>40%<td style="color:#ff6666"><td style="color:#cc6666"><td style="color:#996666"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#ff9999"><td style="color:#cc9999"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ffcccc"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d4d5d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">30° Red-Yellows (Oranges)
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#ff8000"><td style="color:#cc6600"><td style="color:#994d00"><td style="color:#663300"><td style="color:#331900"><td style="color:#000000">
<tr>
<th>20%<td style="color:#ff9933"><td style="color:#cc8033"><td style="color:#996633"><td style="color:#664d33"><td style="color:#333333"><td style="color:#2a2a2b">
<tr>
<th>40%<td style="color:#ffb366"><td style="color:#cc9966"><td style="color:#998066"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#ffcc99"><td style="color:#ccb399"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ffe6cc"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d4d5d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">60° Yellows
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#ffff00"><td style="color:#cccc00"><td style="color:#999900"><td style="color:#666600"><td style="color:#333300"><td style="color:#000000">
<tr>
<th>20%<td style="color:#ffff33"><td style="color:#cccc33"><td style="color:#999933"><td style="color:#666633"><td style="color:#333333"><td style="color:#2a2a2b">
<tr>
<th>40%<td style="color:#ffff66"><td style="color:#cccc66"><td style="color:#999966"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#ffff99"><td style="color:#cccc99"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ffffcc"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d5d4d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">90° Yellow-Greens
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#80ff00"><td style="color:#66cc00"><td style="color:#4d9900"><td style="color:#336600"><td style="color:#1a3300"><td style="color:#000000">
<tr>
<th>20%<td style="color:#99ff33"><td style="color:#80cc33"><td style="color:#669933"><td style="color:#4d6633"><td style="color:#333333"><td style="color:#2a2a2b">
<tr>
<th>40%<td style="color:#b3ff66"><td style="color:#99cc66"><td style="color:#809966"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#ccff99"><td style="color:#b3cc99"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#e6ffcc"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d5d4d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">120° Greens
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#00ff00"><td style="color:#00cc00"><td style="color:#009900"><td style="color:#006600"><td style="color:#003300"><td style="color:#000000">
<tr>
<th>20%<td style="color:#33ff33"><td style="color:#33cc33"><td style="color:#339933"><td style="color:#336633"><td style="color:#333333"><td style="color:#2b2a2b">
<tr>
<th>40%<td style="color:#66ff66"><td style="color:#66cc66"><td style="color:#669966"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#99ff99"><td style="color:#99cc99"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ccffcc"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d5d4d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">150° Green-Cyans
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#00ff7f"><td style="color:#00cc66"><td style="color:#00994c"><td style="color:#006633"><td style="color:#003319"><td style="color:#000000">
<tr>
<th>20%<td style="color:#33ff99"><td style="color:#33cc7f"><td style="color:#339966"><td style="color:#33664c"><td style="color:#333333"><td style="color:#2b2a2a">
<tr>
<th>40%<td style="color:#66ffb2"><td style="color:#66cc99"><td style="color:#66997f"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#99ffcc"><td style="color:#99ccb3"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ccffe5"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d5d4d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">180° Cyans
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#00ffff"><td style="color:#00cccc"><td style="color:#009999"><td style="color:#006666"><td style="color:#003333"><td style="color:#000000">
<tr>
<th>20%<td style="color:#33ffff"><td style="color:#33cccc"><td style="color:#339999"><td style="color:#336666"><td style="color:#333333"><td style="color:#2b2a2a">
<tr>
<th>40%<td style="color:#66ffff"><td style="color:#66cccc"><td style="color:#669999"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#99ffff"><td style="color:#99cccc"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ccffff"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d5d5d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">210° Cyan-Blues
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#007fff"><td style="color:#0066cc"><td style="color:#004c99"><td style="color:#003366"><td style="color:#001933"><td style="color:#000000">
<tr>
<th>20%<td style="color:#3399ff"><td style="color:#337fcc"><td style="color:#336699"><td style="color:#334c66"><td style="color:#333333"><td style="color:#2b2a2a">
<tr>
<th>40%<td style="color:#66b2ff"><td style="color:#6699cc"><td style="color:#667f99"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#99ccff"><td style="color:#99b3cc"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#cce5ff"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d5d5d4"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">240° Blues
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#0000ff"><td style="color:#0000cc"><td style="color:#000099"><td style="color:#000066"><td style="color:#000033"><td style="color:#000000">
<tr>
<th>20%<td style="color:#3333ff"><td style="color:#3333cc"><td style="color:#333399"><td style="color:#333366"><td style="color:#333333"><td style="color:#2b2b2a">
<tr>
<th>40%<td style="color:#6666ff"><td style="color:#6666cc"><td style="color:#666699"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#9999ff"><td style="color:#9999cc"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ccccff"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d5d5d4"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">270° Blue-Magentas
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#7f00ff"><td style="color:#6600cc"><td style="color:#4c0099"><td style="color:#330066"><td style="color:#190033"><td style="color:#000000">
<tr>
<th>20%<td style="color:#9933ff"><td style="color:#7f33cc"><td style="color:#663399"><td style="color:#4c3366"><td style="color:#333333"><td style="color:#2a2b2a">
<tr>
<th>40%<td style="color:#b266ff"><td style="color:#9966cc"><td style="color:#7f6699"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#cc99ff"><td style="color:#b399cc"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#e5ccff"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d5d5d4"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">300° Magentas
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#ff00ff"><td style="color:#cc00cc"><td style="color:#990099"><td style="color:#660066"><td style="color:#330033"><td style="color:#000000">
<tr>
<th>20%<td style="color:#ff33ff"><td style="color:#cc33cc"><td style="color:#993399"><td style="color:#663366"><td style="color:#333333"><td style="color:#2a2b2a">
<tr>
<th>40%<td style="color:#ff66ff"><td style="color:#cc66cc"><td style="color:#996699"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#ff99ff"><td style="color:#cc99cc"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ffccff"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d4d5d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
<table>
<tr>
<th><th colspan="6">330° Magenta-Reds
<tr>
<th><span class="white">W</span>\<span class="black">B</span>
<th>0%<th>20%<th>40%<th>60%<th>80%<th>100%
<tr>
<th>0%<td style="color:#ff0080"><td style="color:#cc0066"><td style="color:#99004d"><td style="color:#660033"><td style="color:#33001a"><td style="color:#000000">
<tr>
<th>20%<td style="color:#ff3399"><td style="color:#cc3380"><td style="color:#993366"><td style="color:#66334d"><td style="color:#333333"><td style="color:#2a2b2a">
<tr>
<th>40%<td style="color:#ff66b3"><td style="color:#cc6699"><td style="color:#996680"><td style="color:#666666"><td style="color:#555555"><td style="color:#494949">
<tr>
<th>60%<td style="color:#ff99cc"><td style="color:#cc99b3"><td style="color:#999999"><td style="color:#808080"><td style="color:#6d6d6d"><td style="color:#606060">
<tr>
<th>80%<td style="color:#ffcce6"><td style="color:#cccccc"><td style="color:#aaaaaa"><td style="color:#929292"><td style="color:#808080"><td style="color:#717171">
<tr>
<th>100%<td style="color:#ffffff"><td style="color:#d4d5d5"><td style="color:#b6b6b6"><td style="color:#9f9f9f"><td style="color:#8e8e8e"><td style="color:#808080">
</table>
</div>
<h2 id='lab-colors'>
Device-independent Colors: Lab and LCH</h2>
Physical measurements of a color are typically expressed as the Lab color space,
created in 1976 by the <abbr title='Commission Internationale de l'Eclairage'>CIE</abbr>.
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.
<!-- Simplify by saying Lab throughout rather than CIELab or
CIE L*a*b*, because that is what people write in practice -->
Lab is a rectangular coordinate system with a central Lightness axis.
L=0 is deep black (no light at all)
while L=100 is a diffuse white
(the illuminant is D50 white, a standardized daylight spectrum with a color temperature of 5000K,
as reflected by a perfect diffuse reflector).
Values greater than 100 would correspond to specular highlights,
but their precise color is undefined in this specification.
Usefully, L=50 is mid gray, by design,
and equal increments in L are evenly spaced visually:
the Lab color space is intended to be <em>perceptually uniform</em>.
The a and b axes convey hue;
positive values along the a axis are a purplish red
while negative values are the complementary color, a 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.
<!-- diagram here -->
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 <dfn export>chromatic adaptation transform</dfn>,
which models the changes in the human visual system as we adapt to a new lighting condition.
The Bradford algorithm
<!-- add reference -->
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.
<!-- because Luv is not widely used nowadays, no need to say LCH(ab)
to distinguish from LCH(uv) -->
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 from the positive a axis,
with positive angles being more clockwise.
Note: 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.
<h3 id="specifying-lab-lch">
Specifying Lab and LCH: the lab() and lch() functional notations</h3>
<!-- lab rather than CIELab or whatever, for brevity -->
CSS allows colors to be directly expressed in Lab and LCH.
<pre class='prod'>
<dfn>lab()</dfn> = lab( <<number>> <<number>> <<number>> [ / <<alpha-value>> ]? )
</pre>
The first argument specifies the CIE Lightness.
This is typically a number between ''0''
(representing black)
and ''100''
(representing white),
similar to the lightness argument of ''hsl()''.
However, CIE Lightness <em>can</em> exceed this range on some systems,
with extra-bright whites using a lightness up to ''400''.
Values less than ''0'' must be clipped to ''0''; values greater than
''100'' are permitted (for forwards compatibility with High Dynamic Range (HDR),
and must not be clipped.
The second and third arguments are the distances along the "a" and "b" axises
in the Lab colorspace,
as described in the previous section.
These values are signed
(allow both positive and negative values)
and theoretically unbounded
(but in practice do not exceed ±160).
There is an optional fourth alpha value,
separated by a slash,
and interpreted identically to the <<alpha-value>> in ''rgb()''.
<pre class='prod'>
<dfn>lch()</dfn> = lch( <<number>> <<number>> <<hue>> [ / <<alpha-value>> ]? )
</pre>
The first argument specifies the CIE Lightness,
interpreted identically to the Lightness argument of ''lab()''.
The second argument is the chroma
(roughly representing the "amount of color").
Its minimum useful value is ''0'',
while its maximum is theoretically unbounded
(but in practice does not exceed ''230'').
If the provided value is negative,
it is clamped to ''0''.
The third argument is the hue.
It's interpreted identically to the <<hue>> argument of ''hsl()'',
but doesn't map hues to angles in the same way.
Instead, ''0deg'' points along the positive "a" axis,
''90deg'' points along the positive "b" axis,
''180deg'' points along the negative "a" axis,
and ''270deg'' points along the negative "b" axis.
If the provided value is is negative,
or is greater than or equal to ''360deg'',
it is set to the value modulo 360.
<!-- add diagram showing hue angles in LCH for RGB primaries and secondaries in sRGB, P3, and Rec.2020 -->
There is an optional fourth alpha value,
separated by a slash,
and interpreted identically to the <<alpha-value>> in ''rgb()''.
Issue: Need to decide what, if anything, to do for high dynamic range on luminance.
<h3 id='rgb-to-lab'>
Converting sRGB colors to Lab colors</h3>
Conversion from sRGB to Lab requires several steps,
although in practice all but the first step are linear calculations and can be combined.
<!-- make these steps links to the appropriate section in a calculations appendix -->
<ol>
<li>Convert from sRGB to linear-light sRGB (undo gamma encoding)
<li>Convert from linear sRGB to CIE XYZ
<li>Convert from a D65 whitepoint (used by sRGB) to the D50 whitepoint used
in Lab, with the Bradford transform
<li>Convert D50-adapted XYZ to Lab
</ol>
There is sample JavaScript code for this conversion in [[#color-conversion-code]].
<h3 id='lab-to-rgb'>
Converting Lab colors to sRGB colors</h3>
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.
<ol>
<li>Convert Lab to (D50-adapted) XYZ
<li>Convert from a D50 whitepoint (used by Lab) to the D65 whitepoint used
in sRGB, with the Bradford transform
<li>Convert from (D65-adapted) CIE XYZ to linear sRGB
<li>Convert from linear-light sRGB to sRGB (do gamma encoding)
</ol>
<h3 id='lab-to-lch'>
Converting Lab colors to LCH colors</h3>
Conversion to LCH is trivial:
<ol>
<li>H = atan2(b, a)
<li>C = sqrt(a^2 + b^2)
<li>L is the same
</ol>
<h3 id='lch-to-lab'>
Converting LCH colors to Lab colors</h3>
Conversion to Lab is trivial:
<ol>
<li>a = C cos(H)
<li>b = C sin(H)
<li>L is the same
</ol>
<h2 id='grays'>
Specifying Grays: the ''gray()'' functional notation</h2>
Issue: 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).
<pre class='prod'>
<dfn>gray()</dfn> = gray( <<number>> [ / <<alpha-value>> ]? )
</pre>
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.
Note: In other words,
''gray(a / b)'' is equal to ''lab(a 0 0 / b)''.
<h3 id='gray-to-rgb'>
Converting gray colors to sRGB colors</h3>
Conversion from gray to sRGB requires multiple steps;
in practice all but the last step are linear calculations and can be combined.
<ol>
<li>Convert to Lab by setting L to the gray value, a and b to 0
<li>Convert Lab to XYZ
<li>Adapt from D50 to D65 (Bradford transform)
<li>Convert from (D65-adapted) CIE XYZ to linear sRGB
<li>Convert from linear-light sRGB to sRGB (do gamma encoding)
</ol>
<h2 id='icc-colors'>
Profiled, Device-dependent Colors</h2>
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 <em>characterised</em>.
This characterization information is stored in a <em>profile</em>.
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 <em>calibrated</em>.
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 <!-- ref -->, <!-- would be good to mention AdobeRGB 1998 here too, need to check trademark and copyright issues first --> widely used by photographers), or any other color or monochrome output device which has been characterized.
In addition, for convenience,
CSS provides two predefined RGB color spaces:
image-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.
<div class='example'>
This example specifies four profiled colors:
for a standard SWOP-coated CMYK press,
for a wide-gamut seven-ink printer,
for ProPhoto RGB,
and for the image-p3 standard RGB space.
In each case, the numerical parameters
are in the range 0.0 to 1.0
(rather than, for example, 0 to 255).
<!-- add examples with alpha, and with fallback -->
<pre>
color: color(swopc 0.0134 0.8078 0.7451 0.3019);
color: color(indigo 0.0941 0.6274 0.3372 0.1647 0 0.0706 0.1216);
color: color(prophoto 0.9137 0.5882 0.4784);
color: color(image-p3 0.3804 0.9921 0.1412);
</pre>
All but the predefined colorspace example
also need a matching ''@color-profile'' at-rule
somewhere in the stylesheet,
to connect the name with the profile data.
<pre>
@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');}
</pre>
</div>
Issue: color() fallback should be like font list fallback, as decided at San Francisco. Recursive?
<h3 id="color-function">Specifying profiled colors: the ''color()'' function</h3>
The ''color()'' function allows a color to be specified
in a particular colorspace
(rather than the implicit sRGB colorspace that the other color functions operate in).
Its syntax is:
<pre class='prod'>
<dfn>color()</dfn> = color( [ <<ident>>? [ <<number>>+ | <<string>> ] [ / <<alpha-value>> ]? ]# , <<color>>? )
</pre>
The color function takes one or more comma-separated arguments,
with each argument specifying a color,
and later colors acting as "fallback" if an earlier color can't be displayed
(for example, if the colorspace it specifies hasn't been loaded yet).
Each argument has the following form:
* An optional <<ident>> denoting the colorspace.
This can be one of the predefined colorspaces
(such as ''image-p3''),
or one defined by a ''@color-profile'' rule.
If omitted, it defaults to the predefined ''srgb'' color profile.
If the <<ident>> names a non-existent colorspace,
this argument represents an <a>invalid color</a>.
* Either one or more <<number>>s providing the parameter values that the colorspace takes,
or a <<string>> giving the name of a color defined by the colorspace.
<dl class=switch>
<dt>If the colorspace takes numeric parameters
<dd>
If more <<number>>s are provided than parameters that the colorspace takes,
the excess <<number>>s at the end are ignored.
If less <<number>>s are provided than parameters that the colorspace takes,
the missing parameters default to ''0''.
(This is particularly convenient for multichannel printers
where the additional inks are spot colors or varnishes
that most colors on the page won't use.)
If a <<string>> is provided,
this argument represents an <a>invalid color</a>.
<dt>If the colorspace defines named colors
<dd>
If <<number>>s are provided,
or a <<string>> is provided that doesn't match any of the color names
defined by the colorspace,
this argument represents an <a>invalid color</a>.
</dl>
* An optional slash-separated <<alpha-value>>.
This is interpreted the same way as the <<alpha-value>> in ''rgb()'',
and if omitted it defaults to ''100%''.
After one or more arguments of the above form,
a final <<color>> argument
using any CSS color syntax
can be provided.
The ''color()'' function represents the color
specified by the first of its arguments that represent a <dfn export>valid color</dfn>
(that is, the first argument that isn't an <dfn export>invalid color</dfn>).
If all of its arguments represent <a>invalid colors</a>,
''color()'' represents <a>opaque black</a>.
<h3 id="predefined">
Predefined colorspaces: ''srgb'', ''image-p3'', ''a98rgb'', ''prophotorgb'' and ''rec2020''.</h3>
The following colorspaces are predefined for use in the ''color()'' function.
They can be used without any ''@color-profile'' rule.
Issue: Decided at San Francisco to add a larger set of common predefined spaces
like AdobeRGB, ProPhoto RGB, and so on. Also coated and uncoated swop, etc, etc.
<dl dfn-type=value dfn-for="color()">
<dt><dfn>srgb</dfn>
<dd>
The ''srgb'' [[!SRGB]] colorspace accepts three numeric parameters,
representing the red, green, and blue channels of the color,
with each having a valid range of [0, 1].
The whitepoint is D65
(a daylight white, with a correlated color temperature of 6504°K).
[[!SRGB]] specifies two viewing conditions, <em>encoding</em>
and <em>typical</em>. The [[ICC]] recommends using the <em>encoding</em>
conditions for color conversion and for optimal viewing, which are
the values in the table below.
sRGB is the default colorspace for CSS,
identical to specifying a color with the ''rgb()'' function.
It has the following characteristics:
<table>
<thead><td></td><td>x</td><td>y</td></thead>
<tr><th>Red chromaticity</th><td>0.640</td><td>0.330</td></tr>
<tr><th>Green chromaticity</th><td>0.300</td><td>0.600</td></tr>
<tr><th>Blue chromaticity</th><td>0.150</td><td>0.060</td></tr>
<tr><th>White chromaticity</th><td>0.3127</td><td>3290</td></tr>
<tr><th>Transfer function</th><td colspan="2">see below</td></tr>
<tr><th>White luminance</th><td colspan="2">80.0 cd/m<sup>2</sup></td></tr>
<tr><th>Black luminance</th><td colspan="2">0.80 cd/m<sup>2</sup></td></tr>
</table>
<pre class="lang-javascript">
var Cl;
if (C <= 0.04045)
Cl = C / 12.92;
else
Cl = Math.pow((C + 0.055) / 1.055, 2.4);
</pre>
C is the red, green or blue component.
<dt><dfn>image-p3</dfn>
<dd>
The ''image-p3'' colorspace accepts three numeric parameters,
representing the red, green, and blue channels of the color,
with each having a valid range of [0, 1].
It uses the same primary chromaticities as [[!DCI-P3]],
but with a D65 whitepoint and the same transfer curve as sRGB.
It has the following characteristics:
<table>
<thead><td></td><td>x</td><td>y</td></thead>
<tr><th>Red chromaticity</th><td>0.680</td><td>0.320</td></tr>
<tr><th>Green chromaticity</th><td>0.265</td><td>0.690</td></tr>
<tr><th>Blue chromaticity</th><td>0.150</td><td>0.060</td></tr>
<tr><th>White chromaticity</th><td>0.3127</td><td>0.3290</td></tr>
<tr><th>Transfer function</th><td colspan="2">same as srgb</td></tr>
<tr><th>White luminance</th><td colspan="2">80.0 cd/m<sup>2</sup></td></tr>
<tr><th>Black luminance</th><td colspan="2">0.80 cd/m<sup>2</sup></td></tr>
</table>
<dt><dfn>a98rgb</dfn>
<dd>
The ''a98rgb'' colorspace accepts three numeric parameters,
representing the red, green, and blue channels of the color,
with each having a valid range of [0, 1]. The transfer curve is
a gamma function, close to but not exactly 1/2.2.
''a98rgb'' is compatible with Adobe® RGB (1998).
Adobe® RGB (1998) uses primaries originally derived
from the SMPTE 240M standard;
errors in the original conversion turned out
to produce a colorspace that was useful for digital photography,
so Adobe® RGB (1998) is a common wider-gamut colorspace for
photographic images. The ''a98rgb'' colorspace allows CSS to
specify colors that will match colors in such images
having the same RGB values.
It has the following characteristics:
<table>
<thead><td></td><td>x</td><td>y</td></thead>
<tr><th>Red chromaticity</th><td>0.680</td><td>0.320</td></tr>
<tr><th>Green chromaticity</th><td>0.265</td><td>0.690</td></tr>
<tr><th>Blue chromaticity</th><td>0.150</td><td>0.060</td></tr>
<tr><th>White chromaticity</th><td>0.3127</td><td>0.3290</td></tr>
<tr><th>Transfer function</th><td colspan="2">256/563 </td></tr>
<tr><th>White luminance</th><td colspan="2">160.0 cd/m<sup>2</sup></td></tr>
<tr><th>Black luminance</th><td colspan="2">0.5557 cd/m<sup>2</sup></td></tr>
</table>
<dt><dfn>prophotorgb</dfn>
<dd>
The ''prophotorgb'' colorspace accepts three numeric parameters,
representing the red, green, and blue channels of the color,
with each having a valid range of [0, 1]. The transfer curve is
a gamma function with a value of 1/1.8.
The white point is D50, the same as is used by CIE Lab. Thus,
conversion to Lab does not require the chromatic adaptation step.
The ProPhoto RGB space uses primaries chosen to allow
a wide color gamut and to minimise hue shifts under tonal manipulation.
It is often used in digital photography as a wide gamut
colorspace for the master version of
photographic images. The ''prophotorgb'' colorspace allows CSS to
specify colors that will match colors in such images
having the same RGB values.
The white luminance is given as a range, and
the viewing flare (and thus, the black luminance)
is 0.5% to 1.0% of this.
It has the following characteristics:
<table>
<thead><td></td><td>x</td><td>y</td></thead>
<tr><th>Red chromaticity</th><td>0.7347</td><td>0.2653</td></tr>
<tr><th>Green chromaticity</th><td>0.1596</td><td>0.8404</td></tr>
<tr><th>Blue chromaticity</th><td>0.0366</td><td>0.0001</td></tr>
<tr><th>White chromaticity</th><td>0.3457</td><td>0.3585</td></tr>
<tr><th>Transfer function</th><td colspan="2">1/1.800 </td></tr>
<tr><th>White luminance</th><td colspan="2">160.0 to 640.0 cd/m<sup>2</sup></td></tr>
<tr><th>Black luminance</th><td colspan="2">See text</td></tr>
</table>
<dt><dfn>rec2020</dfn>
<dd>
The ''rec2020'' [[!Rec.2020]] colorspace accepts three numeric parameters,
representing the red, green, and blue channels of the color,
with each having a valid range of [0, 1]. ITU Reference 2020 is used for High Definition, 4k and 8k television.
It has the following characteristics:
<table>
<thead><td></td><td>x</td><td>y</td></thead>
<tr><th>Red chromaticity</th><td>0.708</td><td>0.292</td></tr>
<tr><th>Green chromaticity</th><td>0.170</td><td>0.797</td></tr>
<tr><th>Blue chromaticity</th><td>0.131</td><td>0.046</td></tr>
<tr><th>White chromaticity</th><td>0.3120</td><td>0.3290</td></tr>
<tr><th>Transfer function</th><td colspan="2">1/2.4 (see note)</td></tr>
</table>
Note: Rec2020 references a different transfer curve for cameras. However
this curve is never used in production cameras or 2020 displays.<br/>
"In typical production practice the encoding function of image sources is adjusted so that the final picture has the desired look, as viewed on a reference monitor having the reference decoding function of Recommendation ITU-R BT.1886, in the reference viewing environment defined in Recommendation ITU-R BT.2035."<br/>
The transfer function (1886) for reference Rec.2020 displays is gamma 2.4 [[!Rec.2020]]
</dl>
<h4 id="predefined-to-lab">
Converting predefined colorspaces to Lab</h4>
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.
<!-- make these steps links to the appropriate section in a calculations appendix -->
<ol>
<li>Convert from gamma-corrected RGB to linear-light RGB (undo gamma encoding)
<li>Convert from linear RGB to CIE XYZ
<li>Convert from a D65 whitepoint (used by both image-p3 and rec2020) to the D50 whitepoint used in Lab,
with the Bradford transform
<li>Convert D50-adapted XYZ to Lab
</ol>
Issue: Canvas proposes adding a 16bit half-float <em>linear</em> rec2020 space
<h4 id="lab-to-predefined">
Converting Lab to predefined colorspaces</h4>
Conversion from Lab to image-p3 or rec2020 also requires multiple steps,
and again in practice all but the last step are linear calculations and can be combined.
<ol>
<li>Convert Lab to (D50-adapted) XYZ
<li>Convert from a D50 whitepoint (used by Lab) to the D65 whitepoint used in sRGB,
with the Bradford transform
<li>Convert from (D65-adapted) CIE XYZ to linear RGB
<li>Convert from linear-light RGB to RGB (do gamma encoding)
</ol>
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.
<h3 id="at-profile">
Specifying a color profile: the ''@color-profile'' at-rule</h3>
The <dfn at-rule id="at-ruledef-profile">@color-profile</dfn> rule
defines and names a <dfn lt="CSS color profile" local-lt="color profile">color profile</dfn>
which can later be used in the ''color()'' function to specify a color.
It's defined as:
<pre class='prod'>
@color-profile = @color-profile <<custom-ident>> { <<declaration-list>> }
</pre>
The <<custom-ident>> gives the <a>color profile's</a> name.
All of the predefined colorspace keywords
(''srgb'', ''image-p3'', ''a98rgb'', ''prophotorgb'', ''rec2020'')
are excluded from this <<custom-ident>>,
as they're predefined by this specification and always available.
The ''@color-profile'' rule accepts the descriptors defined in this specification.
<pre class=descdef for="@color-profile">
Name: src
Value: <<url>>
For: @color-profile
Initial: n/a
</pre>
The '@color-profile/src' descriptor specifies the URL to retrieve the color-profile information from.
Issue: Same-origin and CORS for src.
Issue: local() to use locally installed profiles.
Profile stack like font-face rather than a single url.
Avoid flash of uncalibrated color.
<!-- should we add a format field to this descriptor, like with font-face src? it is always ICC format
in practice, but that could change in the future. or we could add format later, once there is
a need, and make the default ICC if not specified -->
<!-- we decided in San Francisco to not allow rendering intent to be specified in the CSS;
just use the rendering intent provided by the profile. However, leave in for FPWD. -->
<pre class=descdef>
Name: rendering-intent
Value: relative-colorimetric | absolute-colorimetric | perceptual | saturation
Initial: relative-colorimetric
For: @color-profile
</pre>
<a>Color profiles</a> contain “rendering intents”,
which define how to map their color to smaller gamuts than they're defined over.
Often a profile will contain only a single intent,
but when there are multiple,
the 'rendering-intent' descriptor chooses one of them to use.
The four possible rendering intents are [[!ICC]]:
<dl dfn-type=value dfn-for="@color-profile/rendering-intent">
<dt><dfn>relative-colorimetric</dfn>
<dd>
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.
<dt><dfn>absolute-colorimetric</dfn>
<dd>
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.
<dt><dfn>perceptual</dfn>
<dd>
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.
Note: 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.
<dt><dfn>saturation</dfn>
<dd>
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.
</dl>
Issue: 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?
<h2 id="working-color-space">
Working Color Space</h2>
Issue: 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.
<h2 id='cmyk-colors'>
Device-dependent CMYK Colors: the ''device-cmyk()'' function</h2>
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:
<pre class='prod'>