Short note on what CSS display properties do to table semantics

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

Categories: Development

About Steve Faulkner

Steve was the Chief Accessibility Officer at TPGi before he left in October 2023. He joined TPGi in 2006 and was previously a Senior Web Accessibility Consultant at vision australia. 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 ARIA in HTML and HTML Accessibility API Mappings 1.0. He also develops and maintains HTML5accessibility and the JAWS bug tracker/standards support.

Comments

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.

Raghavendra, the post linked at the end, Tables, CSS Display Properties, and ARIA (my post), offers an option to retain / re-add the semantics via ARIA. In the meantime, there is a bug open against Firefox (linked in the second-last paragraph) on which you can comment and also pester the Firefox team (maybe via Twitter as well). I hope you do — I agree with you that this needs more traction.

Ted Whitehead says:

@Raghavendra One solution is provided at the end of the post:

“This can be fixed by the developer by adding the semantics back using the ARIA table/row/columnheader/rowheader/cell roles…”

Example: https://www.w3.org/TR/wai-aria-practices-1.1/examples/table/table.html

Not ideal, but what is 😉

Peter Weil says:

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?

Steve Faulkner says:

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.

Greg Gibson says:

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!

Patrick H. Lauke says:

Greg, for one, media=”speech” is not supported (at least to my knowledge) by any browser (with or without AT running) and will hopefully be deprecated in future – see https://github.com/w3c/csswg-drafts/issues/1751

Greg Gibson says:

Thanks, Patrick. Great info at that link. I guess that means media queries are a no-go as a workaround.

Stomme poes says:

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: https://www.stommepoes.nl/work/tables/table.html 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).

Chris, yep. You got the roles correct. (answering because much of the rest of the team is on a flight right now)

I also made a function to walk through a table, look at the elements (and attributes) used, and add appropriate ARIA roles. It may be handy to use as a reference at least: Functions to Add ARIA to Tables and Lists

Steve Faulkner says:

LGTM