Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Editorial review, Relative color syntax #32004

Merged
merged 66 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
3a71eb5
Add docs for relative CSS colors
chrisdavidmills Dec 12, 2023
ee9c535
more updates to usage tutorial
chrisdavidmills Dec 13, 2023
6f7ccb4
Finish relative colors guide
chrisdavidmills Dec 14, 2023
0c483a0
Add relative mentions to landing pages, modify hsl() page
chrisdavidmills Dec 15, 2023
41974b1
Merge branch 'main' into relative-color-syntax
chrisdavidmills Dec 20, 2023
c53eaf4
Updates according to estelle comments and as a result of cross-browse…
chrisdavidmills Dec 20, 2023
5ca34b6
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 2, 2024
bad0899
Update files/en-us/web/css/color_value/hsl/index.md
chrisdavidmills Jan 8, 2024
bfd352c
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 8, 2024
e965194
fix linting error
chrisdavidmills Jan 8, 2024
72e759b
Fix up existing articles according to latest feedback and implementat…
chrisdavidmills Jan 8, 2024
5bd8892
Update files/en-us/web/css/css_colors/relative_colors/index.md
chrisdavidmills Jan 9, 2024
f640bd0
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 9, 2024
80d352a
Minor fixes, plus adding details of origin channel resolution values
chrisdavidmills Jan 10, 2024
dfc849d
Get examples working in Safari and Chrome, add details of alpha chann…
chrisdavidmills Jan 10, 2024
d819015
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 10, 2024
838ad84
Update rgb() page with relative syntax info
chrisdavidmills Jan 10, 2024
9354868
Merge branch 'relative-color-syntax' of github.com:chrisdavidmills/co…
chrisdavidmills Jan 10, 2024
9d623fc
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 11, 2024
2654bc9
Adding hwb() relative syntax explanation, plus some small tweaks
chrisdavidmills Jan 11, 2024
df9a4c9
Adding lab() relative colors explanation
chrisdavidmills Jan 11, 2024
ada10ec
Adding oklab() relative syntax explanation
chrisdavidmills Jan 11, 2024
6ac9320
Adding lch() and oklch() relative syntax explanation
chrisdavidmills Jan 11, 2024
2f5e718
Add color() relative syntax explanation
chrisdavidmills Jan 12, 2024
a9b436e
Making heading levels correct and consistent
chrisdavidmills Jan 12, 2024
9c61786
Various bits of cleanup
chrisdavidmills Jan 12, 2024
85c062b
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 12, 2024
9a42f52
Fix flaws
chrisdavidmills Jan 12, 2024
eaf2a72
Merge branch 'relative-color-syntax' of github.com:chrisdavidmills/co…
chrisdavidmills Jan 12, 2024
9060623
Update files/en-us/web/css/color_value/hsl/index.md
chrisdavidmills Jan 15, 2024
28f35e3
Update files/en-us/web/css/color_value/lch/index.md
chrisdavidmills Jan 15, 2024
dbca4e8
Update files/en-us/web/css/color_value/oklch/index.md
chrisdavidmills Jan 15, 2024
b6ec895
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 15, 2024
5bb4e1d
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 15, 2024
b602192
Fix bug in Safari support in color() example
chrisdavidmills Jan 15, 2024
5957b37
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 15, 2024
fef927b
Small tweaks to correct comment content
chrisdavidmills Jan 15, 2024
b6498c9
Merge branch 'relative-color-syntax' of github.com:chrisdavidmills/co…
chrisdavidmills Jan 15, 2024
3a12013
Fixes for mysteryDate review comments
chrisdavidmills Jan 18, 2024
fa198f2
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 18, 2024
7980041
Merge branch 'main' into relative-color-syntax
chrisdavidmills Jan 30, 2024
e2957be
Fixes for estelle comments
chrisdavidmills Jan 31, 2024
b148535
more fixes for estelle comments
chrisdavidmills Feb 1, 2024
b9127b2
Fixes for estelle comments
chrisdavidmills Feb 9, 2024
11dfd45
Merge branch 'main' into relative-color-syntax
chrisdavidmills Feb 9, 2024
928e865
Fixes for latest round of Estelle comments
chrisdavidmills Feb 26, 2024
7889aae
Next round of review comment fixes
chrisdavidmills Feb 27, 2024
bf0d623
Various improvements, mainly to the relative colors guide
chrisdavidmills Feb 29, 2024
d8b1b5f
Update files/en-us/web/css/css_colors/relative_colors/index.md
chrisdavidmills Mar 1, 2024
451a963
Merge branch 'main' into relative-color-syntax
chrisdavidmills Mar 1, 2024
ade088a
Next round of review comment fixes
chrisdavidmills Mar 7, 2024
8e9dc2b
Merge branch 'main' into relative-color-syntax
chrisdavidmills Mar 7, 2024
02a894b
Merge branch 'main' into relative-color-syntax
chrisdavidmills Mar 11, 2024
d8a6bf0
Implement changes related to color spaces not necessarily being limit…
chrisdavidmills Mar 11, 2024
198a420
Merge branch 'main' into relative-color-syntax
estelle Mar 11, 2024
c69857b
Latest round of fixes for estelle comments
chrisdavidmills Mar 12, 2024
1d30d55
Merge branch 'main' into relative-color-syntax
chrisdavidmills Mar 13, 2024
6cfb324
More updates for last round of comments.
chrisdavidmills Mar 13, 2024
b546a1a
Merge branch 'main' into relative-color-syntax
chrisdavidmills Mar 14, 2024
892ea0b
More updates
chrisdavidmills Mar 14, 2024
21201a5
update legacy and alias details
chrisdavidmills Mar 14, 2024
2080abc
More updates, mainly tweaks to second example
chrisdavidmills Mar 15, 2024
296b4b3
Latest fixes for estelle comments
chrisdavidmills Mar 18, 2024
5013442
Merge branch 'main' into relative-color-syntax
chrisdavidmills Mar 18, 2024
7e9befc
Final fixes!!
chrisdavidmills Mar 19, 2024
eb742cb
Merge branch 'main' into relative-color-syntax
chrisdavidmills Mar 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 198 additions & 13 deletions files/en-us/web/css/color_value/color/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,154 @@ title: color()
slug: Web/CSS/color_value/color
page-type: css-function
browser-compat: css.types.color.color
spec-urls:
- https://drafts.csswg.org/css-color-5/#color-function
- https://drafts.csswg.org/css-color-5/#relative-color-function
estelle marked this conversation as resolved.
Show resolved Hide resolved
- https://drafts.csswg.org/css-color/#color-function
---

