Mixing Colors in Pure CSS

Avatar of Carter Li
Carter Li on (Updated on )

Red + Blue = Purple… right?

Is there some way to express that in CSS? Well, not easily. There is a proposal draft for a color-mix function and some degree of interest from Chrome, but it doesn’t seem right around the corner. It would be nice to have native CSS color mixing, as it would give designers greater flexibility when working with colors. One example is to create tinted variants of a single base color to form a design palette.

But this is CSS-Tricks so let’s do some CSS tricks.

We have a calc() function in CSS for manipulating numbers. But we have very few ways to operate directly on colors, even though some color formats (e.g. hsl() and rgb()) are based on numeric values.

Mixing colors with animation

We can transition from one color to another in CSS. This works:

div {
  background: blue;
  transition: 0.2s;
}
div:hover {
  background: red; 
}

And here’s that with animations:

div {
  background: blue;
  transition: 0.2s;
}
div:hover {
  animation: change-color 0.2s forwards;
}


@keyframes change-color {
  to {
    background: red;
  }
}

This is an keyframe animation that runs infinitely, where you can see the color moving between red and blue. Open the console and click the page — you can see that even JavaScript can tell you the current color at any exact point in the animation.

So what if we pause the animation somewhere in the middle? Color mixing works! Here is a paused animation that is 0.5s through it’s 1s duration, so exactly halfway through:

We accomplished that by setting an animation-delay of -0.5s. And what color is halfway between red and blue? Purple. We can adjust that animation-delay to specify the percentage of two colors.

This works for Chromium core browsers and Firefox. In Safari, you must change animation-name to force browser to recalculate the animation progress.

This trick can also be used for adding alpha channel to a color, which is typically useful for theming.

Getting the mixed color to a CSS custom property

This is a neat trick so far, but it’s not very practical to apply an animation on any element you need to use a mixed color on, and then have to set all the properties you want to change within the @keyframes.

We can improve on this a smidge if we add in a couple more CSS features:

  1. Use a @property typed CSS custom property, so it can be created as a proper color, and thus animated as a color.
  2. Use a Sass @function to easily call keyframes at a particular point.

Now we still need to call animation, but the result is that a custom property is altered that we can use on any other property.