Screen readers sometimes ignore display:none

It has been widely known for several years that using display:none in your CSS to hide content from users of graphical browsers will also hide it from people who use screen readers. Sometimes that is good, sometimes not. However, it doesn’t always work that way, as Gez Lemon explains in Screen Readers and display: none.

The complete details are available in Gez’s article, so I’m not going to repeat everything here. In short, depending on the circumstances both JAWS and Window-Eyes will sometimes speak content hidden with display:none. This can cause usability problems, especially for Window-Eyes users. But there is a workaround.

Normally when you want to temporarily hide something from all users (provided that their browser supports CSS, of course) you use something like this in your stylesheet:

  1. .hidden {
  2. display:none;
  3. }

As mentioned above, this does not always work. The simple workaround, which was discovered thanks to Jared Smith’s comment on Gez’s article, is to use both display:none and visibility:hidden:

  1. .hidden {
  2. display:none;
  3. visibility:hidden;
  4. }

By adding that extra line you can make sure that content that is meant to be hidden from all CSS-capable user agents actually is hidden.

Posted on November 7, 2007 in Accessibility, CSS

Comments

  1. I remember reading an article a couple of years back (I believe that it was at A List Apart by Joe Clark but a search doesn’t bring up anything familiar) in which the author tests display:none and visibility:hidden in a variety of screen readers and the results were similar.

    However, if you want something to be invisible, why not use, what seems to be more common, a negative value in text-indent?

  2. November 7, 2007 by JEff Edsell

    So then when you unhide the something, you have to use BOTH style.display = ‘block’ AND style.visibility = ‘visible’ ?

  3. November 7, 2007 by Roger Johansson (Author comment)

    Jules:

    However, if you want something to be invisible, why not use, what seems to be more common, a negative value in text-indent?

    Because that doesn’t really hide anything, it just moves it off-screen, meaning screen readers will still announce it.

    Jeff:

    So then when you unhide the something, you have to use BOTH style.display = ‘block’ AND style.visibility = ‘visible’ ?

    No, you change the className of the something to a class that matches a CSS rule containing those properties ;-).

  4. I read that article a while back and was very surprised because of what I thought I knew. I use display:none so infrequently nowadays it’s sort of a moot point (but good to know all the same).

    If I want to hide something I almost always use absolute positioning with a negative top and left. Seems to work very well. The reason that works for me is that usually what I’m hiding is something that I want hidden only from the typical sighted visitor — something I want to be “visible” to those without CSS support or to screen readers.

  5. November 7, 2007 by Roger Johansson (Author comment)

    Mike:

    The reason that works for me is that usually what I’m hiding is something that I want hidden only from the typical sighted visitor

    Right, and the off-left technique is what I use for those occasions as well. The issue with screen readers sometimes announcing elements with display:none is that it can cause problems when you’re using JavaScript to temporarily hide something from everybody (provided their browser supports CSS and JavaScript, obviously).

  6. Ah, of course—I didn’t consider the significance of this until I read the comments, although it would’ve hit as soon as I sat down to write my next ECMAscript masterpiece: we all tend to use display: none so infrequently because we invariably want it still be to be spoken, just not displayed, but scripting tends to be the exception to that.

    Although that’s just made me wonder… what’s the best way of implementing the usual “tabs” pattern such that nothing is lost when spoken? It’s fine if the user doesn’t have scripting turned on–you just don’t hide anything, but if they do but are using a screen reader, I wonder how well (or not) it would work.

  7. This is a more general thought: What style-sheets is a screen-reader loading really?

    The only relevant css for screen-readers should be such with media-type “aural” resp. “all”.

    It should not read “the screen”, but more html. Strictly speaking, media-type “screen” should screen-readers ignore. Or did i get something wrong?

    In my opinion, a better name for screen-reader should be “web-reader” or “html-reader” or something else.

  8. Forgive me if this seems a bit glib, but isn’t the best solution to just not include anything in the markup we wouldn’t want read?

  9. Forgive me if this seems a bit glib, but isn’t the best solution to just not include anything in the markup we wouldn’t want read?

    The sort of situations where this would be an issue is when you’re using javascript to hide/reveal content, e.g. when validating a form, you don’t want the error message to be visible/readable before the submit button has been hit.

  10. @Gerald: Screen readers are just that; they read what’s on the screen. An aural browser would read the aural stylesheets, but that’s not what screen-readers are.

  11. We’ve done somewhat extensive testing on this - I think in terms of JAWS it’s a relationship issue the reader has with the browser.

    Anyway, our work around is to set the location of the element far out to the left of the browser {position:absolute;top:-900px;left:-900px;}

  12. November 10, 2007 by Roger Johansson (Author comment)

    Dennis S: That workaround is for when you do not want to hide the element from the screen reader, isn’t it? This is about those cases when you want to hide the element from everybody, including screen reader users. Or am I misunderstanding you?

  13. Hi Roger

    I know this article is about screen readers but I think you missed a segment of web users who are also effected when display:none is used. Commonly display:none in used in dynamic nested list menus to hide submenus until they are hovered over and this causes accessibility problems for keyboard users since the links within the hidden submenus can not be tabbed to. This is not an issue when absolute positioning is used instead for hiding the submenus.

    I will now go and find the information I was seeking from your site about accessibility so I can improve my own sites’ accessibility. Keep up the good work.

  14. Very interesting discussion!

    I use sometimes display: none and sometimes the absolute positioning technique (-9999px) but I should re-think my methods, now that I know that elements with DISPLAY: none applied to them are NOT always hidden from screen readers…

  15. Roger,

    This is for when we need the screen reader to read something, but not sighted users. Skipto links, additional information, etc.

  16. November 13, 2007 by Sander Aarts

    I agree with Alex. If you don’t want any user to see/experience a piece of content it’s better to just leave it out.

    You can use JavaScript to insert it when needed (I guess the events that trigger the appearance of these pieces of content require JS anyway, like form validation).

  17. PLEASE NEED SOME HELP ON THIS ISSUE!!! How does display:none affect “white hat SEO” flash sites? will a site get dumped from google or other search engines because of hidden divs with text?

    on the other hand… will this hidden text help the site gain any google ranking?

    My “particular” case is about a FLASH BASED SITE that needs a little SEO tunning, but i´ve been told this technique would get the site, eventually, banned. Is this so? Please HELP!!! tnx.

  18. Mo 10, The term “screen reader” is confusing. I’ve tested Thunder/WebbIE and p w Webspeak. They obviously need to read the HTML file and CSS files to present the result. Isn’t that what a browser does? They also interpret links, so the blind user can press a key to select the link. Seems to me they could be called “audio browsers”. They do not merely speak what a browser has placed onto the screen.

    George

  19. An update for pwWebspeak product. link This product is easy to use and enables testing of HTML (example - Skip navigation link).

    It includes local HTML files that reference a CSS file; but the CSS file is apparently ignored.

    Do screen readers utilize a “media=aural” CSS file internally to produce the speech?

    If I want to change the appearance when “browser” is a screen reader, how is that done?

    George

  20. Here is another simple solution:

    .skip { position: absolute; top: -1000em; left: -1000em; }

  21. December 1, 2007 by Roger Johansson (Author comment)

    gs99:

    Do screen readers utilize a “media=aural” CSS file internally to produce the speech?

    In general, no.

    If I want to change the appearance when “browser” is a screen reader, how is that done?

    The only way I have heard of is to use ActionScript in Flash. And that will only work on Windows, and only with some versions of some screen readers.

    lukasz:

    Here is another simple solution:

    If you read the article you will see that the problem here is not about hiding something from visual browsers only, it is about hiding from all user agents, including screen readers. The solution you suggest works fine when you do not want to hide things from screen readers :-).

Comments are disabled for this post (read why), but if you have spotted an error or have additional info that you think should be in this post, feel free to contact me.