WebCraft

color-mix()

The same two colours, mixed two ways

in srgb

in oklch

CaveatThe colour space is required, and it decides the answer: srgb runs the midpoint through grey, which is why a derived hover tint so often looks washed out compared to the swatch the designer picked. Then the percentages, which are the part nobody reads: they are normalised rather than rejected, so 30% and 30% is a 50/50 mix — but because they add up to less than 100%, the result also comes back at 60% alpha. A colour that is both the wrong ratio and quietly translucent, from a line that looks arithmetically fine. currentColor is allowed inside, which is what lets one rule tint every state of a component that has not picked its colour yet.

FallbackAn engine that does not know the function drops the whole declaration, not just the value, so the property falls back to whatever was declared before it in the same block. That fixes the order: the plain colour first, the mix second. Written the other way round the fallback wins everywhere and the mix never applies at all.

CSS
.btn:hover {
  /* plain first: an engine that drops
     the mix keeps this one */
  background: #7fb4e2;
  background: color-mix(
    in oklch, #6fa8dc 75%, #f6b26b);
}

/* 30% and 30% is a 50/50 mix at
   60% alpha, not the colour typed */

Published

Questions

<details name>

Why is my color-mix() hover colour washed out?

Almost always in srgb. Interpolating two saturated colours through sRGB runs the midpoint close to grey. in oklch keeps the chroma up across the whole ramp.

Do the two percentages have to add up to 100?

No, and that is the trap. They are normalised, so 30% and 30% mixes 50/50 — but a sum below 100% is also applied as alpha, so the result comes back 60% opaque. Give one percentage and let the other be implied.

What happens in a browser without color-mix()?

The whole declaration is dropped, so the property keeps the last value it understood. Declare the plain colour first and the mix on the line after it; reversed, the fallback wins everywhere.