Hiding with CSS: Problems and solutions

Many CSS and JavaScript tutorials suggest using display:none to hide elements. It may be temporarily, for example when using JavaScript to hide or show parts of a page depending on the user’s actions, or permanently, for example in image replacement techniques, skip links, or structural headings.

In most cases, using display:none to hide an element is a bad choice that reduces accessibility. I thought this was a well-known fact, but apparently there are many who are not aware of it being a problem. For that reason, here is a quick explanation of the problem and a suggestion for an alternative technique (that I also thought was well-known).

display:none really means do not display or speak

What many do not seem to realise is that display:none really means “Pretend that this element doesn’t exist. Do not display it, print it, or speak its contents.” Perhaps the most obvious example of how that can cause problems is when a person using a screen reader visits a site that uses display:none to hide something from sighted users. Since most screen readers ignore anything hidden with display:none, using display:none to hide things like skip links, text, navigational links, or structural headings is a terrible idea.

An alternative technique that is much less likely to cause problems is the “off-left” technique (described in ScreenreaderVisibility at the css-discuss Wiki), which involves absolutely positioning the hidden element outside the viewport. Here’s the CSS I normally use for that:

.structural {
	position:absolute;
	left:-9999px;
}

The visual effect will be the same as using display:none, but now screen readers will be able to speak the contents of the hidden elements.

Hiding with CSS, showing with JavaScript

Another case where you need to think carefully before using CSS to hide something is when you intend to display it when the user performs a certain action, for example dynamic menus or help text in forms. If you are using JavaScript to show something, you should also use JavaScript to hide it. Otherwise, people with CSS enabled and JavaScript disabled will never be able to see the hidden content.

The solution is simple. Instead of using an id or a class name that is in the markup to apply the hiding CSS, use JavaScript to add a class name to the elements you want to hide. Then create a CSS rule that hides any elements with that class name.

An alternative option is to use JavaScript to give the body element a class such as “js”, and then use that in your CSS selectors.

In both cases, If CSS and JavaScript are both available your script works as expected. If CSS is on but not JavaScript, well, the script obviously won’t work, but at least the content will be available to everybody.

Posted on May 4, 2009 in CSS, JavaScript, Accessibility