{{CSSRef}}

The **`color()`** functional notation allows a color to be specified in a particular, specified colorspace rather than the implicit sRGB colorspace that most of the other color functions operate in.
The **`color()`** functional notation allows a color to be specified in a particular, specified {{glossary("color space")}} rather than the implicit sRGB color space that most of the other color functions operate in.

Support for a particular colorspace can be detected with the [`color-gamut`](/en-US/docs/Web/CSS/@media/color-gamut) CSS media feature.
Support for a particular color space can be detected with the [`color-gamut`](/en-US/docs/Web/CSS/@media/color-gamut) CSS media feature.

## Syntax

```css
/* Absolute values */
color(display-p3 1 0.5 0);
color(display-p3 1 0.5 0 / .5);

/* Relative values */
color(from green srgb r g b / 0.5)
color(from #0000FF xyz calc(x + 0.75) y calc(z - 0.35))
```

### Values

Functional notation: `color(colorspace c1 c2 c3[ / A])`
Below are descriptions of the allowed values for both absolute and [relative colors](/en-US/docs/Web/CSS/CSS_colors/Relative_colors).

#### Absolute value syntax

```text
color(colorspace c1 c2 c3[ / A])
```

The parameters are as follows:

- `colorspace`

- : An {{CSSXref("<ident>")}} denoting one of the predefined color spaces: `srgb`, `srgb-linear`, `display-p3`, `a98-rgb`, `prophoto-rgb`, `rec2020`, `xyz`, `xyz-d50`, and `xyz-d65`.
- : An {{CSSXref("<ident>")}} denoting one of the predefined color spaces: `srgb`, `srgb-linear`, `display-p3`, `a98-rgb`, `prophoto-rgb`, `rec2020`, `xyz`, `xyz-d50`, or `xyz-d65`.

