Huge news! Outfit is joining the Smartsheet family. Read more here.

Dynamically themeable websites using CSS current Colour

John Morris — 4 July 2016


First of all, what is currentColor?

CSS currentColor is exactly what is sounds like. It will take the elements' current computed color value and allow other properties to use it.

Using currentColor to create themeable content

If you set the color on the html or body elements you can pick and choose different elements to use the currentColour as one of their properties. If you then let people change that value, all of the elements using the html’s currentColour will update too.

I’m not going to re-create the demo in this post, I’m just going to go over some of the techniques I’ve used creating it.

Change the color being inlined on the html element below to see it in action.

See the Pen <a href=''>Creating a theme-able website with currentColor</a> by John Morris (<a href=''>@Johnm__</a>) on <a href=''>CodePen</a>.

Applying that demo to a template in Outfit

Instead of creating the color input at the top of the screen, and writing that little snippet of javascript to set the value of the input to the html font color like I’ve done in the demo, In our index.html.mst we can just create an input in the style attribute of the html.

<html style="color: {{ template-color }} ;">

and as long as the value being entered is a valid css color value, it’s smooth sailing.

1. Basic usage

I’m going to create a div nested inside another div, set the parent’s color to blue, and then set the child elements' background to currentColor. Just so we can see what happens.

<div class="div-1"> I'm blue <div class="div-2"> da ba dee da ba die </div> </div>.div-1 { color: blue; background-color: #f2f2f2; } .div-2 { background-color: currentColor; }

Aaaaand the result:

I’m blue da ba dee da ba die


Well, it’s working, but it doesnt seem to be too useful. What’s the point of setting the background color to the text color, you can’t see anything…

If we set the color of div-2 to white, It’ll have a blue background because of its parent, and the white text will make it legible again, right?

I’m blue da ba dee da ba die


Because the color of the element has changed, so has the currentColor property.

The way I fix this is putting a span inside whatever element I want to set the background of. That span will ensure the text stays white without changing the currentColour of the div with the blue background

<div class="div-1"> I'm blue <div class="div-2"> <span class="whitetext"> da ba dee da ba die </span> </div> </div>.div-1 { color: blue; background-color: #f2f2f2; } .div-2 { background-color: currentColor; } .white { color: white; }

Aaaaand the result:

I’m blue da ba dee da ba die

Woooo! And if the text color of div-1 changes?

I’m blue da ba de… oh.  This is essentially all I’ve done for 90% of that demo.

Lightening and darkening the currentColor

This one would be a walk in the park in sass land with lighten() and darken(), but, we’re not in sass land. No nesting, no loops, no mixins and no color functions. But what about the button in the demo? well…

background-image: linear-gradient to the rescue!

because gradients are background images, and an element can have both background-color and background-image, and the background-image always sits infront of the background-color, if we set the background-image to a linear-gradient that uses two identical rgba() values (so the gradient is a solid color) we can have a semi-transparent overlay above the color, effectively darkening it.

Instead of putting a span in my earlier example and making the text white, I’m going to darken the background with a translucent gradient.

<div class="div-1"> I'm not blue anymore <div class="div-2"> and I'm somewhat legible again </div> </div>.div-1 { color: red; background-color: #f2f2f2; } .div-2 { background-color: currentColor; background-image: linear-gradient (-180deg, rgba(0,0,0,0.50) 0%, rgba(0,0,0,0.50) 100%); }I’m not blue anymore And I’m somewhat legible again

This is how I created the hover states, the artwork under the hero, and the lightened and darkened sections.

Instead of using 20% black, try using 80% white, or other colours and blend modes for different effects.

Go forth and theme-ify

You can use currentColor to fill an SVG, set backgrounds, borders and whatever else you might want to do with it. It’s exactly the same as using a color.