The short version
- The color-mix CSS function blends two colours in a named colour space, for example color-mix(in oklab, #7c3aed 40%, white).
- If you give only one percentage, the other colour gets the remainder; with none, the mix is half and half.
- Mixing in oklab keeps lightness even and avoids the grey middles that sRGB mixing produces between distant hues.
- Mixing a colour with transparent is the cleanest way to make a translucent version of a colour stored in a custom property.
- color-mix() works in all current major browsers, so it is safe for production with a plain colour as a fallback for very old ones.
On this page
The color-mix CSS function, color-mix(), blends two colours in a colour space you choose and returns a new colour. Write color-mix(in oklab, #7c3aed 40%, white) and you get a pale violet that is 40 percent violet and 60 percent white, mixed perceptually. It works in every current major browser. Paired with custom properties, it turns one brand colour into tints, shades, hover states and translucent overlays without a single hard coded hex.
color-mix() syntax
/* color-mix(in <colour space>, <colour> [<percentage>], <colour> [<percentage>]) */
.a { color: color-mix(in oklab, #7c3aed, white); } /* 50% each */
.b { color: color-mix(in oklab, #7c3aed 40%, white); } /* 40% violet, 60% white */
.c { color: color-mix(in oklab, #7c3aed, black 30%); } /* 70% violet, 30% black */
.d { color: color-mix(in srgb, #7c3aed 50%, transparent); } /* violet at half opacity */
.e { color: color-mix(in oklch shorter hue, #2563eb, #f59e0b); }Browser uses
Notes
Browser uses
Notes
Browser uses
Notes
Browser uses
Notes
Browser uses
Notes
Which colour space to mix in
The colour space decides the path between the two colours. In sRGB the browser averages red, green and blue numbers, which is fast to reason about but not how eyes see. Two distant hues pass through a dull grey on the way. In oklab the mix follows perceived lightness and colour, so the middle stays clean and the steps look even. Gradient interpolation explains the same choice for gradients, and the effect is easiest to see there.
color-mix() returns at 50 percent in that space: #808080 in sRGB, a light blue grey in oklab.- oklab for tints, shades and most everyday mixing. Even lightness, no grey dip.
- oklch when you want the hue to travel, for example blending two brand colours into a third that sits between them on the wheel.
- srgb for mixing with
transparentor matching older design tools that blend in sRGB. - srgb-linear for physically based light mixing, which reads brighter in the middle.
For the background on why perceptual spaces behave better, see OKLCH explained. Recent versions of the specification allow you to leave the colour space out and default to oklab, but support for that shorthand is newer, so write in oklab explicitly.
Tints and shades from one brand colour
The most useful pattern is a scale built from a single variable. Mix towards white for tints, towards black for shades. Change the variable and every step updates, which makes it ideal for multi brand products or themes chosen by the user.
:root {
--brand: #7c3aed;
--brand-100: color-mix(in oklab, var(--brand) 20%, white);
--brand-200: color-mix(in oklab, var(--brand) 40%, white);
--brand-300: color-mix(in oklab, var(--brand) 60%, white);
--brand-400: color-mix(in oklab, var(--brand) 80%, white);
--brand-500: var(--brand);
--brand-600: color-mix(in oklab, var(--brand) 80%, black);
--brand-700: color-mix(in oklab, var(--brand) 60%, black);
}--brand for any hex and the scale follows.#7c3aed, computed in oklab. Mixed in sRGB, the tints come out a little greyer and the shades a little flatter.Mixing with pure white and black is a starting point. For warmer tints, mix towards an off white such as #fdf6ec; for richer shades, mix towards a deep navy instead of black. That keeps the scale feeling like your brand rather than a generic ramp. Tints, tones and shades covers the colour theory.
Transparency with color-mix()
Before color-mix(), making a translucent version of a colour stored in a variable meant storing the channels separately. Now you mix with transparent. The amount you keep is the opacity.
.badge {
color: var(--brand);
background: color-mix(in srgb, var(--brand) 12%, transparent);
border: 1px solid color-mix(in srgb, var(--brand) 30%, transparent);
}
.button:hover {
background: color-mix(in oklab, var(--brand), black 12%);
}Common color-mix() mistakes
- Leaving out the colour space in code that must run in older browsers. The whole declaration is dropped, not just the space.
- Mixing with black for every shade. Shades of saturated colours go dull; mix towards a deep version of the hue instead.
- Expecting percentages under 100 to stay opaque.
color-mix(in oklab, red 20%, blue 30%)is half transparent. - Using hsl for tints. Lightness in hsl is not perceptual, so a yellow and a blue at the same mix look nothing like the same step.
Browser support and fallbacks
color-mix() has been available in Chrome, Edge, Firefox and Safari since 2023, and current support is listed on caniuse. If you need to cover very old browsers, declare a plain colour first and let the mixed one override it. Browsers that don't understand the second line ignore it.
.card {
background: #ede9fe;
background: color-mix(in oklab, var(--brand) 15%, white);
}A full theme built on these patterns, with light and dark modes, is in CSS variables for theming.
Mixing colours for gradients
color-mix() is handy inside gradients, where it can compute a middle stop from two brand colours so the blend never passes through mud. linear-gradient(135deg, var(--a), color-mix(in oklch, var(--a), var(--b)), var(--b)) gives you a third stop on the hue path between the two. The underlying problem is covered in muddy gradients.
If your brand colour lives in a Gradiently Mark, the Mark's recipe already holds a family of related colours chosen to work together, and the Market lets you search by colour words such as "deep violet" to find one built around the hue you start from.
Questions people ask
What does color-mix() do in CSS?
It blends two colours in a colour space you name and returns the result, for example color-mix(in oklab, red 30%, white).
Which colour space should I use with color-mix()?
Use oklab for tints, shades and most mixing, oklch when you want the hue to travel, and srgb for mixing with transparent.
How do I make a colour transparent with color-mix()?
Mix it with transparent: color-mix(in srgb, var(--brand) 20%, transparent) gives the brand colour at 20 percent opacity.
Is color-mix() supported in all browsers?
It works in current versions of Chrome, Edge, Firefox and Safari. Declare a plain colour first as a fallback for older browsers.
What happens if the percentages don't add up to 100?
Totals above 100 are scaled down. Totals below 100 are scaled up and the result becomes partly transparent.
Written by Gradiently
The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.
See our profile