Notes on accessible CSS image sprites

The issue of CSS image sprites has been raised again on the Web Accessibility Initiative Interest Group mailing list. Here is the advice we provide on the issue:

CSS image sprite issues

  • A default HTML method to add a text alternative is not provided.
  • When images are disabled the sprite is not displayed.
    Note:
    This is not an accessibility issue, but is a usability issue . If you do not want to test whether images are disabled, there is a  high contrast mode (only) detection script available.
  • When high contrast mode is enabled in the Windows OS, the sprite is not displayed (CSS background images are not displayed in high contrast mode).

CSS image sprite issue fixes

  • Include alternative text inside the element that the CSS background image is attached to.
  • If images are enabled and Windows high contrast mode is not enabled use JavaScript to add a style sheet that visually hides the text alternative, but is still  available to assistive technology.
  • Use JavaScript to detect when images are disabled and remove the CSS visually hidden display state of the text alternative.
  • Use JavaScript to detect when Windows high contrast mode is enabled and remove the CSS visually hidden display state of the text alternative.

Accessible CSS image sprite example pageexample files (zip)

Example code (JavaScript):

function HCTest() {
var objDiv, strColor, objFlag;

//reference to img element used to check if images are disabled
objFlag = document.getElementById('flag');

//Create a test div
objDiv = document.createElement('div');

//Set its color style to something unusual
objDiv.style.color = 'rgb(31,41,59)';

//Attach to body so we can inspect it
document.body.appendChild(objDiv);

//Use standard means if available, otherwise use the IE methods
strColor = document.defaultView?document.defaultView.getComputedStyle(objDiv, null).color : objDiv.currentStyle.color;

//Delete the test DIV
document.body.removeChild(objDiv);

//Check if we got back what we set (strColor== ??) If not we are in high contrast mode
// Use .offsetwidth and .readyState (for IE) to check if images are enabled
//If either images are disabled or high contrast is enabled (or both) the CSS stylesheet link will not be added to the page and the visually hidden text will be displayed in place of the missing background image

if (((objFlag.offsetWidth === 1 && objFlag.readyState === 'complete')||(objFlag.offsetWidth === 1 && objFlag.readyState === undefined))
&& (strColor === 'rgb(31,41,59)' || strColor === 'rgb(31, 41, 59)'))

{
var objHead = document.getElementsByTagName('head');
var objCSS = objHead[0].appendChild(document.createElement('link'));
objCSS.rel = 'stylesheet';
objCSS.href = 'alt.css';
objCSS.type = 'text/css';
}
}

Example code (HTML):

//call function onload
<body onload="HCTest();">

//image for testing offsetwidth
<img id="flag" src="clear.gif" alt="">

//example link with CSS background image
<a href="#" class="sprite">

//text label displayed when CSS image is not displayed
<span class="visually-hidden">Select</span></a>
...
</body>

Example code (CSS):

In a separate file

.visually-hidden {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding:0 !important;
border:0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}

Notes by Ted Drake, on use of the off screen technique described:

Using negative position can create long scroll bars when localizing a site for a rtl language. Also, it uses CSS properties that are commonly used and easy to accidentally over-ride.

The Yahoo Accessibility Lab recommends using clip for content that should be hidden from the visual user, yet available to screen reader users. Thierry Koblentz has a great article on this technique, as well as the underlying philosophy behind using the correct CSS techniques for hiding content. Clip your hidden content for better accessibility

What the technique does

The technique above resolves the issues of provision of a text alternative in all circumstances and provision of a visible label when images are disabled or high contrast mode is enabled.

Enabling Windows high contrast mode

Related reading:

 

Thanks to: my friend and colleague Gez Lemon for providing a cleaner script and discussion about disabled images not being an accessibility issue.

 

Categories: Development

About Steve Faulkner

Steve was the Chief Accessibility Officer at TPGi before he left in October 2023. He joined TPGi in 2006 and was previously a Senior Web Accessibility Consultant at vision australia. Steve is a member of several groups, including the W3C Web Platforms Working Group and the W3C ARIA Working Group. He is an editor of several specifications at the W3C including ARIA in HTML and HTML Accessibility API Mappings 1.0. He also develops and maintains HTML5accessibility and the JAWS bug tracker/standards support.

Comments

George Hite says:

I turned off javascript to see what happens in that situation and I find it to have an usability issue. In the situation that javascript is turned off and the images are on, the image and the text element overlay each other making it impossible to discern the text. I would assume you would want the css to still hide the text element.

Steve Faulkner says:

Hi George, thanks for the heads up. Have fixed this by moving the application of the background image to the CSS file rather than in page. This results in the text being shown when JavaScipt is disabled rather than the sprite.

Ted Drake says:

Todd Kloots worked with Thierry Koblentz and several other engineers to come up with this solution for high contrast capable sprites. He was particularly concerned with a solution that was accessible, but did not harm performance or add extra burden to the engineers.
https://yaccessibilityblog.com/library/high-contrast-friendly-icons.html

Steve Faulkner says:

thanks for the pointer Ted, have added to related reading.

Nico says:

What about this technique : https://openweb.eu.org/articles/performances_web_les_sprites_CSS

There is no need of Javascript, the technique uses only CSS and it works without images and without CSS.

Sylvain Galineau says:

Note that starting with IE10 there is a media query to detect high-contrast mode and preserve background images if needed. See here.

David Johnson says:

This doesn’t seem to happen in Chrome with High Contrast Mode enabled?

Steve Faulkner says:

Hi david,
Chrome does not inherit the OS high contrast settings for web content, Firefox and IE do.

Steve Faulkner says:

Thanks Sylvain, its good to see this CSS property being considered for standardisation by the CSS working Group.