Frontend Quick Tips #17 Changing the Color of a Multicolored Icon

No one likes those big articles - that’s why we’re creating Quick Tips - short tips to change your developer's life from the moment you read them.
Those may be some patterns explained in JS code on real-life examples or some techniques for better code.
Problem
Let’s assume that you have a multicolored icon in your project and you’d like to change its color on hover.
Example
<svg
xmlns="http://www.w3.org/2000/svg"
width="17"
height="16"
viewBox="0 0 17 16"
>
<g fill="none" fill-rule="evenodd">
<path
fill="red"
d="M15.3 0H1.7C.76 0 .008.716.008 1.6L0 16l3.4-3.2h11.9c.94 0 1.7-.716 1.7-1.6V1.6c0-.884-.76-1.6-1.7-1.6z"
/>
<path
fill="blue"
d="M3 3H14V4H3zM3 6H14V7H3zM3 9H14V10H3z"
/>
</g>
</svg>
Let’s take this icon as an example. A common approach to this problem is to override the color by selecting nested SVG elements inside styles like so:
svg {
&:hover {
g {
path:first-child {
fill: yellow
}
path:last-child {
fill: green
}
}
}
}
But there’s a better way to address this type of situation.
Solution
An effective way to handle the mentioned issue is by using CSS variables.
The procedure is simple: change the value of the icon’s fill property from a hard coded color to something like this:
<svg
xmlns="http://www.w3.org/2000/svg"
width="17"
height="16"
viewBox="0 0 17 16"
>
<g fill="none" fill-rule="evenodd">
<path
fill="var(--icon-primary)"
d="M15.3 0H1.7C.76 0 .008.716.008 1.6L0 16l3.4-3.2h11.9c.94 0 1.7-.716 1.7-1.6V1.6c0-.884-.76-1.6-1.7-1.6z"
/>
<path
fill="var(--icon-secondary)"
d="M3 3H14V4H3zM3 6H14V7H3zM3 9H14V10H3z"
/>
</g>
</svg>
The next step is to change the styles to:
svg {
--icon-primary: red;
--icon-secondary: blue;
&:hover {
--icon-primary: yellow;
--icon-secondary: green;
}
}
And if you’d like to change only one color of the icon, then you can use the “currentColor” value and do something like this:
<svg
xmlns="http://www.w3.org/2000/svg"
width="17"
height="16"
viewBox="0 0 17 16"
>
<g fill="none" fill-rule="evenodd">
<path
fill="currentColor"
d="M15.3 0H1.7C.76 0 .008.716.008 1.6L0 16l3.4-3.2h11.9c.94 0 1.7-.716 1.7-1.6V1.6c0-.884-.76-1.6-1.7-1.6z"
/>
<path
fill="blue"
d="M3 3H14V4H3zM3 6H14V7H3zM3 9H14V10H3z"
/>
</g>
</svg>
Finally, change your styles to:
svg {
color: red;
&:hover {
color: yellow;
}
}
Voilà!