Unintentionally tabling table semantics
I feel like I have a knack for finding bugs and uncovering oddities in how HTML and/or ARIA is exposed to browsers’ accessibility trees. Rarely do I say “let’s go find some bugs to write about”. Specifically because “let’s” indicates I’d be talking to someone else to share these odd choices for adventures with.
The fact of the matter is I’m often alone in my discoveries, and they’re often discoveries I didn’t want to make. Truly, the main reason I find most of these issues is because I have stopped assuming things will work as expected. What a sunny outlook I have, no?
Anyway, today’s discovery? Flimsy tables.
A sticky situation
It started innocently enough. I was attempting to help Adrian Roselli with an issue related to
position: sticky with Safari on macOS and iOS.
Safari requires -webkit-sticky, and then gets offset by the <caption>. Thanks to @scottohara for reminding me prefixed styles are still a thing.— Adrian Roselli 🗯 (@aardrian) April 17, 2019
As Adrian’s tweet mentions, the first issue was that we needed to use
position: -webkit-sticky to get Safari to mostly work. The next problem though was that if a
table contained a
caption the sticky
thead wouldn’t stick to the top of the browser, but would rather stick to a position that was equal in height to the size of the table’s caption.
So that isn’t acceptable.
Since hacking at the CSS would just cause issues with the browsers that worked correctly, I tried thinking about the problem from a different angle: a
caption provides an accessible name to a
table. Why not use a paragraph outside of the table and point to it with
aria-labelledby? What could possibly go wrong?
A table by any other name is apparently not a table
Per the HTML AAM, a
table should be able to receive it’s accessible name from
title (if none of the prior methods were used).
Though, the reality of the situation is revealed in testing. Providing the
table with an
aria-labelledby to point to the faux caption, I noticed that VoiceOver was announcing the
table as a “group”.
Alright. Seems I’m doing this again…
Attempting to mitigate this unwanted behavior, I tried using
aria-describedby instead, even though I knew the attribute wouldn’t communicate the “caption” in the intended way. No matter though, as not only did
aria-describedby not match the way in which a
caption should be announced (as expected), the
table’s role was completely negated. It didn’t even announce as a group this time. The same behavior also occurs when using
Investigating further, Chrome on macOS expose tables with
titles with a role of
Quickly checking with Firefox, Internet Explorer 11, and Edge (pre-Chromium), all these browsers continue to expose
tables as expected. When each was paired with JAWS 2019, aside from some minor oddities with Edge, the tables were discoverable and announced as expected.
When testing JAWS 2019 with Chrome, JAWS was at least able to identify tables as tables. However, the number of columns were incorrectly announced for these quirky tables. JAWS was at least picking up some slack here, but couldn’t fully fill the gaps.
I did not test with NVDA this time around. I had enough evidence to indicate that this was broken with Webkit based browsers. But hey, if you want to give it a go and see what else you can find, here’s the reduced test case:
See the Pen testing table "captions" by Scott (@scottohara) on CodePen.
And here’s a link directly to the test case on CodePen.
As one should do when they find unexpected behavior, I have filed a bug with WebKit.
This whole line of testing began with trying to help Adrian find a way around Safari’s issue with
position: sticky and a table’s
To go full circle, I figure it’s a good idea to mention that if you want to learn a few more ways you can muck up table semantics (and then reintroduce them) you should check out Adrian’s post Tables, CSS Display Properties, and ARIA.