flashman
← All posts

CSS color-mix percentage debugging

Debug a CSS color-mix that looks wrong by naming the interpolation space and checking whether the two percentages sum below 100, which lowers the alpha.

2026-10-15 · 6 min read · Rahul Chitturi

  • css
  • color
  • design-systems

color-mix() blends two colors in a color space you name. The space changes the midpoint, and the percentages change the alpha. A mix that looks muddy or washed out is often doing exactly what the declaration says.

The in keyword is required. in srgb mixes the gamma-encoded channels. in srgb-linear mixes light linearly, so the same 50/50 red and blue is lighter than the srgb midpoint. in oklch or in hsl also interpolates hue, and the default hue path is the shorter arc.

Read the percentages before the channels

If both percentages are omitted, each color is 50%. If one is omitted, it becomes 100% minus the other. If the two numbers sum to more than 100%, they are scaled down until they sum to 100%, and the mix stays opaque.

If they sum to less than 100%, the color ratio is still normalized, then the alpha is multiplied by that sum. color-mix(in srgb, #ff0000 40%, #0000ff 40%) is a 50/50 mix at 80% alpha, not an opaque color that is 40% of each. A transparent mix on a white page looks pale. On a dark page it looks dirty.

  • Write both percentages when the alpha should stay at 1.
  • Treat a sum below 100% as an alpha change.
  • Scale a sum above 100% in your head before you blame the space.
  • Check the computed color, not only the authored rule.

Name the hue path on polar spaces

Shorter is the default. From red to blue, the short hue arc goes through magenta, so the midpoint is purple. The long arc goes through yellow and green. If the design wanted that rainbow, the declaration has to say longer hue, increasing hue, or decreasing hue.

When the two hues are 180 degrees apart, there is no unique short arc. Pick increasing or decreasing if the direction matters. A premultiplied mix also pulls a translucent endpoint toward transparent, so its RGB contributes less than the percentage suggests.

Compare the painted hex with both endpoints

Copy the computed hex from the element that looks wrong. Compare it with the two endpoints in the same space you wrote. If the computed color is more transparent than either endpoint, the percentages summed below 100%.

Use Flashman's color tool on the painted hex and the surface behind it, the CSS formatter to read the color-mix declaration, and diff to compare the source rule with the built stylesheet. The color tool does not evaluate color-mix. It shows the hex the browser already computed.

Try these tools