demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

So Long, CSS Sprites: Use CSS3 Filters To Create Icon Rollover Effects

css / filters

Estimated reading time: 3 minutes, 36 seconds

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 , 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 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; }
Home Work User

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.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.