Foreground Sprites – High Contrast Mode Optimization

98 10
98 10

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.

In Google Video, the next and previous buttons dissappear:

Google Video

In Yahoo Finance, the navigational tabs and buttons dissappear:

Yahoo Finance

In sites like Facebook, Amazon and AOL Music, logos vanish from thin air…err, screen:

facebook

Aol Music

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

Add This 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?

Our example HTML for graphic headers in this case look like this:

<h2 class="popular"><img src="img-sprite.png" alt="" />Featured</h2>
<h2 class="featured"><img src="img-sprite.png" alt="" />Popular</h2>

We set the alt attribute to “” so screen readers skip over it. We include the “Featured” text so search engines have an understanding of what this section is about (more powerful than alt text).

The following CSS is then applied to crop the parts of the image we want:

h2 {
 overflow: hidden;
 position: relative;
 height: 50px;
 width: 200px;
}
h2 img {
 position: relative;
}
h2.popular img {
 top: -100px;
}
h2.featured img {
 top: -200px;
}

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:

1)Start Menu… Control Panel
2) Open Accessibility Options
3) Click on the Display tab
4) Ceck the High Contrast checkbox
5) 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.

CSS Sprites Demo Page
<img> Sprites Demo Page

Known Limitations

For image cropping to work, it must be inside a block element or an inline element with the CSS property display: block.

Chris Blouch, AOL’s resident accessibility expert tested this technique out on various HTML elements and found that we cannot crop <img> elements inside the following elements:

Fail to crop: <fieldset>, <legend>, <input>, <button>, <table>, <tr>, <td>, <th>
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

Css Sprite

<img> Sprites Printed

img sprite print

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.

 

In this article

Join the Conversation

10 comments

  1. Aaron Peters Reply

    Dave,

    this is great!!!
    fyi, tested it in FF3.0.19 and works fine.

    One question: in your opinion, what are the downsides of leaving the alt tag empty?
    Usability, SEO (Google Images!), other….

    Keep up the good work!

    Aaron

    1. artzstudio Reply

      Hey Aaron, cool to hear from you 🙂

      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?

  2. Sergey Chernyshev Reply

    ave,

    Great technique!
    I would imagine that this also works better on printers (without switching browsers to print backgrounds).

    Seems too good to be true as well. Any idea why this was never used before?
    Seems like a huge miss by those who implemented background-image sprites as a best practice!

    Sergey

    1. artzstudio Reply

      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 route.

  3. Pat Ree Reply

    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.

    1. artzstudio Reply

      @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

      ’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.

  4. mike foskett Reply

    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.

    1. artzstudio Reply

      @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.

  5. richard Reply

    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.

  6. Dallas Despain Reply

    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