Now You See Me

by Aaron Gustafson

38 Reader Comments

Back to the Article
  1. I hadn’t realised that screen readers processed javascript at all. My method to date has been to ensure that everything is visible in terms of HTML/CSS, only using jQuery to hide elements on page load. Do all modern screen readers use javascript nowadays?
    Copy & paste the code below to embed this comment.
  2. I believe they do Garve but a large percentage of people still use something older.
    Copy & paste the code below to embed this comment.
  3. I was looking forward to this book, but after reading this excerpt I almost have no interest now. The proposed best solution in this day is to position things off screen ~999em’s ? This is not a line of thinking I wish to see furthered in any modern web builds. I’m no JS ninja, but I’m fairly certain one day soon we will gravely regret ever positioning objects off the viewable page into outer space. It’s an awful hack that I think developers should stopped using a while ago. Even though “display:none” has it’s screen-reader shortcomings, I can think of no better alternative at this time. Though, I will say the article was very well written and educational.
    Copy & paste the code below to embed this comment.
  4. When ‘accessibly-hidden’ is added via JQuery is it changing the state of display: none and adding text-indent and/or positioning CSS to achieve the same effect? Why is the slideDown(0) in the hiding portion of the code?
    Copy & paste the code below to embed this comment.
  5. Unlike the snark rovo, above, I eagerly await this book. Thanks for the snippet. I am encouraged that I may finally be able to follow direct and clear instructions to implement unobtrusive and accessible jQuery.
    Copy & paste the code below to embed this comment.
  6. Excuse my ignorance but are these software readers or actual devices? if it’s hardware, are there emulators available?
    Copy & paste the code below to embed this comment.
  7. This seems to me like a usable approach for SEO issues (what is hidden isn’t indexable) but I really do not see, what kind of assisting devices actually need to understand JavaScript.
    Would I program visual effects for blind people?
    Copy & paste the code below to embed this comment.
  8. For Windows developers, NVDA is a free, open-source screen reader. Highly recommended for testing. http://www.nvda-project.org/
    Copy & paste the code below to embed this comment.
  9. bq. I hadn’t realised that screen readers processed javascript at all. My method to date has been to ensure that everything is visible in terms of HTML/CSS, only using jQuery to hide elements on page load. Do all modern screen readers use javascript nowadays? With the advent of WAI-ARIA and a greater understanding of accessibility, the accessibility community’s previous encouragement of assistive technology users to disable JavaScript has been reversed. We can now create very accessible interfaces that use JavaScript. It is even possible to use JavaScript to enhance the accessibility of a page beyond what is possible in markup alone (as Derek Featherstone & company have shown). For the record, it isn’t (at least in my experience) that assistive technologies “process” JavaScript, but they receive access to the markup, etc. via APIs provided by the browser. bq. This is not a line of thinking I wish to see furthered in any modern web builds. I agree it isn’t ideal, but offscreen positioning is the only reliable way to visually hide content without making it inaccessible to assistive technologies. Perhaps that will change in the future, but it’s what works best now. bq. When “˜accessibly-hidden’ is added via JQuery is it changing the state of display: none and adding text-indent and/or positioning CSS to achieve the same effect? Why is the slideDown(0) in the hiding portion of the code? The “accessibly-hidden” @class@ simply hides the content by positioning it off-screen. When jQuery applies that @class@, the content is hidden from view and the @slideUp@ (which originally hid the content by adjusting the element’s height before setting @display:none@) can be reversed (thereby removing the @display:none@ CSS property jQuery had applied). It’s kind of like sleight of hand. The steps are reversed when a user goes to expand the element again. bq. Excuse my ignorance but are these software readers or actual devices? if it’s hardware, are there emulators available? In some cases, they are software (such as screen readers like the excellent NVDA catchmyfame mentioned). In other cases, they are a hardware/software combination (e.g. a braille printer or touch-feedback device). I am not aware of emulators for hardware-based assistive technologies. I don’t think they’re often needed; most hardware-based assistive tech has a direct equivalency to more common input devices (e.g. mouse, keyboard, etc.) and output devices (e.g. printers, speakers, etc.). bq. This seems to me like a usable approach for SEO issues (what is hidden isn’t indexable) but I really do not see, what kind of assisting devices actually need to understand JavaScript.
    Would I program visual effects for blind people? If all you are using JavaScript for is visual effects, you’re only scratching the surface of its power. But, since you asked, it’s not that we are programming JavaScript specifically _for blind people_ (or any other people for that matter), but that we are programming _with *respect* to people_. We should strive to make our websites provide a great experience whether you have “special needs” because you’re blind or because you’re on a mobile device. A user’s situation is unknowable, but in order to provide them with an amazing experience, we need to be considerate of whatever their situation might be.
    Copy & paste the code below to embed this comment.
  10. Wouldn’t top: 100% (or left: 100%) work better than left with an arbitrary, obsolete-able static value, especially with overflow: hidden set on a parent element?
    Copy & paste the code below to embed this comment.
  11. Just wondering about the “newest” thinking on this topic. Here is what I am referring to: .accessibility {
      border: 0 none !important;
      clip: rect(0.1em, 0.1em, 0.1em, 0.1em);
      height: 0.1em !important;
      overflow: hidden;
      padding: 0 !important;
      position: absolute !important;
      width: 0.1em !important;
    } This doesn’t push items off the screen but it does essentially hide them. This won’t work for everyone’s needs (such as drop downs, although possible with this code would take some work). Just curious about the impact. It seems to be one of the better ways I have found.
    Copy & paste the code below to embed this comment.
  12. Please don’t read any sarcasm or condescension into my title—I mean it sincerely. If I have deliberately hidden content from my sighted readers using _display: none;_
    why would I need it to be accessible to screen readers? My normal solution for graceful degradation (particularly for non-javascript-enabled browsers) is to code the content as visible by default, then execute Javascript on page load to hide it. Under what circumstances would this leave a screen reader unable to read the content just as well as a standard browser would? That is: if the screen reader browser is Javascript-enabled, the content will become visible under the right conditions (e.g. a button is clicked). If it is not Javascript-enabled, the browser will default to displaying all content in full. If there is another option that I’m missing, I need to know about it so I can account for it in my future development.
    Copy & paste the code below to embed this comment.
  13. bq. Wouldn’t top: 100% (or left: 100%) work better than left with an arbitrary, obsolete-able static value, especially with overflow: hidden set on a parent element? Shifting content off the top of the screen is certainly valid as well (though without testing I’m not sure the mileage you’d get from 100%), but it does introduce some weirdness when you intentionally or accidentally bring focus to an item off-screen: the page will jump back to the top. Moving it off the left (or right in RTL languages) does not cause that issue. bq. Just wondering about the “newest” thinking on this topic. Here is what I am referring to: .accessibility { border: 0 none !important; clip: rect(0.1em, 0.1em, 0.1em, 0.1em); height: 0.1em !important; overflow: hidden; padding: 0 !important; position: absolute !important; width: 0.1em !important; } Good call, I forgot about that one. It doesn’t need to be that convoluted: position:absolute; clip:rect(1px 1px 1px 1px); should work just fine and would be accessible to assistive technology. The beauty of using a @class@ to manage this is that you can easily upgrade your accessibly hidden content strategy as better practices come up. bq. My normal solution for graceful degradation (particularly for non-javascript-enabled browsers) is to code the content as visible by default, then execute Javascript on page load to hide it. Under what circumstances would this leave a screen reader unable to read the content just as well as a standard browser would? It’s a relatively good strategy, but not all screen reader users surf the web with JavaScript turned off (nor should they have to). I’ll give you an example: in an accordion interface, screen reader user will not have access to content that is tucked away in unfocused sections unless they somehow figure out content is hidden in some way and then figure out how to unhide it. Browsing the web should not be that challenging. ARIA gets us partway there (allowing for you to define an interface and then control what’s showing an what isn’t), but not all assistive technologies support ARIA yet (and I’d wager even fewer widgets implement it).
    Copy & paste the code below to embed this comment.
  14. If we want to talk about all of the ways to hide content from a screen reader, we need to expand to use aria. aria is relatively new and not fully supported, but hopefully, in the future it will allow for better control. According to the WAI-ARIA specs, the aria-hidden attribute (aria-hidden=“true”) can be added to an object to tell the screen reader that the object should be hidden from the user. Using the css selectors, it is possible to use the aria-hidden attribute to style elements to be hidden, ex. [aria-hidden=“true”] { visibility: hidden; } It is possible that some day this attribute could be used to tell the screen reader that although it is not visible to the normal user, it should be visible to the user of a screen reader. (i.e. even though the style says, visibility: hidden; if the aria-hidden=“false” the object would be read by the screen reader.) But, I suppose until aria is fully supported by all of the browsers in use, we will continue to rely on other methods such as positioning content off screen to make hide content from the visual user while making it accessible to the users of a screen reader.
    Copy & paste the code below to embed this comment.
  15. I am fairly new to web design, and still learning the use of different functions, so it is interesting to see all these options. I am definitely a very big fan of overflow:hidden, I haven’t been web building for that long, but when I discovered overflow:hidden, it made things much easier.
    Another one I tend to use is display:none, and I am going to try out some of the other things you mentioned, to get a better perspective on what works best.
    Copy & paste the code below to embed this comment.
  16. nice tip Aaron, if you’re using this technique a lot the JS could be put into a function to make this easier to call. As wonkeythemonkey notes, we also often leave content visible and then hide with JS but I can see this causes an issue with screen readers with JS enabled since it just hides content for those users. If the control to show/hide is not accessible to that user then they will never see that content. Which is an accessibility problem if that content is essential or very useful to the page. We have a slide up/down contact form on a recent site we built (http://www.cambridgebs.co.uk/). It does have a normal link to a contact page but I wonder how that would fare to screen reader users if they have JS enabled? I am sure I read somewhere that a very high percentage of screen readers browse the web with JavaScript enabled (something like 85-90%) so this is definitely an issue worth raising. It’s also one that rarely gets talked about, so thanks for posting an interesting article on the subject.
    Copy & paste the code below to embed this comment.
  17. I know that I must be missing something.
    Why would I want for a screen reader to have access to something that I wouldn’t want a visual user to see? If I have chosen to hide something, why would I want that content available to a user of a screen reader? Thanks in advance!
    Copy & paste the code below to embed this comment.
  18. “MikeB”:http://www.alistapart.com/comments/now-you-see-me/P10/#15 is 100% correct, ARIA offers mechanisms for hiding content from assistive technologies (which is the next section in the book, coincidentally) and, as long as you’ve defined methods to unhide that content in a manner that ARIA-enabled assistive tech can make sense of, you should be fine. As he says, though, ARIA is not fully supported. Which leaves us in the pickle “Derek described a few months back in this very magazine”:http://www.alistapart.com/articles/aria-and-progressive-enhancement/. Detlev Fischer also offered “some great insight into ARIA”:http://www.alistapart.com/articles/the-accessibility-of-wai-aria/ in “that issue”:http://www.alistapart.com/issues/319. bq. I know that I must be missing something. Why would I want for a screen reader to have access to something that I wouldn’t want a visual user to see? If I have chosen to hide something, why would I want that content available to a user of a screen reader? As I’ve mentioned in other comments, it’s not so much the hiding that’s really the problem, but rather the ability to unhide the content in a reasonable and easily understandable way. The beauty of hiding content and still allowing it to be read by screen readers is that you don’t have to force a blind person (for instance) to figure out that you’ve got an accordion widget or tabbed interface and then force them to interact with it in order to access the content of your page. You work hard on your content and, unless you’re doing something nefarious, you probably have the content hidden because you want to streamline the interface, but you want it read _eventually_. By accessibly hiding content, you don’t put any additional barrier between people who require assistive technology and your content and you can keep your streamlined interface for everyone else.
    Copy & paste the code below to embed this comment.
  19. I had thought that positioning off page was the best way to go for cases where we wanted to hide & show certain pieces of content & coded accordingly. 

    Then my organization hired an accessibility consultant, who was blind.  The consultant’s feedback was that he didn’t prefer this approach.  He wanted to hear the same content as a sighted user.  He also valued having less content on the page to have to listen to - similar to why we’d use a widget for sighted users, so they can just skim & only view the content they really want to see.  We also worked out adding some hidden content (via positionig off page) that would help orient a non sighted user to the state change - for example, something like “click to expand”. I’m hopeful that Aria will eventually help out a lot with these types of scenarios.
    Copy & paste the code below to embed this comment.
  20. ...in the literal sense of the word. Your article provoked some useful discussion of the accessibility thing wrt hide/show, which I for one hadn’t thought about. The current situation is clearly not ideal for blind users, but comment #20 shows how one’s best attempts may backfire. This Aria thing (which I’d never heard of) sounds as if it might be the way to go in future). PS What’s the rest of the book about?
    Copy & paste the code below to embed this comment.
  21. In the old days we used LAYER tags and Z-INDEX. Is this not a viable option for hiding text? Just create one div that is 100% high and wide and not transparent and then send your hidden objects behind it?
    Copy & paste the code below to embed this comment.
  22. For nav menus that use images as links I have been using the following method to hide the link text…but hopefully keep it readable by screen readers… a {
      background-image: **path to image**
      width: **bg-image width**
      height: **bg-image height**
      text-indent: -9999px;
      overflow: hidden
    } Acording to this article it would seem that the text would still be readable by screen readers… http://www.abilitynet.org.uk/webarticle67 Any responses are greatly appreciated…
    Copy & paste the code below to embed this comment.
  23. Hey Aaron, Great article. I decided to take a stab at changing the jQuery hide() function to use this technique to hide elements as apposed to display:none. I got it working it seems ;) Have a look over here: http://goo.gl/2nIHQ Thoughts?
    Copy & paste the code below to embed this comment.
  24. It could be that I totally missed the point of this article but when you hide stuff visually it should be hidden from screen readers too. The “Idea” presented here is to keep hidden stuff available to screen readers. THAT is ridiculous. Every modal window would always be in view for screen reader users. There would be no expand/collapse for accordion controls ... That is just plain wrong. The only use for positioning off-screen - is not to hide, but to place a message on the page that is intended for blind visitors and specifically not for visual users. For example there might be a section of the page that is visually obviously a log in section, but no heading text is available. You might position a heading “Log-in form” off screen so a blind user would find that section using headings navigation (the H key). Another nice example of using this technique is a skip link, positioned off screen for blind visitors, but which becomes visible when focused and basically hidden for mouse users. That is the case for the skip links on my site.
    Copy & paste the code below to embed this comment.
  25. This is also incorrect: “height: 0; width: 0; overflow: hidden; Element is collapsed and contents are hidden Content is ignored by screen readers” I just double checked and it is read everywhere I tried: JAWS 11 with IE and FireFox, WindowEyes 7.5 with IE and FireFox and NVDA 2010.2 with IE and FireFox.
    Copy & paste the code below to embed this comment.
  26. This is an interesting article that has clarified a few points. I’ll be sure to use the tips next time.
    Copy & paste the code below to embed this comment.
  27. The main point that I take away from the article is that just because I cannot see something on the screen, it does not mean that a screen reader will also not see and thus read the content. When using a JavaScript library such as jQuery, you don’t always know what the animation is doing and it is possible that it will change in future releases. I was working on a page and animating the opacity of an object and later realized that the screen reader still had access to that content. I changed my code to use a callback function to apply a class that set the visibility to hidden after the animation was complete. This is the opposite of his example, but the principle is the same.
    Copy & paste the code below to embed this comment.
  28. About MikeB’s commment. If the principle being advocated is the use of callback functions, then you have used that principle in a way that is effective for everybody. The author here suggests the use of that principle to explose for screen readers all hidden content - which, as I suggested above, is a disaster!
    Copy & paste the code below to embed this comment.
  29. If jQuery has non-accessible code, why not fix jQuery so that it produces accessible content by default?  After all, it’s open source.
    Copy & paste the code below to embed this comment.
  30. Excellent stuff! Thank you for sharing. I’m also seeing more and more mobile websites on smart phones (iphone and android) using these techniques which is important because of the small screen real-estate.  Worth sharing is mobileInDesign, http://www.mobileInDesign.com which shows mobile website trends.
    Copy & paste the code below to embed this comment.
  31. None of the projects I’ve ever worked on had enough budget and resources for working on accessibility. I don’t know if there is a better way to do this, or a kind of international force for implementing it. But whatever it is, I know that it’s budget which directs products, not us directing it. A good example is my own website, http://www.thoughtresults.com which can not be updated on a daily basis, just because I don’t make money enough to recruit for it. So, I suggest that we take accessibility as a lower priority concern.
    Copy & paste the code below to embed this comment.
  32. Thank you for give me the chance to learn more about Hollaback scripts, but I have question:
    ‘(function(){
      var $button = $(’#myButton’),
        $text   = $(’#myText’),
        visible = true;
      $button.click(function(){
      if ( visible ) {
        $text.slideUp(‘fast’);
      } else {
        $text.slideDown(‘fast’);
      }
      visible = ! visible;
      });
    })();’
    how to change the size of the button?
    Copy & paste the code below to embed this comment.
  33. Nice article. The absolute positioning method is something I’ve never really thought of using before (to to hide content anyhow). In terms of accessibility I guess it is the best way of going about hiding things. However as some have already mentioned, I can’t help but feel it’s a little… hacky. I’m quite surprised W3C haven’t considered adding a new display decoration to CSS3, that does what we all require - hides content, leaves no space, but is readable by screen readers.
    Copy & paste the code below to embed this comment.
  34. Your information or instructions are really useful. I think your job is perfect.
    Copy & paste the code below to embed this comment.
  35. Thanks for the article and the interesting discussion! Since the discussion somehow broke off after the strong statement by Jim Thatcher (“This is the wrong advice”) I have tried to revise and order the arguments in favour of both approaches (hiding or not hiding content for screen reader users) in a short article “Dealing with hidden content: what is best for screen reader users?”:http://www.bitvtest.eu/articles/article/lesen/hidden-content.html
    I’d be glad to hear views especially of screen reader users (expert and not expert).
    Copy & paste the code below to embed this comment.
  36. bq. The author here suggests the use of that principle to explose for screen readers all hidden content — which, as I suggested above, is a disaster! I’m sorry, but I disagree with you (at least partially) Jim. While it is true that you may want to hide some content from both sighted and non-sighted users, in most cases content that is hidden by default and meant to be exposed via JavaScript (as in a tabbed interface or accordion) is never exposed to screen readers because the default styles turn it off and (in some cases) those users are surfing with JavaScript turned off (because of its traditional accessibility issues). There’s also the issue of alerting users to changes/updates in the content. ARIA provides mechanisms for this, but support is currently uneven at best. All of that said, I _do_ think it makes sense to hide *unnecessary* content with display:none in order to speed document traversal for keyboard users and screen readers as well as to limit potential confusion. I would group lightboxes, modal dialogs, tooltips, etc. in this category. This assumes, of course, their function is not required in order to actually use the page/site. If you are using a modal login box, I’d recommend a link to a login page somewhere prominent. bq. If jQuery has non-accessible code, why not fix jQuery so that it produces accessible content by default? After all, it’s open source. It’s a noble idea, for sure, but one fix may not be best for everyone. Also, techniques change. I think it’s fine to have a certain default in jQuery and then to override it with a @class@-based hiding mechanism that you control and can update as you deem necessary. bq. Thank you for give me the chance to learn more about Hollaback scripts, but I have question: how to change the size of the button? CSS. bq. Thanks for the article and the interesting discussion! Since the discussion somehow broke off after the strong statement by Jim Thatcher (“This is the wrong advice”) I have tried to revise and order the arguments in favour of both approaches (hiding or not hiding content for screen reader users) in a short article Dealing with hidden content: what is best for screen reader users?
    I’d be glad to hear views especially of screen reader users (expert and not expert). Reading it now.
    Copy & paste the code below to embed this comment.
  37. First off Rovo makes a good point, I think the truth is that placing things off screen versus a proper solution is a shortcoming of the readers themselves, this needs to be improved all around, if screen readers want to avoid elements styled with “display: none;” I think this is the perfect scenario for them to avoid the content.  However, “visibility: hidden;” seems like the perfect method for us, and it should be the way the screen readers work, this is by far the cleanest most meaningful, logical implementation for hidden text thats screen readable. To recap: no, neither of the methods mentioned above work, but “in a perfect world” screen readers would support them. Beyond screen readers, I wonder about search engines as well, can they crawl via “display: none” or “visiblity: hidden”? Becomes a much more usable scenario. But I digress, before my long post my original point was to post updated code for a method to do this that removes the inline style created by a framework like jQuery (in my example jQuery was used.) here is my solution: $navMenu = $(’#mastHead .menu’);
    $navButton = $navMenu.find(‘dt’);
    $navDropDown = $navMenu.find(‘dd’); $navMenu.click(function () {
      $(this).toggleClass(‘active’);   // cannot be toggle, too complex of an ordering is required
      if ($navMenu.hasClass(‘active’)) {
          $navMenu.addClass(‘down’);
          $navDropDown.fadeIn(200, function() {
            $navDropDown
              .addClass(‘show’)
              .attr(“style”, “”);
          });
      } else {
          $navDropDown.fadeOut(200, function() {
            $navDropDown
              .removeClass(‘show’)
              .attr(“style”, “”);
            $navMenu.removeClass(‘down’);
          });
      }
    });
    Copy & paste the code below to embed this comment.
  38. ok, here is more or less the meat of the post: .attr(“style”, “”); thats needed to remove the inline style, but be careful where you do it, if you’re animating anything this will need to be done in a certain order to avoid glitches
    Copy & paste the code below to embed this comment.