CSS rollover effects on text have been used for a long time, and I’ve demonstrated many variations on the concept in past articles. More recently icon fonts have made the creation of UI elements far easier. For everything else – in which a link requires a hover effect but is not text, nor something that can be encoded as a font – the traditional solution has been CSS sprites.
The limitations of CSS sprite images are well known:
- Tricky to make (although there are tools that can streamline the work)
- Difficult to adjust or change once they are in place
- Sprite images often double the file size of single-image bitmap files
In many cases, image sprites could be replaced with CSS filters, which have none of these drawbacks.
CSS Filters For UI Elements

I’ve covered filters in past articles, but usually in the context of photographic effects: making images black and white using CSS, for instance. I haven’t applied the techniques to UI elements until now, an innovation inspired a web development student who was using an ersatz image sprite as the logo of his portfolio, and wanted a better solution.
You can see the completed logo effect to the left: mouseover the image to see the effect. It’s entirely reasonable to present the logo as an image: it’s not worthwhile embedding the required fonts (Avenir and Avenir Next, in this case) in the web page solely for the use of a logo, so creating it as an alpha-masked PNG makes sense.
The transition the student wanted to achieve was to have the logo shift from white to hot pink on mouse rollover. Rather than creating two versions of the image, we’ll just place the original version, in pink, on the page:
<img src="aaron-baranec.png" alt="Aaron Baranec Art & Design" id="logo">
We want this image to be white: first, we’ll make it greyscale. (Note that I’m using a non-vendor-prefixed version of the filter; for the sake of completeness, it should be preceded by a –webkit
prefixed version at the very least).
img#logo {
width: 303px;
height: 81px;
filter: grayscale(100%);
}
The problem is that the filter produces – not surprisingly – a grey result. We want to lighten the image, so let’s pair the greyscale filter with one to control brightness:
img#logo {
width: 303px;
height: 81px;
filter: grayscale(100%) brightness(100%);
}
That creates the result we’re after. To achieve the equivalent in current versions of Firefox, we need to use the original SVG syntax of the filter. The SVG code could be saved as a separate file, or embedded somewhere on the same page as the image. I’ll choose the latter approach:
<img src="aaron-baranec.png" alt="Aaron Baranec Art & Design" id="logo">
<svg version="1.1" xmlns=//www.w3.org/2000/svg" height="0">
<defs>
<filter id="desaturate">
<feColorMatrix type="matrix" values="1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 0 0 1 0"/>
</filter>
</defs>
</svg>
(The matrix math is a little complicated to explain here, so it’s entirely okay to copy and paste the SVG code).
To use both filters and achieve cross-browser compatibility, our CSS changes to:
img#logo {
width: 303px;
height: 81px;
filter: grayscale(100%) brightness(100%);
filter: url(#desaturate);
}
With appropriately vendor prefixed versions of the filter code, that’s all we have to do. To turn the image into full color on hover, we just need to switch the filters off:
img#logo { filter: none; }



We can even transition the change in Webkit browsers, as shown in the example.
Other variations
It’s possible to use a similar effect to change the color of icons with a hue-rotate
filter. hue-rotate
works on the color wheel you should be familiar with from the CSS3 HSL color system, "twisting" the hue of elements by a specified number of degrees. As one possibility, this allows you to shift the color of red bitmap icons to yellow:
img:hover {
filter: hue-rotate(60deg);
filter: url(#huetwist);
}
The SVG equivalent code:
<svg version="1.1" xmlns=//www.w3.org/2000/svg" height="0">
<defs>
<filter id="huetwist">
<feColorMatrix type="hueRotate" values="60"></feColorMatrix>
</filter>
</defs>
</svg>
There’s nothing to stop you using the concept of CSS sprites together with these techniques. I’d suggest that CSS filters offer many more possibilities for UI enhancement than the traditional sprite approach by itself, creating a field that is ripe for exploration.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.