Developers who choose HTML elements that best describe a screen’s structure and semantics often don’t know how browsers use their CSS to break those semantics.
2. Agenda
About Me
Use Case
HTML Tables
Responsive Web Design (RWD)
CSS Display Properties
ARIA to the Rescue?
ARIA Grid
display:contents
How is This a Thing?
Wrap-up
3. Adrian Roselli
• Building for the web
since 1993,
• Learn more at
AdrianRoselli.com,
• Avoid on Twitter
@aardrian.
5. UseCase
Build a layout that can adapt to screen sizes,
Uses a native HTML element that has inbuilt structure,
Also has inbuilt semantics,
Provides a specific set of nodes in the accessibility tree.
7. HTMLTables
We will use HTML tables as our proxy,
They have a long history on the web,
Used for layout and tabular data,
Have a specific DOM structure,
Have their own navigation methods in screen readers.
8. BasicHTMLTable
Make a valid HTML <table>,
Avoid spanning cells,
Make sure you use <th> for headers,
Add a useful <caption>.
9. <table>
<caption>Books I May or May Not Have Read</caption>
<tr>
<th>Author</th>
<th>Title</th>
<th>Year</th>
</tr>
<tr>
<td>Miguel De Cervantes</td>
<td>The Ingenious Gentleman Don Quixote of La Mancha</td>
<td>1605</td>
</tr>
[…]
</table>
BasicHTMLTable
10. Complexity#1:RowHeaders
Continue to use <th>,
Add the scope attribute using the values (as appropriate):
- row, col, rowgroup, colgroup.
Conforms to WCAG technique H63: Using the scope attribute to
associate header cells and data cells in data tables.
12. Complexity#2:SpanningCells
Continue to use <th>,
Every <th> gets an id,
Every <td> gets a headers attribute
The headers value is the id of the <th> you want it to use,
Conforms to WCAG 2.0 technique H43: Using id and headers
attributes to associate data cells with header cells in data tables.
15. ResponsiveTables
Specifically talking about viewport width,
Let it scroll off-screen:
- Add tabindex="0" for keyboard users,
- Add role="region" so screen readers announce it,
- Add aria-labelledby so screen readers give it a name,
- Set the aria-labelledby value to the id of the <caption>.
16. ResponsiveTable
<div role="region" aria-labeledby="Cap1" tabindex="0">
<table>
<caption id="Cap1">Books I May or May Not Have Read</caption>
<tr>
<th>Author</th>
<th>Title</th>
<th>Year</th>
<th>ISBN-13</th>
<th>ISBN-10</th>
</tr>
<tr>
<td>Miguel De Cervantes</td>
<td>The Ingenious Gentleman Don Quixote of La Mancha</td>
<td>1605</td>
<td>9783125798502</td>
<td>3125798507</td>
</tr>
[…]
</table>
</div>
24. CSSDisplayProperties
The following override native semantics in the browser:
- display: block
- display: inline
- display: grid
- display: flex
- display: contents
25. CSSDisplayProperties
Nothing in the HTML / CSS specifications mandates this,
Does not work in reverse:
- display: table
- display: table-cell
26. AssistiveTechnology(AT)
Browsers do not convey correct semantics to AT,
Users who rely on these semantics can be stranded:
- Understanding content,
- Navigating a page.
27. TablesasaCanary
Breaking semantics of any single required child element can break
entire table:
- A missing row, column or row header;
- The parent table even with good rows and cells.
31. AccessibilityTree
A sub/super-set of the DOM,
Includes UI objects of browser & objects of the document,
Created in tree for every DOM element that:
- Fires an accessibility event,
- Has a property, relationship or feature which needs to be exposed.
Is abstracted for dev tools.
37. Chromev80
Released February 19, 2020,
Fixes flex bug on table,
Caused me to re-examine overall,
Other fixes / changes are in there,
Browsers based on Blink (ChromiEdge) will benefit.
38.
39. TheWebIsNotChrome
Screen Reader & Browser # of Respondents % of Respondents
JAWS with Chrome 259 21.4%
NVDA with Firefox 237 19.6%
NVDA with Chrome 218 18.0%
JAWS with Internet Explorer 139 11.5%
VoiceOver with Safari 110 9.1%
JAWS with Firefox 71 5.9%
VoiceOver with Chrome 36 3.0%
NVDA with Internet Explorer 14 1.2%
Other combinations 126 10.4%
WebAIM Screen Reader Survey #8 (2019)
45. display:table
display: table, table-caption, table-row, table-cell;
Each of these will add layout-table semantics in Chrome v80,
There is no CSS display property for col/row headers,
Requires a well-structured DOM,
Not a workaround, fix, or way to do <div>s-as-tables.
46.
47. display:table
As LayoutTable, LayoutRowTable, LayoutCellTable;
JAWS, Narrator will read this as a table,
- But without col/row headers,
NVDA, VO, TalkBack will not read this as a table.
48. Chromev82
Will support align-items on <button>s,
- When display: inline-grid / grid / inline-flex / flex is applied,
Lack of support has hampered <button> uptake in these layouts,
Expect to see more <button>s with more display properties.
55. ARIAGrid
Do not use for simple data tables,
Intended to mimic Excel-style spreadsheet,
A grid is a composite widget so it:
- Contains multiple interactive controls,
- Has only one tab-stop in the sequence,
- Requires author to provide code to manage focus within.
57. Whatisdisplay:contents
The element does not generate any boxes,
- Its children and pseudo-elements still generate boxes,
- Text runs as normal,
For box generation & layout, element treated as if replaced in element tree
by its contents,
- As if opening and closing tags removed,
Also yanks it from accessibility tree.
58. Whydisplay:contentsIsMoreDangerous
You cannot add it back to the accessibility tree with ARIA,
- You can give it an accessible name and properties,
- But these are not passed to screen readers,
Some browsers do not hand the information off,
If used as a poor-dev’s CSS reset:
- Will hide elements from assistive technology,
- Will hide semantics from assistive technology.
65. Bugs!
Firefox bug 1455357 (19-Apr-2018): Setting grid item to display:
contents resets its accessible role
Chromium Issue 835455 (20-Apr-2018): Element not exposed to
accessibility tree when it is set to display: contents
Safari bug 39630240 (which I cannot see because my AppleID may
not have the needed permissions to see it)
CSSWG #2632 (30-Apr-2018): [css-display][css-aam][selectors-4]
How elements with `display:contents` get focused?
67. AssistiveTechIsNotatFault
Not screen readers’ fault,
Accessibility information comes from browser,
Screen reader needs more than DOM to understand page,
Cannot ignore all but the DOM:
- Years of HTML tables for layout informed screen readers,
- Screen readers developed heuristics for dealing with tables.
68. DetectingATIsNotViable
Users generally don’t want us to be able to detect screen readers,
Not all screen reader users are blind anyway,
Mouse actions are a poor proxy for sighted screen reader users,
Disabling a site’s CSS for screen reader users is impractical (and a
terrible, terrible idea).
69. CSSIsNotBlameless
CSS already impacts HTML semantics — display: none,
Using display: table does (generally) not impart HTML table
semantics,
CSS flex or grid makes it easy for content order and source order to
disagree,
CSS grid to lay out an HTML table still won’t be a table semantically.
70. ARIAIsNotIdeal
You must understand ARIA and the table structure,
This will require you to keep current on SR and browser support,
You have to manage headers and other content you might hide,
Consider how this scales with CSS does not load,
This is not the purpose of ARIA,
The technique here is a stop-gap.
71. TheBrowserIsNotRight
The CSS spec does not state that semantics should be dropped,
As display properties, there is no reason to remove them,
The accessibility tree should not care about visuals.
73. References
It’s OK to Use Tables
Hey, It’s Still OK to Use Tables
A Responsive Accessible Table
Tables, CSS Display Properties,
and ARIA
Tables, JSON, CSS, ARIA,
RWD, TLAs…
GitHub Contributions Chart
Short note on what CSS display
properties do to table semantics
by Steve Faulkner
Data Tables by Heydon Pickering
How display: contents; Works by
Ire Aderinokun
CSS3 — Appendix B: Effects of
display: contents on Unusual
Elements
Building for the web since 1993,
Learn more at AdrianRoselli.com,
Avoid on Twitter @aardrian.
Let’s talk about an example use case
Think about an HTML structure that challenges developers across screen sizes and contexts
HTML has a great way to present information in two axes.
Tables will be my proxy throughout
First a recap of tables
Coding them is easy, though it can be monotonous.
A series of rows, consistently coded.
A header.
A caption.
Sure, they can be a bit more complex, but that only adds some attributes.
Generally spanning is a bad idea, but it has its place.
Responsive design may have been the cause of some of this resistance to tables
Lists have fared much better.
Now let’s look at how RWD complicates things
Tables are the bane of the typical responsive developer.
This is arguably the easiest and least-risky approach
Still using tables as our example.
Requirements might demand some visual restructuring
Print is a media query, just like width, so support it.
You likely will have to do nothing on a simple table.
Unless you are using background colors or images.
Perhaps you want to try a more novel way of adapting to a narrow width.
You can rearrange the table cells using CSS.
CSS display properties just as block, grid, flex can all be powerful.
I convert everything in the table to block to make layout easier,
Dumps all the table, row, and cell styling,
I use grid on the cells to make it easier to add the ‘headings’ inline.
I convert everything in the table to block to make layout easier,
Dumps all the table, row, and cell styling,
I use grid on the cells to make it easier to add the ‘headings’ inline.
CSS as implemented in browsers today can remove semantics,
Conversely, you can not add it back with CSS
CSS as implemented in browsers today can remove semantics,
Conversely, you can not add it back with CSS
If any one part of a valid table goes away, the entire thing falls down.
Mis-count of rows or columns,
Headers associated with wrong data.
Harder to see this in action with elements that do not have so many required children in a required structure.
A broken table means your code may have this elsewhere.
Github just wanted to prevent wide tables from breaking its layout.
It made the table scrollable instead of a container.
To do that required .markdown-body table {display: block;}.
That made the table useless to SR and keyboard users.
Using NVDA with Firefox
Hit T to get to the table
Using Ctrl + Alt + arrow keys to navigate the table
Announces column headings as I change columns
Tells me when at the edge
Using NVDA with Firefox
Hitting T will not bring me to the table
Using Ctrl + Alt + arrow keys will not work
Does not announce column nor row count
Does not tell me when I am at the edge
Table before CSS display properties on the left
Table after CSS display properties on the right
Note how the entire accessibility tree is gone
Caption before CSS display properties on the left
Caption after CSS display properties on the right
Its caption role is maintained
But it is not associated with a table
Th before CSS display properties on the left
Th after CSS display properties on the right
Not associated with the table
No computed properties
Td before CSS display properties on the left
Td after CSS display properties on the right
Not associated with the table
No computed properties
Then things went all wobbly
Chrome 80 was released.
It fixed a bunch of issues related to tables.
The highlighted cell is a flex item in a flex container.
This image shows the accessibility inspector.
The inspector shows it as a cell in a row.
Yes, it is always gridcell
This does not mean all is well.
Chrome with JAWS makes up only ~22% of screen reader users.
Chrome with NVDA is another 18%.
Remember this is survey data.
We don’t know how other assistive technology is handling it (I ran out of time to test).
Chrome 80 does well with flex, grid, block, inline-block, and contents.
Across tables, lists, headings, and buttons.
Except lists with display: contents.
<th>s with flex and grid are announced as cells, not col or row header,
Inserts text leaf between each one,
Issues a keyboard use warning.
But recognizes <dl>
Chrome 80 does well with flex, grid, block, inline-block, and contents.
Across tables, lists, headings, and buttons.
Except lists with display: contents.
Essentially performs as desktop
Treats all cells belonging in column 1.
Still fires on double-tap with VO.
If you create a structure like a table and add table-related display styles, Chrome calls it a layout table.
CSS align-items defines the cross-axis
The vertical axis in LTR languages
Used for vertical alignment (centering, expanding, top, bottom, etc.)
There is a long aversion to tables owing to their mis-use for layout.
So some people try to use other HTML elements,
They opt to “throw ARIA” at them.
You can use ARIA to re-insert lost semantics
Caption role coming in ARIA 1.2
Grid slides coming up
Using NVDA with Firefox
Hit T to get to the table
Using Ctrl + Alt + arrow keys to navigate the table
Announces column headings as I change columns
Tells me when at the edge
ARIA grids are a terrible idea and are not for data tables.
Not covering in this talk
I am seeing this quickly become the new hotness.
I want to call this one out specifically.
I am seeing this quickly become the new hotness.
I want to call this one out specifically.
We know Chrome v80 has just addressed a bunch of issues,
I covered it in the previous slides,
The following slides show an older version of Chrome,
They also demonstrate how you can confirm support without needing to fire up all your tools.
Table before CSS display properties on the left
Table after CSS display properties on the right
Note how it is ignored in the accessibility tree
The role does not bring it back
ul before CSS display properties on the left
ul after CSS display properties on the right
Note how it is ignored in the accessibility tree
The role does not bring it back
button before CSS display properties on the left
button after CSS display properties on the right
Note how it is ignored in the accessibility tree
The role does not bring it back
h2 before CSS display properties on the left
h2 after CSS display properties on the right
Note how it is ignored in the accessibility tree
The role does not bring it back
30 seconds of navigating by element type then by virtual cursor
Some of this support has changed
Again, see previous slides
This demonstrates how you can test.
These bugs are still open.
Even the fixes in Chrome v80 do not close the Chromium issue.
You may ask yourself: where is my beautiful table?
You may ask yourself: where are the table semantics?
And you may ask yourself: why is this so broken?
Because developers used layout tables for years, SRs had to improvise to make them useable.
Still using tables as my proxy, focus on SRs (which are not the only AT).
How do you account for those with mobility impairments who do not use a mouse?
Or mobile screen reader users who rely on touch gestures
Think about how it used for vertical centering because vertical centering was not a thing in CSS for so long
First Rule of ARIA!
As ARIA fixes it in browser exposure, should help other AT.