An issue that has stressed the relationship between web performance and accessibility is the little known fact that CSS image sprites, a technique used to reduce image HTTP requests, dissappear in Microsoft Windows’ high contrast mode. This is because they are typically created using the background-image CSS property.

To demonstrate this issue, let’s take a look at some popular websites in High Contrast mode.

Popular content sharing service AddThis also incorporates CSS sprites for its toolbox sharing buttons:

It is great more sites are using sprites to deliver a faster user experience, however we need to recognize (myself included) we are damaging the user experience for High Contrast users.

Introducing <img> Sprites

While noodling over a new design for AOL.com that featured graphical headers using our new corporate identity font, I decided to prototype something I had thought about a couple years ago but never got around to doing.

Since <img> elements show up in High Contrast mode, why not try to crop the image to show what we want?

Simply set the height (and width if needed) on the outer container (in this case, the <h2>) to the size of the image you want to crop, and play around with top (and left if needed) to move the image into place.

Verifying Your Implementation

To enable High Contrast mode in Windows:

Start Menu… Control Panel

Open Accessibility Options

Click on the Display tab

Ceck the High Contrast checkbox

Click Apply to see the effect.

Or…

Alt + Shift + Printscreen

<img> Sprite Working Demos

Check out our CSS Sprites Demo, and then turn on High Contrast mode. Then, visit the <img> Sprite page to see the difference.

All other tags should work, please leave a comment if you find otherwise.

This solution has been tested to work in IE6+, Firefox 3.5+, Chrome and Safari 4+ and it is expected to work in all future browsers.

Detecting High Contrast Mode

Chris Blouch also created a High Contrast detector as part of the AXS Accessibility JavaScript Library. It should come in handy if you are really having trouble getting your site to look good in High Contrast mode.

http://dev.aol.com/downloads/axs1.2/readme.html#hd

More Information on High Contrast Mode

This video gives a nice overview of the challenges facing people with a low vision disability. At 19:38 the host goes through some of the accessibility tools available in Windows like High Contrast mode:

Bonus! Printable Image Sprites!

A couple commenters pointed out background images don’t print by default and this technique solves that. Here’s a print preview of my demo pages in Firefox for some evidence.

CSS Sprites Printed

<img> Sprites Printed

I guess I shouldn’t assume it looks good in IE too, let me know if it doesn’t.

Further Reading

I wanted to call out Thierry Koblentz, he kindly informed me (see comments) that he wrote about this exact technique save for me going the relative positioning route. Turns out I’m not as original as I thought — nice job Thierry.

SEO: Most of the things you’d want to do this with (headers, buttons, logos) you wouldn’t want to have indexed by Google Image Search. I’d almost want to include them in robots.txt so they didn’t snag the sprite. As for leaving alt text empty, just be sure to include the text in the container and Google will have more than enough to weight for those terms.

Usability: It’s interesting, I disabled images on my IMG Sprite Demo page and the original text showed up. This is because if you noticed, I didn’t set a width and height on the image so the browser doesn’t push the text out of the container (hiding it). On text only browsers, since we include the text in the container, it should definitely still be useful. Anything else that we should think about?

I haven’t tried printing it out…If you have a printer handy, print out both demo pages and take pictures for me and I’ll post them

There’s still a place for background-image sprites, especially for non-essential design elements such as gradients, rounded corners, etc. I think once we venture into the realm of image text, icon buttons and logos, we’ll want to go the <img> route.

I tried with css off. Not pretty. Each location of the “sprite” displayed image shows the entire sprite and the viewer would have no clue what is going on. This is a basic requirement of WCAG.

The alt attribute is specifically used to provide the equivalent content for an image. I’m not sure I would go to the trouble to use and hide text, just for a slight SEO boost. This the opposite of what accessibilty advocates are trying to get us to understand and is confusing for new web designers learning standards.

One reason why many are using background images for buttons and widgets, is that you can get easily the hover effect in the css. For an inline image that is a button or link, you will need JavaScript to provide the rollover effect.

Another problem with this technique if you re-size text only with images off in regular browser, the text will be clipped, although more browsers use zoom to re-size the whole page an not just text.

@Thierry – Kudos! I did search around after writing it and couldn’t find anything. You also document a technique we internally at AOL called “iCE” (image content exposure), a technique we use for non-sprited images to avoid any text-indent/cloaking hackery. Funny I never connected the dots till now.

@Pat – How do you turn CSS off (without the Web Developer toolbar)? On the alt text issue, I would argue that a screen reader should get the benefit of *real* header text rather than hearing that it’s an image. I definitely think having text in the header is well worth it to Google too, as we’ve seen benefits in ranking when tweaking <h2>’s. Last I checked Yahoo and Bing don’t even index alt text as part of the document. Good point on the :hover effect, that’s definitely a drawback I hadn’t considered and would be messy to hack together with JS. Thanks for the sanity check.