- `c1`, `c2`, `c3`

- : {{CSSXref("number")}} between 0 and 1, a {{CSSXref("percentage")}} or the keyword `none`, which provide the component values in the color space.
- : Each value can be written as a {{CSSXref("number")}}, a {{CSSXref("percentage")}}, or the keyword `none` (equivalent to `0` in this case). These values represent the component values for the colorspace. When using a `<number>` value, generally, `0` to `1` represents the bounds of the color space. Values outside of that range are permitted but will be out of {{glossary("gamut")}} for the given color space. When using a percentage value, `100%` represents `1` and `0%` represents `0`.

- `A` {{optional_inline}}

- : An {{CSSXref("&lt;alpha-value&gt;")}} or the keyword `none`, where the number `1` corresponds to `100%` (full opacity).
- : An {{CSSXref("&lt;alpha-value&gt;")}} representing the alpha channel value of the color, where the number `0` corresponds to `0%` (fully transparent) and `1` corresponds to `100%` (fully opaque). Additionally, the keyword `none` can be used to explicitly specify no alpha channel. If the `A` channel value is not explicitly specified, it defaults to 100%. If included, the value is preceded by a slash (`/`).

> **Note:** See [Missing color components](/en-US/docs/Web/CSS/color_value#missing_color_components) for more information on the effect of `none`.

#### Relative value syntax

```text
color(from <color> colorspace c1 c2 c3[ / A])
```

The parameters are as follows:

- `from <color>`
- : The keyword `from` is always included when defining a relative color, followed by a {{cssxref("&lt;color&gt;")}} value representing the **origin color**. This is the original color that the relative color is based on. The origin color can be _any_ valid {{cssxref("&lt;color&gt;")}} syntax, including another relative color.
- `colorspace`
- : An {{CSSXref("&lt;ident&gt;")}} denoting the {{glossary("color space")}} of the output color, generally one of the predefined color spaces: `srgb`, `srgb-linear`, `display-p3`, `a98-rgb`, `prophoto-rgb`, `rec2020`, `xyz`, `xyz-d50`, or `xyz-d65`.
- `c1`, `c2`, `c3`
- : Each value can be written as a {{CSSXref("number")}}, a {{CSSXref("percentage")}}, or the keyword `none` (equivalent to `0` in this case). These values represent the component values for the output color. When using a `<number>` value, generally `0` to `1` represents the bounds of the color space. Values outside of that range are permitted but will be out of {{glossary("gamut")}} for the given color space. Generally, when using a percentage value, `100%` represents `1` and `0%` represents `0`.
- `A` {{optional_inline}}
- : An {{CSSXref("&lt;alpha-value&gt;")}} representing the alpha channel value of the output color, where the number `0` corresponds to `0%` (fully transparent) and `1` corresponds to `100%` (fully opaque). Additionally, the keyword `none` can be used to explicitly specify no alpha channel. If the `A` channel value is not explicitly specified, it defaults to the alpha channel value of the origin color. If included, the value is preceded by a slash (`/`).

#### Defining relative color output channel components

When using relative color syntax inside a `color()` function, the browser converts the origin color into an equivalent color in the specified color space (if it is not already specified as such). The color is defined as three distinct color channel values plus an alpha channel value (`alpha`). These channel values are made available inside the function to be used when defining the output color channel values:

- The three color channel values of the origin color are resolved to a `<number>`. For predefined color spaces, depending on which is specified, these values will be one of the following:
estelle marked this conversation as resolved.
Show resolved Hide resolved

- `r`, `g`, and `b`: Color channel values for the RGB-based color spaces `srgb`, `srgb-linear`, `display-p3`, `a98-rgb`, `prophoto-rgb`, and `rec2020`.
- `x`, `y`, and `z`: Color channel values for the CIE XYZ-based color spaces `xyz`, `xyz-d50`, and `xyz-d65`.

estelle marked this conversation as resolved.
Show resolved Hide resolved
> **Note:** Each of these values is usually between `0` and `1` but, as explained above, they may be outside these bounds.

> **Note:** Referencing `r`, `g`, and `b` values inside a `color()` function with a XYZ-based colorspace, `x`, `y`, and `z` values inside a `color()` function with an RGB-based colorspace, or any other characters, is invalid. The origin color channel values available inside the function must match the specified type of colorspace.

- `alpha`: The color's transparency value, resolved to a `<number>` between `0` and `1`, inclusive.

When defining a relative color, the different channels of the output color can be expressed in several different ways. Below, we'll study some examples to illustrate these.

In the first two examples below, we are using relative color syntax. However, the first one outputs the same color as the origin color and the second one outputs a color not based on the origin color at all. They don't really create relative colors! You'd be unlikely to ever use these in a real codebase, and would probably just use an absolute color value instead. We included these examples as a starting point for learning about relative `color()` syntax.

Let's start with an origin color of `hsl(0 100% 50%)` (equivalent to `red`). While you are unlikely to ever write the following functions because they output the same color as the origin color, this demonstrates how to use the origin color channel values as the output channel values:

```css
color(from hsl(0 100% 50%) srgb r g b)
color(from hsl(0 100% 50%) xyz x y z)
```
estelle marked this conversation as resolved.
Show resolved Hide resolved

These functions' output colors are `color(srgb 1 0 0)` and `color(xyz-d65 0.412426 0.212648 0.0193173)`, respectively.

The next functions use absolute values for the output color channel values, outputting completely different colors not based on the origin color:

```css
color(from hsl(0 100% 50%) srgb 0.749938 0 0.609579)
/* Computed output color: color(srgb 0.749938 0 0.609579) */

color(from hsl(0 100% 50%) xyz 0.75 0.6554 0.1)
/* Computed output color: color(xyz-d65 0.75 0.6554 0.1 */
```

The following functions use two of the origin color channel values for the output color channel values (`r` and `b`, and `x` and `y`, respectively), but use a new value for the other output channel value (`g` and `z`, respectively), creating a relative color based on the origin color in each case:

```css
color(from hsl(0 100% 50%) srgb r 1 b)
/* Computed output color: color(srgb 1 1 0) */

color(from hsl(0 100% 50%) xyz x y 0.5)
estelle marked this conversation as resolved.
Show resolved Hide resolved
/* Computed output color: color(xyz-d65 0.412426 0.212648 0.5) */
```

> **Note:** As mentioned above, if the output color is using a different color model to the origin color, the origin color is converted to the same model as the output color in the background so that it can be represented in a way that is compatible (i.e. using the same channels). For example, the {{cssxref("color_value/hsl", "hsl()")}} color `hsl(0 100% 50%)` is converted to `color(srgb 1 0 0)` in the first case above and `color(xyz 0.412426 0.212648 0.5)` in the second case.

In the examples we've seen so far in this section, the alpha channels have not been explicitly specified for either the origin or output colors. When the output color alpha channel is not specified, it defaults to the same value as the origin color alpha channel. When the origin color alpha channel is not specified (and it is not a relative color), it defaults to `1`. Therefore, the origin and output alpha channel values are `1` for the above examples.

Let's look at some examples that specify origin and output alpha channel values. The first one specifies the output alpha channel value as being the same as the origin alpha channel value, whereas the second one specifies a different output alpha channel value, unrelated to the origin alpha channel value.

> **Note:** See [Missing color components](/en-US/docs/Web/CSS/color_value#missing_color_components) for the effect of `none`.
```css
color(from hsl(0 100% 50% / 0.8) srgb r g b / alpha)
/* Computed output color: color(srgb 1 0 0 / 0.8) */

color(from hsl(0 100% 50% / 0.8) xyz x y z / 0.5)
/* Computed output color: color(xyz-d65 0.412426 0.212648 0.0193173 / 0.5) */
```

The following examples use {{cssxref("calc")}} functions to calculate new channel values for the output colors that are relative to the origin color channel values:

```css
color(from hsl(0 100% 50%) srgb calc(r - 0.4) calc(g + 0.1) calc(b + 0.6) / calc(alpha - 0.1))
/* Computed output color: color(srgb 0.6 0.1 0.6 / 0.9) */

color(from hsl(0 100% 50%) xyz calc(x - 0.3) calc(y + 0.3) calc(z + 0.3) / calc(alpha - 0.1))
/* Computed output color: color(xyz-d65 0.112426 0.512648 0.319317 / 0.9) */
```

> **Note:** Because the origin color channel values are resolved to `<number>` values, you have to add numbers to them when using them in calculations, even in cases where a channel would normally accept `<percentage>`, `<angle>`, or other value types. Adding a `<percentage>` to a `<number>`, for example, doesn't work.

### Formal syntax

{{csssyntax}}

## Examples

### Using predefined colorspaces with color()
### Using predefined color spaces with color()

The following example shows the effect of varying the lightness, a-axis, and b-axis values of the `color()` function.

Expand Down Expand Up @@ -93,11 +201,11 @@ div {

#### Result

{{EmbedLiveSample("using_predefined_colorspaces_with_color")}}
{{EmbedLiveSample("using_predefined_color_spaces_with_color")}}

### Using the xyz colorspace with color()
### Using the xyz color space with color()

The following example shows how to use the `xyz` colorspace to specify a color.
The following example shows how to use the `xyz` color space to specify a color.

#### HTML

Expand Down Expand Up @@ -136,11 +244,11 @@ div {

#### Result

{{EmbedLiveSample("using_the_xyz_colorspace_with_color")}}
{{EmbedLiveSample("using_the_xyz_color_space_with_color")}}

### Using color-gamut media queries with color()

This example shows how to use the [`color-gamut`](/en-US/docs/Web/CSS/@media/color-gamut) media query to detect support for a particular colorspace and use that colorspace to specify a color.
This example shows how to use the [`color-gamut`](/en-US/docs/Web/CSS/@media/color-gamut) media query to detect support for a particular color space and use that color space to specify a color.

#### HTML

Expand Down Expand Up @@ -187,6 +295,81 @@ div {

{{EmbedLiveSample("using_color-gamut_media_queries_with_color")}}

### Using relative colors with color()

This example styles three {{htmlelement("div")}} elements with different background colors. The middle one is given the unmodified `--base-color`, while the left and right ones are given lightened and darkened variants of that `--base-color`.

These variants are defined using relative colors — the `--base-color` [custom property](/en-US/docs/Web/CSS/--*) is passed into a `color()` function, and the output colors have their `g` and `b` channels modified to achieve the desired effect via `calc()` functions. The lightened color has 15% added to those channels, and the darkened color has 15% subtracted from those channels.
estelle marked this conversation as resolved.
Show resolved Hide resolved

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

#### CSS

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

.item {
flex: 1;
margin: 20px;
}
```

```css
:root {
--base-color: orange;
}

#one {
background-color: color(
from var(--base-color) display-p3 r calc(g + 0.15) calc(b + 0.15)
);
}

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

#three {
background-color: color(
from var(--base-color) display-p3 r calc(g - 0.15) calc(b - 0.15)
);
}

/* Use @supports to add in support old syntax that requires r g b values
to be specified as percentages (with units) in calculations.
This is required for Safari 16.4+ */
@supports (color: color(from red display-p3 r g calc(b + 30%))) {
#one {
background-color: color(
from var(--base-color) display-p3 r calc(g + 15%) calc(b + 15%)
);
}

#three {
background-color: color(
from var(--base-color) display-p3 r calc(g - 15%) calc(b - 15%)
);
}
}
```

#### Result

The output is as follows:

{{ EmbedLiveSample("Using relative colors with color()", "100%", "200") }}

## Specifications

{{Specifications}}
Expand All @@ -198,5 +381,7 @@ div {
## See also

- [The `<color>` data type](/en-US/docs/Web/CSS/color_value) for a list of all color notations
- [Using relative colors](/en-US/docs/Web/CSS/CSS_colors/Relative_colors)
- [CSS colors](/en-US/docs/Web/CSS/CSS_colors) module
- [`color-gamut`](/en-US/docs/Web/CSS/@media/color-gamut) media feature
- [Wide Gamut Color in CSS with Display-p3](https://webkit.org/blog/10042/wide-gamut-color-in-css-with-display-p3/)
Loading
Loading