Screen readers and CSS
As I have noted in a couple of blog posts recently, there are some cases when CSS has quite unexpected results in screen readers (or the way web browsers create the accessibility information they hand over to screen readers). If you haven’t read them, the posts are Screen readers, list items and list-style:none and Using display:table has semantic effects in some screen readers.
Here are a few examples:
- Using
display:table
on non-table elements to get the visual layout characteristics of an HTML table without actually using one may cause screen readers to act as if there was a real table - Using
display:block
or float on table-related elements may cause screen readers to treat the table as a layout table and ignore its semantics or report an incorrect data structure - Using
list-style:none
to visually remove bullets or numbers from list items may cause screen readers to ignore them too, basically treating list items as paragraphs of text
Some argue that this is in fact correct behaviour and that screen readers should do their best to convey only what is visible on the screen. I disagree with this since it has the effect of mixing content and semantics (HTML) with presentation (CSS). A central idea of CSS is that it makes it possible to use correct semantics in the HTML layer while still being able to change the visual appearance of your document. I think there are very few developers who expect that using CSS to change the way an HTML element is displayed will also change its semantics for screen reader users.
But if this is the way browser and screen reader vendors think it should be, here are some other situations where CSS should change the semantics of the underlying HTML:
<irony>
h1, h2, h3, h4, h5, h6 { font:inherit; margin:0; }
should turn all headings into plain text.h1 { display:block; margin:0.67em 0; font-weight:bold; font-size:2em; }
should turn arbitrary elements into real h1 headingsa:link, a:visited { color:inherit; text-decoration:none; }
should turn all links into plain text.link { display:inline; margin:0; color:#00e; text-decoration:underline; }
should turn arbitrary elements into links (without hrefs though)fieldset { display:inline; margin:0; padding:0; border:0; }
should prevent screen readers from announcing legend text before form controlsinput[type="text"] { display:inline; padding:0; border:0; font:inherit; }
should turn text inputs into non-interactive plain text.offscreen { position:absolute; left:-9999px; }
should have the same effect asdisplay:none
, as should.invisible { position:absolute; opacity:0; }
</irony>
Yes, I’m being ironic, or at least trying to be. It would be a bit absurd if all of this was implemented. But I think it’s very confusing that lists and tables are treated the way they currently are in some combinations of browsers and screen readers.
In my opinion there is not a lot of CSS intended for visual media types that screen readers should apply. display:none
is obvious and useful. Other than that, I can’t really think of any other CSS 2.1 properties than counter-reset
, counter-increment
, and possibly generated content, that make sense for screen readers to apply. If the developers I have talked to about this are anything to go by, that is the behaviour most of us expect.