Short note on what CSS display properties do to table semantics

Posted on Sunday, 4 March 2018 by Steve Faulkner

The CSS display properties are powerful. You can change the visual display of elements to match your desired styling, but sometimes doing this can have an unintended effect of nuking the semantics of the elements, as conveyed to screen reading software, in the browser accessibility tree. Screen readers and other assistive tech, in general, do not have direct access to the HTML DOM, they are provided access to a subset of information in the HTML DOM via Accessibility APIs. Sometimes what an element represents in the HTML DOM is not how it is represented in the accessibility tree.

If what is represented in the accessibility tree does not represent the developer’s intended UI, it’s either (wittingly/unwittingly) the fault of the developer or the browser. But what we can be sure of, in these cases, is that it is not the fault of the screen reader.

An example

the good

A data table with default display properties is represented in the browser accessibility tree with each element’s semantics correctly conveyed:

accessibility tree of a data table, with correct semantics displayed.

Each element is represented in the accessibility tree with its appropriate role, for example a table element has a role=table.

the table element has a role=table

the bad

When CSS display:block or display:grid or display:flex is set on the table element, bad things happen. The table is no longer represented as a table in the accessibility tree, row elements/semantics are no longer represented in any form.

table semantics are not exposed correctly when display:block is set.

None of the elements are represented in the accessibility tree with data table semantics, they are all given a role=text frame.

This can be fixed by the developer by adding the semantics back using the ARIA table/row/columnheader/rowheader/cell roles (see the ARIA table design pattern) which is a lot of heavy lifting for the developer that should not be needed. In this case the browser should not be messing with the table semantics.

If nothing else, a developer should be aware that it is not always the fault of the assistive technology when we can’t have nice things.

Related reading

Tables, CSS Display Properties, and ARIA

About Steve Faulkner

Steve is the Technical Director at TPG. He joined The Paciello Group in 2006 and was previously a Senior Web Accessibility Consultant at vision australia. He is the creator and lead developer of the Web Accessibility Toolbar accessibility testing tool. Steve is a member of several groups, including the W3C Web Platforms Working Group and the W3C ARIA Working Group. He is an editor of several specifications at the W3C including HTML 5.1, ARIA in HTML, Notes on Using ARIA in HTML and HTML5: Techniques for providing useful text alternatives. He also develops and maintains HTML5accessibility.


  1. Very informative post, if this is not problem of screen readers & problems with browsers then why browsers are not fixing this. And what is the alternative method to use other than display: block or display: grid or display: flex? There must be some alternative to achieve the same design using other CSS properties.

  2. I’m not sure that this is a “browser problem”. Can someone offer a real-life use case where you’d want to use display: block/grid/flex on a table element?

  3. I’m not sure that this is a “browser problem”

    I am sure it is a browser problem, but to what extent it effects users is dependent upon the usage of CSS display on table elements. I looked into this because there was a recent example of an re-orderable table using flex.

  4. Thanks so much for this. I’m working on a responsive table widget for some work sites (which must remain accessible) and was this close to changing the table/tr properties to grid/flex, in browsers that support those features. I had no idea about this caveat.

    One question: can this be worked around with a media query? For example, if media=”screen” then display tables as grid, but if media=”speech” then display tables as tables? I suspect there’s a reason this is not optimal/compliant, but I’m not sure exactly why!

  5. Peter:

    Can someone offer a real-life use case where you’d want to use display: block/grid/flex on a table element?

    Scrolling tables do it all the time (unless you do the trick where you actually have two identical tables and hide the body of the first one: Table #2 does this, which I think is ridiculous to have to do just for a visual presentation). Most scrolling tables set the display state to something that’ll get a scrollbar (“block” is popular).

Comments for this post are closed.