CSS color recipe
color-mix() Tints, hovers and overlays from one color
color-mix() blends two colors in the space you name. Mixing the brand with white, black or transparent gives a badge tint, a hover and an overlay that follow the brand when it changes.
- Baseline
- Widely available
- First versions
- Chrome 111 · Firefox 113 · Safari 16.2
- 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.
color-mix.css
:root { --brand: #3959DA; }
/* Fallbacks: the same mixes, worked out ahead of time. */
.badge { padding: 4px 12px; border: 1px solid #B4C7F7; border-radius: 999px; background: #E5ECFD; color: #1B2E79; }
.button { padding: 10px 18px; border: 0; border-radius: 8px; background: var(--brand); color: #ffffff; font: inherit; }
.button:hover, .button.is-hover { background: #2C46AF; }
.scrim { width: 120px; height: 44px; border-radius: 8px; background: rgb(57 89 218 / 0.4); }
@supports (color: color-mix(in oklab, red, blue)) {
.badge {
border-color: color-mix(in oklab, var(--brand) 35%, white);
background: color-mix(in oklab, var(--brand) 12%, white);
color: color-mix(in oklab, var(--brand), black 35%);
}
.button:hover, .button.is-hover { background: color-mix(in oklab, var(--brand), black 15%); }
.scrim { background: color-mix(in srgb, var(--brand) 40%, transparent); }
}
How it works
What each part does
Why not two declarations?
background: color-mix(…, var(--brand) …)containsvar(), so an old browser accepts it while parsing and only fails when it computes the value. By then the earlier declaration is gone and the background turns transparent.@supportsavoids that.Mix in Oklab. Mixing toward white or black in
oklabkeeps the hue steady; insrgba blue tint drifts toward purple.The fallbacks are the same mixes. Each hex was worked out in Oklab from the brand color, so both paths show the same tint.
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.
- color-mix()Widely availableBaseline widely available since 9 November 2025.
| Browser | color-mix() |
|---|---|
| Chrome | 111 |
| Chrome for Android | 111 |
| Edge | 111 |
| Firefox | 113 |
| Firefox for Android | 113 |
| Safari | 16.2 |
| Safari on iOS | 16.2 |
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
The badge text measures 10.36:1 on its tint, and white on the hover color 8.07:1.
- 10.36:1AAA
#1B2E79 / #E5ECFD - 8.07:1AAA
#FFFFFF / #2C46AF
References
Go to the source
- CSS Color Module Level 5: color-mix()www.w3.org
- CSS Conditional Rules Level 3: @supportswww.w3.org
- web-features at 98723fdgithub.com
- MDN browser-compat-data at 3b28abegithub.com