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:
Each element is represented in the accessibility tree with its appropriate role, for example a 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.
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.
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.
@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 😉
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?
I am sure it is a browser problem, but to what extent it effects users is dependent upon the usage of CSS
display
ontable
elements. I looked into this because there was a recent example of an re-orderable table usingflex
.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!
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
Thanks, Patrick. Great info at that link. I guess that means media queries are a no-go as a workaround.
Peter:
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).
Y’all – did I get the roles correct here?
https://codepen.io/team/css-tricks/pen/wXgJww?editors=1100
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
LGTM