CSS color-mix() Generator: Blend Colors in Any CSS Color Space
Learn how the CSS color-mix() function works and how to blend two colors in sRGB, OKLab, OKLCH and more with a live preview and copy-ready CSS.
Table of Contents
For years, blending two colors in CSS meant reaching for a preprocessor like Sass, copying hex values out of a design tool, or shipping a small JavaScript utility just to compute a hover state. The CSS Color 5 specification changed all of that with a single native function: color-mix(). Today you can write color-mix(in oklab, #ff6347 50%, #4682b4) directly in your stylesheet, and the browser blends the two colors for you β no build step, no runtime, no duplicated hex values drifting out of sync with your design tokens.
The catch is that color-mix() has a surprising number of moving parts. Which interpolation space should you use β srgb, oklab, oklch, or one of the nine others the spec supports? What does the percentage actually mean? Why does the same mix look muddy in one space and vibrant in another? The CSS color-mix() Generator answers all of these interactively: pick two colors, choose from twelve color spaces, drag a slider, and watch the result update live with copy-ready CSS underneath.
In this guide, we'll walk through how the generator works, what's happening under the hood when the browser interpolates colors, and the practical patterns that make color-mix() one of the most useful modern CSS features for design systems work.
Why Use the CSS color-mix() Generator?
- Zero setup, zero dependencies. The generator runs entirely in your browser. There is no account, no upload, and no color value ever leaves your machine β it is 100% client-side.
- All twelve interpolation spaces in one place. The CSS Color 5 spec defines srgb, srgb-linear, lab, oklab, xyz, xyz-d50, xyz-d65, hsl, hwb, lch, oklch, and display-p3 as valid spaces for color-mix(). The generator exposes every one of them in a single dropdown, so you can compare results side by side instead of guessing.
- Live preview before you commit. A three-swatch strip shows Color 1, the blended result, and Color 2 in real time. You see exactly what the browser will render β including the subtle differences between an oklab mix and an srgb mix of the same pair.
- Copy-ready output. The generated CSS is syntactically exact, with correct casing and percentage placement. Paste it straight into your stylesheet or your design token definitions without hand-editing.
- Flexible input formats. Paste colors as 3-digit (#f63), 6-digit (#ff6347), or 8-digit hex with alpha (#ff6347cc), or use the native color picker. Alpha is preserved through the mix, thanks to premultiplied alpha handling in the spec.
- A learning tool, not just a generator. Because you can flip between spaces instantly, the generator doubles as a sandbox for building intuition about perceptual color spaces β the fastest way to internalize why OKLab exists.
Key Features
| Feature | What it does |
|---|---|
| Two color inputs | Hex fields plus native pickers; supports 3-, 6-, and 8-digit hex |
| 12 color spaces | Every color-mix() interpolation space defined in CSS Color 5 |
| Percentage slider | Controls the amount of Color 1 from 0% to 100%, defaulting to an even 50/50 |
| Live 3-swatch preview | Color 1, blended result, and Color 2 rendered instantly as you adjust |
| Copy-ready CSS | Emits exact syntax like color-mix(in oklab, #FF6347 50%, #4682B4) |
| Client-side only | All computation happens in the browser; nothing is uploaded |
Two details are worth calling out. First, the slider semantics follow the spec's polar model: the slider represents the share of Color 1, and the remainder is implicitly Color 2 β so 50% is an even blend, 100% is pure Color 1, and 0% collapses to pure Color 2. Second, the tool validates your hex input as you type and falls back gracefully, so a half-typed value never crashes the preview.
Browser support for color-mix() itself is broad in 2026: Chrome 111+, Safari 16.2+, and Firefox 113+ all interpolate it natively, which covers effectively the entire evergreen browser population.
How to Use
- Open the CSS color-mix() Generator β the tool loads instantly with a sensible default pair, tomato #ff6347 and steel blue #4682b4.
- Set your two source colors using the hex fields or the native color pickers. Both 6-digit and shorthand formats work, and 8-digit hex keeps alpha.
- Choose an interpolation space from the dropdown. Start with oklab for general-purpose blending β it is the generator's default for good reason.
- Drag the percentage slider to control how much of Color 1 enters the mix. Watch the middle swatch update live as you move it.
- Click Copy next to the CSS output and paste the color-mix() declaration into your stylesheet, token file, or CSS custom property.
Understanding Color Interpolation Spaces
The single most important idea behind color-mix() is that "the color halfway between red and blue" is not a well-defined question until you name a color space. Each space interpolates along different axes, and the halfway point lands somewhere different in each one.
srgb and srgb-linear. The srgb space interpolates the familiar gamma-encoded RGB channels. It is fast and universally supported, but it is not perceptually uniform: midpoints tend to lose saturation and drift darker than expected β the classic "muddy middle" you see in RGB gradients between saturated complementary colors. srgb-linear interpolates in linear-light coordinates, which gives physically smoother luminance transitions and is the better choice when the mix feeds an opacity or blend effect.
hsl, hwb, lch. These cylindrical spaces interpolate hue as an angle, which preserves vibrancy across the mix β but also introduces hue-shift artifacts. In HSL, mixing yellow and blue can swing through green even when no green is perceptually "between" them for your design intent. LCH improves on lightness uniformity but still over-saturates midpoints for some hue pairs, producing colors that are more chromatic than either endpoint.
oklab and oklch. OKLab was engineered to be perceptually uniform: equal numeric steps correspond to roughly equal perceived changes. oklab blends lightness and color in a way that midpoints look naturally in-between β no muddy gray, no neon surprise. oklch adds a hue angle to that foundation, keeping mixes perceptually even while following hue rotation. For most UI work β hover states, tints, shades, borders β oklab is the pragmatic default, and that is why the generator ships with it preselected.
xyz, xyz-d50, xyz-d65, display-p3. The XYZ family are device-independent tristimulus spaces, mostly relevant when you need color-management-precise mixing for print pipelines or ICC workflows (d50 vs d65 refers to the white point). display-p3 interpolates inside the P3 gamut, useful for wide-gamut work where the result should stay representable on modern displays rather than being clamped to sRGB.
Two mechanics complete the picture. Premultiplied alpha: when one or both inputs have alpha, the spec premultiplies the color channels by alpha before interpolating and un-premultiplies afterwards, which prevents transparent colors from bleeding unexpected brightness into the result. The percentage: p1% means the result is pulled p1% of the way from Color 2 toward Color 1 along the interpolation line. If both percentages are given and sum to more than 100%, they are normalized β a detail that occasionally surprises people writing color-mix(in oklab, red 60%, blue 60%).
Practical Use Cases
Deriving tint and shade scales from a single token
Instead of hardcoding eleven hex values per brand color, define your base and derive the ramp: --brand-600: color-mix(in oklab, var(--brand) 80%, black) gives you a shade, while mixing with white at increasing percentages yields tints. One source of truth, an entire scale, and re-theming the site means changing exactly one variable.
Hover, pressed, and focus states without a preprocessor
The canonical pattern is background: color-mix(in oklab, var(--accent) 85%, black) for hover and a white mix for soft, disabled-looking states. This is what Sass lighten() and darken() always tried to be β but computed by the browser, in a perceptually even space, and always in sync with the token it derives from.
Dark-mode adjustments in one line
Dark themes usually need desaturated, slightly lifted versions of brand colors. color-mix(in oklab, var(--brand) 70%, #1c1c22) pulls a saturated accent toward your dark background, and the same declaration works for every accent because the mix references the token, not a literal. Combined with the light-dark() function pattern, a full dual-theme palette needs remarkably few declarations.
Accessible focus rings and contrast tuning
When an accent color sits too close to a background, blending toward black or white in oklab nudges its lightness β and therefore its contrast β in controlled steps. Generate a few candidate mixes in the tool, then verify the winning pair with the Color Contrast Checker to confirm you meet WCAG thresholds before shipping.
Best Practices
- Default to oklab for UI state colors. Reach for other spaces deliberately: oklch when you want controlled hue rotation, srgb when matching an existing gradient, display-p3 for wide-gamut assets.
- Mix with currentColor for theming. color-mix(in oklab, currentColor 70%, transparent) creates translucent variants that automatically follow inherited text color β perfect for icons, dividers, and subtle borders.
- Store mixes as custom properties. Wrapping the function in --hover: color-mix(...) at the token layer keeps components clean and makes the derivation auditable in one place.
- Test both endpoints of your slider. Check the 0% and 100% extremes and a mid value β a space that looks fine at 50% can behave oddly near its boundaries, especially with alpha involved.
- Use relative color syntax for transforms. Pair color-mix() with relative color (the from keyword) when you need channel-level adjustments like oklch(from var(--brand) calc(l + 0.1) c h).
- Verify contrast, don't assume it. A perceptually even blend changes lightness in perceptual units, not contrast ratios; always check text-bearing mixes against WCAG minimums.
Start Mixing
The color-mix() function removes one of the last everyday reasons to keep a preprocessor or a color-math library in your stack. Once your tints, shades, hover states, and theme adjustments all derive from a handful of tokens, re-thaming becomes a one-variable change and your palette stops drifting.
Open the CSS color-mix() Generator, drop in your two colors, and compare srgb against oklab on the same pair β the difference is the fastest way to understand what perceptual interpolation buys you. Everything runs locally in your browser, and the output is always paste-ready CSS.
Happy mixing!