Accessible way of Hiding/Displaying help?

I’m trying to use an FAQ style method for initialing hiding then revealing answers to common questions.

A similar example can be seen on:
Support | Springpad under the section Common Questions.

The problem is that when an item is revealed, by switching the elements style from “display:none” to “display:block”, the screen reader will not read it.

Does anyone know if it is possible to use this UI device in an accessible way?

Many thanks!

Some screen readers will read something that has changed state, but many older ones won’t, because they don’t know they must update their buffer.

buffered screen readers, when they load the page, make a local copy (a buffer) which the user then interacts with.

In any case, without Javascript there is only one set of thingies on the right side. That is a mistake. The best method is to show ALL the information by default and let your menu on the left skip to the relevant information using the urlhash (like #common).

When users have Javascript, let Javascript do the hiding, instead of defaulting with CSS. Javascript hides and unhides the relevant areas.

And finally you can avoid the block/none problem by using another method of hiding non-relevant information from sighted users.
One is to absolutely position the content offscreen. This “counts” as being on the screen as far as a screen reader is concerned, meaning that content will get loaded into the buffer. So instead of onclick making the section go from “none” to “block”, you would instead change its “left” or “left-margin” property (usually I have Javascript add or remove a class which is pre-defined in CSS with these margins).

Another is the overflow method. You could start with the box on the right being as tall as necessary (auto) to hold and show ALL the information (which is inside an inner box), but when Javascript loads in then users browser, make that box a set height with overflow: hidden on it. That allows only an amount of content you want to be visible (but it’s all on the page, and screen readers can ignore overflow: hidden). Again, Javascript will adjust the box inside the box (by sliding it, like most photo scrolling sliders) either by manually manipulating the top/margin-top value or adding/removing a class.

<div id=“outer”>
<div id="inner>
content…
</div>
</div>

#outer has a set width
#inner has NOTHING inside it that could be wider than #outer’s set width!

Javascript, onload:
#outer gets overflow: hidden and a set height.

#inner starts out at 0, 0 (showing the top information) and when a menu item is selected it can pull it “up” to the relevant section using margin-top, or I believe there is a better way using hash tags but I haven’t tried myself.

On the Orca mailing list I once heard people complaining about a web site where they would click but nothing would happen.

Turns out the site had h2’s with onclick events (so the screen readers thought these were clickable things and read them out as links in this case, but they weren’t links and could not be selected via keyboard) that were supposed to take divs underneath who were display: none by default and change them to display: block. A expansion script using either overflow or absolute positioning would have been much better (also using something natively clickable like an anchor would have also helped, and the content should not have been hidden also from those who don’t have the Javascript to show it).

Of course, there had better be a really really good reason to hide stuff from people. Are you really increasing usability?
You can always try the typical FAQ format.

Heh, love the way the targeted numbers get bigger. Very nice. :slight_smile:

Heh, love the way the targeted numbers get bigger.

Not in IE.

But of course.

Works fine in Internet Explorer 9.

Heh, love the way the targeted numbers get bigger.

I was going to make much the same comment. I had to have a snoop at your CSS to see what you used and I’ve never seen :target used anywhere before, that I know of.

Places It’s Tempting To Use Display: None; But Don’t

You want to hide something on a page, so:


.hide {
   display: none;
}

But wait! By applying that class to an element you’ve immediately made that content “inaccessible” by screen readers. You’ve probably known this forever, but still the poison apple sneaks into our code once in a while.

I don’t want to re-hash all the specifics. Your best bet is to read “Now You See Me” by Aaron Gustafson on A List Apart to get an understanding of this if you don’t already.

One way to encourage yourself to do the right thing is by creating more appropriate class names. Your regular hide class should position the content off screen, which still leaves it screen reader accessible:


.hide {
   position: absolute !important;
   top: -9999px !important;
   left: -9999px !important;
}

I use !important here because if you’ve gone to the trouble to add a “hide” class to something, you probably mean it and don’t want to think too hard about if the specificity value is strong enough. And if you know that you need to display: none something, the class should help you understand it:


.remember-this-will-NOT-be-read {
   display: none !important;
}

OK you got it. Easy peasy when you’re totally in control of class names and all you do is apply and remove them. But things get a little tricker with JS libraries that apply their own CSS. For instance in jQuery, after you .slideUp(), you’ll have a display: none in the inline CSS to deal with. Yes, screen readers run JavaScript and yes, that’s still a problem.

Again Aaron Gustafson has us covered there, who suggests applying the accessible class name after the sliding is done and then removing the display: none by sliding it the other direction.


var $button = $('#myButton'),
    $text   = $('#myText'),
    visible = true;

$button.click(function() {
  if (visible) {
    $text.slideUp('fast',function() {
      $text.addClass('hide')
           .slideDown(0);
    });
  } else {
    $text.slideUp(0,function() {
      $text.removeClass('hide')
           .slideDown('fast');
    });
  }
  visible = !visible;
});&#8203;

Original article is posted by ChrisCoyier : http://css-tricks.com/places-its-tempting-to-use-display-none-but-dont/

I have nothing to add to this thread. Just wanted to mention that I really like that FAQ look that Stomme posted. =p

Actually, I lied.

To elaborate on the overflow:hidden method. This would be an especially handy method for this implementation. If you wanted to do an effect (like a slideDown), you can easily do that by leaving it overflow:hidden and increasing it’s height (the basic approach jQuery uses). The absolute positioned one can do it as well, but the “logic” behind it is a bit weird to me (you have to make it small, then move it back, then make it grow, etc).

Just be careful if you use things like jQuery’s slideUp, because it sets display: none to the element at the end, so you’d want to remove that when it was done.

To me it’s a sign of bad CSS, except later you mention jQuery and often (unfortunately) the common use patterns for jQuery and many of the plugins people use add in inline CSS, which can only be overridden with !important. Still, I hate it. My user stylesheet needs !important to override bad author stylesheets.
Also, unless Window-Eyes fixed their bug (maybe they did, this was like version 5 or something), don’t use top: -9999px. Left will do.

I used to use em’s for off-screen, like left: -9999em. This was very very bad for Opera and Konqueror. Konq would wrap around to the right. Opera did something else, I forgot. Doing the same for top: -9999em made Opera cut the page short. Turns out Opera has a pixel limit on widths and heights, something like 32000px (found by Erik J). So now it’s -999em, or if it needs to come onscreen on :focus I noticed em’s didn’t work at all with keyboard so back to -9999px I went. Sigh.

How about we go to jQuery.com with pitchforks and torches and demand an end to the display: none junk?

It wouldn’t be a bad idea. I want to get my team to stop using display: none as well, so I’ve been thinking of downsides or special cases when it is required or when a large negative margin wouldn’t work, but I can’t really think of anything. It seems pretty easy to just drop it in place, then flip back to position: static when you need to move it back.

Sometimes having it positioned doesn’t work in a setup, I suppose… but then I’d fall back to overflow then…