Using display:table has semantic effects in some screen readers

Sometimes you may want the layout properties that HTML tables have, but you don’t want the semantics of a table since you’re not really working with tabular data. A couple of examples are creating equal height boxes and making an unknown number of items flexibly occupy all available horizontal space.

In situations like these you can use CSS to tell any HTML elements you want to behave like they were tables, table rows, and table cells by using a combination of display:table, display:table-row, and display:table-cell. You get the layout you want without littering your markup with tables that shouldn’t be there. But there is a slight catch.

When testing the technique I describe in Flexible height vertical centering with CSS, beyond IE7, I noticed that, in some cases, some screen readers will treat “tables” created with CSS as if they were real HTML tables. I did not expect that.

I recently did some more testing to try to figure out when this happens, and here’s a summary of my observations:

  • VoiceOver: Does not announce CSS tables as tables.
  • ORCA: Announces all CSS tables as tables when you navigate between tables on the page.
  • NVDA + Firefox: Announces CSS tables as tables except for single-cell tables.
  • NVDA + IE: Does not announce CSS tables as tables.

I made a display:table demo page if you want to try it out for yourself.

Update: A couple of readers have tested the demo page in Window-Eyes and JAWS with IE and Firefox (thanks!), and neither seems to announce fake tables as tables.

It appears that what’s going on is similar to the issue with list items that I bring up in Screen readers, list items and list-style:none – some browsers, especially Firefox, apply more CSS than others before creating the “accessibility tree” that screen readers use when reading the page.

In the case of list items not being announced just because their visual appearance has been changed, I think that is not really what should happen. The same goes for markup that is not table related being announced as a table just because the developer has used table-related display values to create a particular layout.

It’s like a heading not being announced as a heading just because you’ve changed its appearance:

h1 { font:normal 1em serif; }

Or the opposite – some random text being announced as a header because you’ve styled it like one:

span.h1 {
    display:block;
    font:bold 2.5em sans-serif;
}

I don’t think you would expect – or want – either of those to happen.

So just a word of caution that sometimes the CSS you use may change the semantics of a page. And that is probably not what you intended.

Posted on October 11, 2011 in (X)HTML, Accessibility, CSS

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.