updated: March 4th, 2009 / Ross Johnson / 16 Comments

Accessible CSS roll over images

While some might claim that with the increase in typography control in css, and the number of people browsing with anti-aliased fonts(not that many, thanks microsoft! *cough* cleartype *cough*) that one no longer needs roll-over images. The argument being that they require a preloader, increase download times, and they are really not that accessible. I disagree however –

By mixing a few css techniques we can obtain fully accessible roll over images with out a whole lot of extra code or require extra javascript/dom.

We will start with the HTML so we can build the basic structure and totally separate design from content. Our goal is to have accessible mark-up, so we want our menu of roll over images to be a list, and have a text link for alternative needs (screen readers, text browsers, handhelds, etc.)

Now we have a menu that is a list, and it has a text link so it is accessible. We do want it to look visually pleasing however, and have a roll-over effect. We also don’t need the bullet that a list, nor the margins. So into CSS we dive to remove the list styling and add some style of our own!

The next step is designing the roll over image itself. I went ahead and designed an image in three different states (roll over, active, and visited) as seen here:

Front Page Active Button

Front Page Visited Button

Front Page Rolled Over

While we could simply swap the background on the different events in CSS, we would have to preload each image, and it still gets a flickering effect in IE. The solution is simple, browsers render the movement of a background image quicker than swapping one. So I created an image with all three states together plus a default state for the image.

Roll Over to see it hereFront Page Button, Combined

Each rendition of the button is 116 pixels wide, so we will set the width of our button to 116 px, set the background to our roll over image, and it will only show the first 116 pixels (or our first button.) When we want to change which rendition it is showing, we will use the background-position: tag in css to shift it over 116 or more pixels.

To start this, we will create a class for a li element:

Now we can change our HTML to:

The li element is now a block, and has the height/width and background we assigned it. Now all it needs is some basic functionality.

Back into CSS, lets define some states for hovering, and visited links.

This will shift the background image to the left in 116 pixel increments, resulting in a roll-over effect.

We still have the text link over the image however – which looks pretty crappy. Lets get that out of there while still ensuring that screen readers, text browsers, and hand helds can see it. This will be done using Mike Rundle’s Image Replacement technique.

We change our li.frontpage a tag to the following…

The text-indent pushes the text out of the field, and by designating a hidden overflow it is not rendered on the screen. Text browsers, screen readers, handhelds, and those browsing with out style sheets will see the text links however and it remains fully accessible!

Here is the end result!

It was pointed out on digg that if the images don’t load (or are turned off, but css is on) then you get nothing. This is true, and some people probably still browse with css on but images off… so here is the suggested alternative.

The CSS:

16 thoughts Accessible CSS roll over images

  1. Pingback: aNieto2K - » Roll-over de imagenes accesibles con CSS

  2. Pingback: » 2nd hand dig effect - Web Design - 3.7crea.tv Blog

  3. I’ve looked at this page in IE 6, Firefox 1.5, and Opera 9. I don’t see the rollover effect.

    I couldn’t find a #frontpage class in the CSS linked from this page.

    George V. Reilly
  4. Pingback: » Hello Rebooters - Web Design - 3.7crea.tv Blog

  5. This was the PERFECT solution I needed for a image rollover effect in a tabbed css menu! Thanks for laying this out there, I had pillage through CSS rubble for about a whole day until I found this.

  6. Thank you for your very useful tutorial.
    Only two things:

    there’s a typo here, an extra opening brace, search for this line:

    background: url((images/fp.gif);

    when you first talk about “li.frontpage a” you use “display: block;”, then you add text-indent and overflow but “display: block;” disappears ad if it is missing the behavior will not be as expected.

  7. Hellow
    mieledivespa,thanks for sharing your knowledge.i will try it out today.Article does a great job expounding upon the essential points of building great apps. Thx!

    Steve Mac

  8. i like this better


    page 2


    .??? a
    display: block;
    background-image: url(images/image01.jpg);
    width: XXXpx;
    height: XXXpx;
    text-indent: -999999px;
    overflow: hidden;

    .??? a:hover
    background-image: url(images/image02.jpg)

    uses less code than a list
    (i know it uses image replacement)
    feel free to discuss, dissect or squash

  9. what on earth… html didnt work???

    should be


    div class=”bus”> gallery01 ” at beginning and end respectively)

  10. Well for most navigation semantically you want to use a list because navigation really is, a list of links. You don’t have to use a list for this technique, it just fits most situations :).

    The reason that I have it so it switches background position rather than load a new image is some browsers have a delay in rendering that second image so you get flashing (either initially or all the time), where moving the position of an image is instant.

    -Ross Johnson

  11. Excellent work. CSS is magic. The technique implemented is very fast. Just load image onece and create effect. Fantastic.

  12. If anyone can help me with the scroll that http://www.3point7designs.com is using on a page devided that is scrolling from right to left.

  13. Pingback: Basit Resimli Menü Yapmak / Fatih Hayrioğlu’nun not defteri

Comments are closed.

Free WebinarOur proven method of increasing website leads by 400% or more using design psychology

That anyone can implement, even if you're not a designer or developer.

Join me on April 8th at 11:00am EST time and you'll learn:

  1. How to understand your target audience so you can excite them and drive them towards action
  2. How to capture prospects before they’re ready to reach out, so you can build a relationship and nurture them towards a sale
  3. How to avoid the #1 mistake on websites that causes lackluster results
  4. A step by step process to realign your website around your target audience’s psychology

Plus we'll provide downloadable templates and checklists so you can implement what you learn on your own!