table
markup has been with us since HTML 3.2 circa 1997.
You (and I) would think that the representation of data table semantics in the accessibility tree, complete interoperability implementation in browsers, expert advice on marking up accessibly and mature feature functionality in Screen Readers, is a given… Time for a beer.
A really simple table, with one row of or column of table headers in row 1 or column 1
Table with header cells in the top row only
Now sit back, relax, take a long sip on that cold beer:On Windows 10
- In Firefox – looks good, the
table
is represented correctly.th=column header
andtd=cell
. - In Chrome – looks good, the
table
is represented correctly.th=column header
andtd=cell
. - In Edge – looks good, the table is represented correctly.
th=LocalizedControlType: "header item"
andtd=LocalizedControlType:"cell"
. Each of the cells have the correctly associated header, for example 12 February cell hasTable.ItemColumnHeaderItems: "Date" header
item. - In IE 11 things don’t look so great:The
column headers
are exposed asrow headers
not to mention the absence of row semantics doh! But don’t let that bother you unduly, sip don’t gulp, as IE 11 accessibility support is broken in so many ways, so screen readers that attempt to provide support do their own DOM hacking rather than make use of the accessibility tree.
Table with row headers in the first column only
The results for the simple table with 1 column of row headers is pretty much the same,<th>
elements are correctly identified as row headers
, and in this case, IE11 correctly exposes the row headers
as row headers
.
FYI This is not a reason to code all tables with row headers only…
On Mac
Things work a bit differently on Mac, there is no explicitrole
differentiation between header and data cells. All have a role=AXcell
. The row or column headerness of the elements is expressed by being referenced as items
by cell
Row Header UIElements
and/or Column Header UIElements
properties.
Screen reader announcements for really simple tables
See the Pen Table headers in top row or first column only by steve faulkner (@stevef) on CodePen.
Note: I have gathered the table navigation commands for various screen readers in one location, principally as I keep forgetting them, but also it may be helpful to you.
I have broken down the details by Browser and Screen reader:Firefox 64.0 with…
JAWS 2019
Using Ctrl+Alt+Arrow Keys: when entering a column or row, the row or column number of the cell is announced, followed by the header and cell content. For example:“Event” “Waltz with Strauss” “Column 2” “Venue” “West Wing” “Row 3”Using Ctrl+Alt+NumPad 5 to announce the current cell details, the row and column number of the cell is announced, followed by the header and cell content:
“Column 3, Row 4” “Venue” “Main Hall”
NVDA 2018
Using ctrl+alt+Arrow Keys: when entering a column or row, the header related to the cell is announced, the row or column number, followed by and cell content. For example:“Event” “Column 2” “Waltz with Strauss” “Venue” “Row 3” “West Wing”Note: NVDA does not have a keys stroke combination like JAWS to announce the current cell details.
Chrome 71.0 with…
JAWS 2019
Same as with Firefox.NVDA 2018
Same as with Firefox.VoiceOver
Using Arrow Keys: when entering a column or row, the header related to the cell is announced, the cell content, followed by the row or column number. For example:“Event” “Waltz with Strauss” “Column 2 of 3” “Row 3 of 3” “Venue” “West Wing”Using VO+C+C to announce the read content of table column:
“Event” “Waltz with Strauss” “The Obelisks” “The What”Using VO+C to announce the content of table column:
“Venue” “West Wing”Using VO+R to announce the content of table row:
“Venue” “West Wing” “Main Hall”
Safari 12.01 with…
VoicOver, same as with Chrome 71.Internet Explorer 11 with…
JAWS 2019
Same as with Firefox.NVDA 2018
Same as with Firefox.Notes on screen reader behaviour:
- Although all browsers expose
<th>
as row or column headers (except IE11 of course) depending on the placement of the<th>
elements, no screen readers (except Narrator) explicitly identify the role of these elements. This is an aural UI design choice on the part of the screen reader developers and not something we should sweat. - Header cell content is announced when users navigate to a cell in a new row or column, the order in which the cell information is announced, varies across screen readers.
- Header cell content is also announced when user invoke the commands to announce column or row content information.
- JAWS has the richest set of commands to interrogate the table data, followed by VoiceOver, NVDA has the least. It is unknown additional JAWS/VoiceOver keystrokes provide any practical benefit to users.
- Contrary to the statements in the WAI tutorials about ambiguity leading to screen readers to incorrectly announce
content, no ambiguity was found and thus no need to use additional markup such as the
scope
attribute. For simple data tables browsers correctly assign header semantics based on the use of<th>
alone.
Drink to the browser engine that was – Edge
Given that the recent news that the Edge browser engine is to be replaced with Chromium, discussing how tables are supported in Edge is somewhat moot. Microsoft has indicated that as part of its future contributions to chromium will be to add UI Automation support. So what we see today could be indicative of what is implemented in Chromium.Microsoft Edge and Chromium Open Source: Our Intent – by @MSEdgeDev https://t.co/Ny5UCev5Yt
— Steve Faulkner (@stevefaulkner) December 6, 2018
Conclusion
For simple tables at least, browser and screen reader interoperability is good. Developers need only use<th>
to identify column or row headers and modern browsers take care of the rest or in the case of IE11 screen readers fix its brokenness. I realise that this article does not cover all screen readers and platforms, feel free to use the test cases to test and feedback any new data — thanks!
And please realise this is only 1 beer’s worth of testing. Will have to invest in a slab of stubbies to tackle more complex tables…