@Pat
If you check my article at http://tjkdesign.com/articles/how-to_use_sprites_with_my_Image_Replacement_technique.asp you’ll see that turning CSS off is not an issue. The key is to zero out dimensions via HTML and set proper value using CSS.
And, fwiw, I agree with “ArtzStudio” about the SEO benefit. In any case, the empty “alt” attributes would not cause accessibility issues.
Regarding clipping, I believe a technique derived from this one would work: http://tjkdesign.com/articles/tip_5.asp
And regarding the rollover effect I don’t see the difference with this technique and a background image technique (I may be missing something though). What do you think would be the blocker?

An excellent in-depth article but I still fail to agree with any CSS-Sprite technique in practice.
Even though I have and do use them.
CSS-Sprites present an overly complex solution to a basically simple problem.

Images should only be replaced if the are background graphics, that is purely for prettifying, and never if it’s content related.

If saving a few image HTTP requests is really important to your site performance investigate usage of the Data URI scheme.
Combined with gzip or deflate, caching, and conditional comments for IE prior to v8, and you’re ready to rock.

Works for both content images and background graphics.
HTTP requests for images?
That’ll be a big 0.
The Data URI scheme will hopefully relegate CSS-Sprites to become the historic relic they deserve.

This is excellent, thanks. I am in the middle of an implementation that will greatly benefit from this technique. By the way, do you have any stats regarding usage of the Windows high contrast mode vs. third party software like Zoomtext? Also, am I correct in thinking that Zoomtext’s high contrast mode displays background images correctly?

@Mike – While I agree with you, our challenge is ensuring our IE7 and lower users (50% of our audience) get a faster experience than our competitors and image sprites help us towards this goal. They can also make skinning and maintenance easier when used effectively. That said, I need to look into MHTML, a solution for Data URIs in IE6/7 that Stoyan blogged about here.

@Michelangelo – I don’t have stats but will ask someone from our Accessibility department at AOL to chime in. I have to think Zoomtext is more popular based on the youtube video I posted above. It does appear to display background images.

@ArtzStudio
I cannot find a contact form or link on this site, but I wanted to tell you that I kind of expected you to mention in your article that there was “prior art”. After my first post, I thought you would acknowledge that in the article itself (as we know, most people do not read comments).
Thanks.

I can see why you remove the alt text in the example heading you give, but I think it is important to emphasise that alt text should be present where the image has informational meaning that isn’t otherwise presented as text. For example in the case of buttons disappearing from Google video, if these were changed to an image sprite then it wouldn’t solve the accessibility problem because the individual buttons need to have alt text of “previous” and “next” or similar. A single sprite image wouldn’t be able to identify this.
I do think that sprites can be used in some circumstances, but rarely in the case of informational images, in which case the problem of the image disappearing in high-contrast mode is no longer a problem.
The only situation I can think of where an html sprite image might work is if you had the same information repeated across the different parts of the image (so only one alt text is needed), e.g. a form submit button that was portrayed in different fonts or colours on different parts of the page.

@ArtzStudio + Pat: About the hover problem – I think it should still be possible to get this done [without] using Javascript. At least, for any tag that encloses an image tag, ie. in the standard case that would be an linked image (a + img tag).

In said example, that should be something like

h2 a:hover img {
top: -300px; // the hover state is starting at a height of 300px
}

@Michelangelo – While there are techniques for discerning whether someone has AT (assistive technology) running on windows making use of the MSAA (microsoft active accessibility) API or high contrast mode, this question quickly moves into the realm of consumer advocacy and privacy. Most AT users do not want to self-identify as having some kind of disability or have us probing their system to find out. It’s a tough nut because we would really like to know so we can make stronger arguments for supporting AT in our products, but privacy does and should trump this desire for personal user data.

@ArtzStudio your method enhances my solution regarding transparent images as you use the image to push the text down while I am hiding that text behind the image. Slightly different, but it solves a real problem. I’ll use that

I was just barely looking for a solution to this and I found your article on twitter. Great info. My only concern is that I feel like we’re doing back flips to solve the limitations of Windows high contrast mode. If the comments above are to be believed, magic handles css background images “correctly”, and my own testing verifies that OS X high contrast mode also displays background images.

I suppose the definition of “correctly” handling background images in high contrast mode could be debated. Does anyone know why Windows chooses not to display them? CSS background images are assumed to be decorative only for the purposes of screen readers and if not, some text alternative should be provided, but for a low vision user, they do provide value. OS X does a much better job by reversing the colors in the images.

I do realize that none of us has the power to change Windows I contrast mode, but perhaps we should submit a bug and notify them that they’re forcing web developers to get very creative to solve a shortcoming in Windows high contrast mode

I have a question about sprites. Would it be “wrong” to put the css rules for the sprite directly in the tag? I was trying to think of a way to create helper methods within templates to render an image sprite.

It’s good practice to avoid inline styles if you can help it to keep the HTML lean, and it is generally considered easier to update stylesheets vs. mucking around in the markup. That said if it is more convenient from a development standpoint for you to maintain, it may be worth it in your situation.