CSS color recipe
Relative colors Hover, disabled and chip colors derived from one brand color
Relative color syntax takes a color apart into its channels and lets you change any of them: oklch(from var(--brand) calc(l - 0.08) c h) is the brand, 8 points darker. States stay tied to the brand without a second palette.
- Baseline
- Newly available
- First versions
- Chrome 125 · Firefox 128 · Safari 18
- Tested
- 3 of 3 engines
Live example
The recipe, running
Left: the CSS below, as your browser runs it. Right: the same CSS as a browser without the feature reads it, so you see exactly what the fallback gives.
Turn on JavaScript to see whether your browser supports it; the examples work either way.Your browser supports it, so the left example runs the modern path.Your browser does not support it yet, so both examples show the fallback.
The CSS
Copy it as it is
This is the exact CSS the example runs. Fallbacks come first; the modern values follow, so each browser keeps the last line it understands.
relative-color.css
:root { --brand: #3959DA; }
.button { padding: 10px 18px; border: 0; border-radius: 8px; background: var(--brand); color: #ffffff; font: inherit; }
.button:hover, .button.is-hover { background: #273FBE; }
.button:disabled { background: rgb(57 89 218 / 0.45); }
.chip { padding: 4px 12px; border-radius: 999px; background: #E9EEFC; color: #243B9C; }
@supports (color: oklch(from red l c h)) {
.button:hover, .button.is-hover { background: oklch(from var(--brand) calc(l - 0.08) c h); }
.button:disabled { background: oklch(from var(--brand) l c h / 0.45); }
.chip {
background: oklch(from var(--brand) 0.95 calc(c * 0.1) h);
color: oklch(from var(--brand) 0.4 calc(c * 0.8) h);
}
}
How it works
What each part does
Channels are numbers. Inside
oklch(from …),l,candhare plain numbers, socalc()can shift them and/ 0.45sets the alpha.The fallbacks are those results. Each hex is the derived OKLCH color converted to sRGB; every one is inside sRGB, so it matches.
Safari 18 or later. Earlier Safari versions read relative colors with an older version of the syntax, which is why the support table starts there.
Browser support
Where it runs
First version of each browser with the feature, from the web-features project and MDN’s browser-compat-data. “No” means not supported yet.
- Relative colorsNewly availableBaseline newly available since 16 September 2024: every core browser has it, but older versions in use may not.
| Browser | Relative colors |
|---|---|
| Chrome | 125 |
| Chrome for Android | 125 |
| Edge | 125 |
| Firefox | 128 |
| Firefox for Android | 128 |
| Safari | 18 |
| Safari on iOS | 18 |
Support reviewed on against web-features 98723fd and browser-compat-data 3b28abe.
Tested
Tested in three engines
| Engine | Version | Supported | As written | Fallback |
|---|---|---|---|---|
| Chromium | 147.0.7727.15 | Yes | Pass | Pass |
| Firefox | 148.0.2 | Yes | Pass | Pass |
| WebKit | 26.4 | Yes | Pass | Pass |
Run on in Chromium 147.0.7727.15, Firefox 148.0.2 and WebKit 26.4, with Playwright.
Accessibility
Measured, not assumed
White on the hover color measures 8.27:1; the chip’s text measures 8.30:1 on its background.
- 8.27:1AAA
#FFFFFF / #273FBE - 8.30:1AAA
#243B9C / #E9EEFC
References
Go to the source
- CSS Color Module Level 5: relative colorswww.w3.org
- web-features at 98723fdgithub.com
- MDN browser-compat-data at 3b28abegithub.com