Extending the Color Cascade with the CSS currentColor Variable
If you use Sass or LESS, then you probably already use variables in your style sheets and know how useful they are. If you don’t use a preprocessor, then you might be curious what the fuss is all about and why variables are so popular and how they can be useful. In this article, we’re going to get an overview of why variables are useful, and get acquainted with one particular variable: currentColor
.
What are variables good for?
Variables in CSS are useful because they allow us to write more DRY (Don’t Repeat Yourself) code. They are also particularly useful for managing and maintaining large-scale projects that contain a lot of repeated values.
One of the most common use cases for variables are color themes/schemes throughout a website or application. With variables, creating and managing color schemes across a CSS document becomes a lot easier. For example, color schemes usually require you to reuse a few color values for different properties in the CSS file. If you want to change the primary color of a scheme, you would normally have to change all occurrences of that color in the style sheet. Using CSS variables, you can define a variable in one place (for example a variable named “primary-color”), assign a color value to it, and then use the variable as a value anywhere you want in the style sheet. Then, when the time comes to change this color, all you would have to do is assign it a different color value, and all occurrences of that variable in the style sheet will be automatically updated.
CSS 2.1 did not introduce variables. (Although, that’s not entirely true, as you will see in this article.) In 2014, native CSS variables that are similar to preprocessor variables were introduced; these variables are arguably even more capable than preprocessor variables. A CSS variable is accepted as a value by all CSS properties.
In addition to the new variables, CSS already comes with a keyword value that is practically also a variable: the currentColor
keyword.
The currentColor
keyword
The currentColor
keyword is like a CSS variable, except that it has one main restriction: you can only use it where a value is expected; if a property does not accept a “value, it will not accept currentColor
as a value.
The following are all examples of using currentColor
in properties that accept it as a value.
box-shadow: inset 2px 2px 3px currentColor;
background-color: currentColor; /* not a good idea! */
background-image: linear-gradient(currentColor, transparent);
Another difference between currentColor
and other variables is that you don’t get to assign a value to it the same way you would assign other variables values. The value of currentColor
is determined by the computed value of the color
property that is currently being used on the element. That is, the value of currentColor
is equal to the current color
property value. And this is where the currentColor
name comes from.
So, if we were to go back to our previous example, the currentColor
keyword sets the box shadow color to whatever color
value you have set on the div
. If you haven’t set any color
, it will use the inherited color from any of the div
’s ancestors. If no ancestor has a color
, most browsers will just default to black.
Put another way: the currentColor
keyword is used to make properties of an element, or child elements of an element, inherit the color set by the element’s color
property. It therefore acts as the inherit
value to allow inheritance of a color that would otherwise not be inherited by a property or child element.
This also means that, for properties that already inherit the color
value, currentColor
will not be of much use.
Properties and elements that inherit the color
value by default
When an element has a color
value, whether it is explicitly set or inherited, some of the foreground elements of that element that accept a “value will inherit that color
value by default.
For example, an element’s borders are part of the element’s foreground; thus, even if you don’t specify a border color, the border will get the same color as the color
property value. If the element does not have one, most browsers usually default to black.
The border color in this example will be purple:
.parent {
color: purple;
}
.child {
border: 5px solid; /* we didn’t specify the border color here */
}
The elements that will get/inherit the element’s color
value include:
- The element’s text—it is what the
color
property is used for. - The text’s outline.
- The element’s border.
- The element’s box shadow.
- An
img
’salt
text. That is, when the image cannot be displayed, the text that appears in its stead will have that color value. - A list item’s bullet(s) and border.
- In some browsers (e.g Chrome) the horizontal rule’s (`` ) border color. (Without a border, the color will not be affected.)
When you set these element’s properties on an element without explicitly assigning them a color, they will inherit the computed color
value of the element by default.
The following demo shows the above elements in action as they inherit the color
set on the page’s body
. Change the color
property value on the body to see these elements’ colors also change.
See the Pen currentColor — Adobe DW Blog by Sara Soueidan (@SaraSoueidan) on CodePen.
At this point, you might be wondering: if so many properties/elements already inherit the color
value, how or where can currentColor
be useful?
Extending color inheritance with currentColor
There are some places where retrieving the color
value and using it could come in handy. One example where currentColor
can be used that would not otherwise inherit the color
value is gradients. CSS gradient images, be that linear or radial gradients, do not inherit colors. By using currentColor
, you can make a linear gradient used as a background image, for example, adjust to match any color you specify somewhere else as the “primary color” of a theme.
background-image: linear-gradient(to bottom, currentColor, #fff);
Such an example was created by Scott Kellum who took this concept a little further and added an animation to the color
property. As the color
property animates, all the elements affected by that color will also animate their colors. See the Pen currentColor by Scott Kellum (@scottkellum) on CodePen.
This is a great example of using currentColor
, particularly the animation part.
However, more practical examples for currentColor
exist. Let’s take a look at some of them.
currentColor
Use Cases
The idea behind currentColor
is to extend the color cascade. This comes in handy in a lot scenarios.
currentColor
for theming UI components
From the previous demo, we can move to a more practical (and brilliant, I must say) use case for currentColor
demonstrated by Simon “Simurai” in a talk he gave at CSSConfau last year. The talk was about how we can use Flexbox, currentColor
and em
units inside UI components to quickly style entire Web Apps straight in the browser.
To demonstrate the usefulness of currentColor
, Simon created a set of UI elements, including some sliders. These elements have the same color scheme applied. For coloring the sliders and input types, he used the currentColor
variable to force the color
inheritance in the background color of the slider’s thumb and checkboxes that would otherwise not inherit that color.
Similarly, more UI components can be created that inherit a color
value that you would specify somewhere up in the cascade. With this, a UI theme is established on these components. Then, leveraging the cascade and currentColor
, you can change the main color
value and get a new set of colored components every time you do, thus practically automating the process.
The following GIF image shows that in action. Simon is using the browser devtools and the color picker in the browser to change the value of the color
property, and get a live preview of these changes on the components.
Using the browser’s devtools capabilities, you would be able to change the theme to your liking and then save the changes to your working files right from the browser. To learn all about it, refer to Simon’s talk and blog post.
currentColor
for theming and styling SVG
SVGs are great, but they come with a few styling quirks and limitations depending on how you use them. One such case is reusing parts of an SVG using the SVG “element.
If you’re not familiar with the element, you can read all about it [here](http://sarasoueidan.com/blog/structuring-grouping-referencing-in-svg/). The idea behind
is to reuse parts of an SVG anywhere we want these parts to appear on the page. By use
ing an SVG element, we’re practically creating a live copy of that element. This is similar to copy-pasting the element in a graphics editor, except that the copy is live—meaning that its characteristics can change as the original copy changes.
The element is used a lot when [creating SVG sprites](http://24ways.org/2014/an-overview-of-svg-sprite-creation-techniques/). An SVG containing all of the icons would be used as the sprite, and then we can insert individual icons from that sprite anywhere on the page, using
. You can read all about SVG creating sprites in this article.
When an element is use
d, however, the copy of its contents is cloned into a shadow DOM. This means that these contents cannot be selected and styled with CSS the way we would select and style SVG elements or even HTML elements present in the regular DOM. This is one reason why styling SVG icons created like that is limited.
Using currentColor
, we can work around this limitation but allowing a color we specify in CSS “leak” into the contents of the use
d SVG, by setting currentColor
as a value for the properties we want the color value to leak into.
So with an SVG icon used like so:
And assuming the #home
icon defined in the sprite sheet contains something like:
We can then apply styles to the icon and have the fill
color cascade down to the #roof
(which does not have a fill attribute above) and the color
value be inherited by the #bottom
rectangle’s fill
attribute:
.home-icon {
fill: red;
color: white;
}
The fill
color will cascade down from the svg
to use
and then to #roof
. The color
value will be used as a value for the #bottom
fill color because of currentColor
.
Fabrice Weinberg wrote an article about this technique a while back on his Codepen blog.
This technique comes in handy when you want to create multiple icons each having different colors; all you would have to do in that case is change the color
and fill
values in the CSS. An example of this usage is the following demo Fabrice shows in his post:
See the Pen Sass SVG Icons 1.1KB by Fabrice Weinberg (@FWeinb) on CodePen.
Of course, you can use currentColor
on multiple elements inside the SVG. However, as you probably have noticed, this only allows you to change two colors inside the SVG.
If you want to have more control over colors and specify more color values that you could leak into the SVG, you would need more variables; this is where the new CSS Variables specification will come in handy. You can read more about this here.
Final Words
In the previous examples, we saw how we can use currentColor
in multiple places, and then change the colors we want in one place and have that color be applied to those multiple places, instead of having created multiple occurances of the same color and then changed all of them. This helps us write shorter CSS, and provides us with some sort of automation, especially in situations like the UI components we saw in Simon’s talk.
With CSS Variables, you will be able to define your own set of variables and use them in similar and much, much more use cases, as the new variables will be valid values for any CSS property, not only those that accept “values. Dealing with SVG icons will certainly become easier, as will maintaining large-scale projects. Again, if you use a preprocessor, then you already know how useful variables are.
Can you think of more use cases for currentColor
? If so, make sure you share them in the comments below!