﻿WEBVTT

00:00:13.960 --> 00:00:15.820
- [Adrian] Thank you for attending.

00:00:15.820 --> 00:00:20.500
My talk CSS Display Properties
versus HTML Semantics.

00:00:20.500 --> 00:00:22.020
We have a bunch of things

00:00:22.020 --> 00:00:24.900
that we are going to cover in this talk.

00:00:24.900 --> 00:00:26.480
I've put together a quick agenda.

00:00:26.480 --> 00:00:28.050
But don't worry about that so much,

00:00:28.050 --> 00:00:30.020
I'll get to everything here.

00:00:30.020 --> 00:00:31.910
Hi, I am Adrian Roselli.

00:00:31.910 --> 00:00:35.370
I have been building
for the web since 1993.

00:00:35.370 --> 00:00:38.630
You can learn more about me
on my site adrianroselli.com.

00:00:38.630 --> 00:00:40.430
You can also avoid me on Twitter

00:00:40.430 --> 00:00:42.430
or block me right now @aardrian.

00:00:42.430 --> 00:00:45.450
That's A-A-R-D-R-I-A-N.

00:00:45.450 --> 00:00:47.000
For a little bit of context,

00:00:47.000 --> 00:00:49.340
so that you know the
person who is speaking

00:00:49.340 --> 00:00:51.870
might have some experience in this stuff

00:00:51.870 --> 00:00:53.430
or have a bit of a clue.

00:00:53.430 --> 00:00:54.450
I've written some books.

00:00:54.450 --> 00:00:56.320
I've written a bunch of magazine articles.

00:00:56.320 --> 00:00:58.570
I was one of the co-founders of evolt.org,

00:00:58.570 --> 00:01:00.910
used to write for Web Standards Sherpa.

00:01:00.910 --> 00:01:03.040
I have a few resource sites like

00:01:03.040 --> 00:01:07.770
'Does My Site Deserve
Recognition?' and a11y reviews.

00:01:07.770 --> 00:01:11.930
I've participated in W3C
standards creation for years.

00:01:11.930 --> 00:01:14.640
I'm one of the people
behind Inclusive Design 24

00:01:14.640 --> 00:01:19.293
and I do accessibility editorial
work over at A List Apart.

00:01:20.730 --> 00:01:23.470
So let's talk about an example use case

00:01:23.470 --> 00:01:26.650
for the overall range of my slides here.

00:01:26.650 --> 00:01:29.920
Think about an HTML structure
that challenges developers

00:01:29.920 --> 00:01:32.663
across screen sizes and context.

00:01:34.590 --> 00:01:36.710
Think about something where
you have to build a layout

00:01:36.710 --> 00:01:38.330
that can adapt to screen sizes.

00:01:38.330 --> 00:01:41.350
Something that has an inbuilt structure,

00:01:41.350 --> 00:01:44.850
with inbuilt semantics where
the nodes that are exposed

00:01:44.850 --> 00:01:47.830
in the accessibility tree
have to be put together

00:01:47.830 --> 00:01:49.963
in the DOM in a very particular way.

00:01:50.960 --> 00:01:54.320
The example I'm gonna use is HTML tables.

00:01:54.320 --> 00:01:57.223
It's a great way to present
information in two axes.

00:01:58.170 --> 00:02:01.170
They kind of are the perfect proxy

00:02:01.170 --> 00:02:02.790
for everything I wanna do.

00:02:02.790 --> 00:02:04.540
So let's recap them really quickly.

00:02:05.620 --> 00:02:08.200
HTML tables have a long
history on the web.

00:02:08.200 --> 00:02:10.550
They have been used not
just for tabular data

00:02:10.550 --> 00:02:13.950
but also for layout since
they were first introduced.

00:02:13.950 --> 00:02:16.160
That was kind of their thing.

00:02:16.160 --> 00:02:18.470
They have a very specific DOM structure.

00:02:18.470 --> 00:02:22.730
If you leave nodes out,
the thing can fall apart.

00:02:22.730 --> 00:02:24.850
They also have their
own navigation methods

00:02:24.850 --> 00:02:26.743
within screen readers, for example.

00:02:28.150 --> 00:02:31.760
A basic HTML table,
pretty straightforward.

00:02:31.760 --> 00:02:35.490
Avoid spanning cells, make
sure you use th for headers,

00:02:35.490 --> 00:02:37.060
add a useful caption.

00:02:37.060 --> 00:02:40.020
I mean, realistically,
coding tables is pretty easy

00:02:40.020 --> 00:02:42.420
even if it might be a bit monotonous.

00:02:42.420 --> 00:02:44.510
The idea is that it's a series of rows,

00:02:44.510 --> 00:02:47.780
consistently coded with
a header for each column,

00:02:47.780 --> 00:02:49.160
and a caption.

00:02:49.160 --> 00:02:51.860
In my example here, I
have a table that shows

00:02:51.860 --> 00:02:55.030
authors in one column,
titles in another,

00:02:55.030 --> 00:02:58.563
and years of their books
in the final column.

00:02:59.880 --> 00:03:03.090
Now you can start to add
some complexities to tables.

00:03:03.090 --> 00:03:05.250
Row headers is one of those complexities.

00:03:05.250 --> 00:03:07.210
You would still use a th element,

00:03:07.210 --> 00:03:09.500
but you would add scope attribute

00:03:09.500 --> 00:03:12.410
and choose a value as appropriate.

00:03:12.410 --> 00:03:14.120
Scope attributes that are valid include:

00:03:14.120 --> 00:03:17.070
row, col, rowgroup, and colgroup.

00:03:17.070 --> 00:03:20.070
And making sure that your
row headers are well-coded,

00:03:20.070 --> 00:03:22.387
conforms to WCAG technique H63:

00:03:23.570 --> 00:03:26.110
Using the scope attribute
to associate header cells

00:03:26.110 --> 00:03:28.850
and data cells in data tables.

00:03:28.850 --> 00:03:32.210
So this is a pretty
straightforward bit of complexity.

00:03:32.210 --> 00:03:33.870
In the example I'm showing here,

00:03:33.870 --> 00:03:36.740
it's phone numbers and fax numbers

00:03:36.740 --> 00:03:38.910
in cities for some people.

00:03:38.910 --> 00:03:42.393
And those people's names are
essentially the row headers.

00:03:43.850 --> 00:03:46.650
Now we can make it a
little bit more complex.

00:03:46.650 --> 00:03:49.390
Complexity number two would
be some spanning cells.

00:03:49.390 --> 00:03:51.063
You'd still use a th.

00:03:51.930 --> 00:03:55.140
But every th at that point gets its own id

00:03:55.140 --> 00:03:57.890
and then every td, every individual cell,

00:03:57.890 --> 00:03:59.730
gets a headers attribute.

00:03:59.730 --> 00:04:02.860
And the headers attribute
points to the id or ids

00:04:02.860 --> 00:04:06.460
of the th or ths that
you want it to reference.

00:04:06.460 --> 00:04:09.890
This conforms to WCAG 2.0 technique H43:

00:04:09.890 --> 00:04:13.080
Using id and headers attributes
to associate data cells

00:04:13.080 --> 00:04:15.500
with header cells in data tables.

00:04:15.500 --> 00:04:18.850
Now, generally, spanning is a bad idea.

00:04:18.850 --> 00:04:20.470
It has its place.

00:04:20.470 --> 00:04:23.730
This example shows homework assignments

00:04:23.730 --> 00:04:26.620
or homework percentage
when factoring in grades

00:04:26.620 --> 00:04:29.770
and compares it to exams and
projects across two semesters.

00:04:29.770 --> 00:04:32.740
And it uses exams spanning three columns

00:04:32.740 --> 00:04:35.070
and projects spanning three columns

00:04:35.070 --> 00:04:38.370
to compare first semester, second semester

00:04:38.370 --> 00:04:40.570
and then final exam.

00:04:40.570 --> 00:04:43.180
This example and the previous example

00:04:43.180 --> 00:04:46.140
are both lifted from W3C documents,

00:04:46.140 --> 00:04:48.390
showing how to correctly code tables

00:04:49.240 --> 00:04:51.703
and these two variations of complexity.

00:04:53.250 --> 00:04:57.030
Now responsive design
may have been the cause

00:04:57.030 --> 00:05:00.200
of some of the resistance
to tables that we see today.

00:05:00.200 --> 00:05:02.910
A lot of developers are very
uncomfortable using tables.

00:05:02.910 --> 00:05:05.740
They think that they are the antithesis

00:05:05.740 --> 00:05:07.570
of good development practices.

00:05:07.570 --> 00:05:10.480
Lists have fared much better
for a variety of reasons.

00:05:10.480 --> 00:05:12.840
So let's look a little
bit at how responsiveness

00:05:12.840 --> 00:05:14.510
complicates things.

00:05:14.510 --> 00:05:16.210
Specifically for the next few slides,

00:05:16.210 --> 00:05:18.340
I'm gonna talk about viewport width.

00:05:18.340 --> 00:05:19.950
There's a lot more to responsiveness,

00:05:19.950 --> 00:05:22.460
but just the viewport width for this.

00:05:22.460 --> 00:05:25.050
Again the tables are typically the bane

00:05:25.050 --> 00:05:27.710
of a typical responsive developer.

00:05:27.710 --> 00:05:30.250
But I'm showing you here
probably the easiest

00:05:30.250 --> 00:05:33.540
and least risky approach
to make a responsive table.

00:05:33.540 --> 00:05:36.370
And namely just letting
it scroll off-screen.

00:05:36.370 --> 00:05:37.510
Put it in a container,

00:05:37.510 --> 00:05:40.260
add a tabindex of zero to that container

00:05:40.260 --> 00:05:42.360
so that a keyboard user can tab to it

00:05:42.360 --> 00:05:45.830
and then arrow right or
left to scroll the view.

00:05:45.830 --> 00:05:48.770
Add a role region so that
screen readers announce it.

00:05:48.770 --> 00:05:50.520
And add aria-labelledby

00:05:50.520 --> 00:05:52.040
so screen readers will give it a name.

00:05:52.040 --> 00:05:55.050
And, ideally,
aria-labelledby will point to

00:05:55.050 --> 00:05:57.263
the id of the table's caption.

00:05:58.230 --> 00:06:01.410
Simple example here, using my books table,

00:06:01.410 --> 00:06:02.800
added a couple more columns,

00:06:02.800 --> 00:06:06.100
and we can see it's too
wide for that narrow view.

00:06:06.100 --> 00:06:08.600
So there is a scroll bar
sitting at the bottom.

00:06:08.600 --> 00:06:09.433
That's it.

00:06:09.433 --> 00:06:12.750
Tab to it, scroll back and
forth and you're in good shape.

00:06:12.750 --> 00:06:16.623
Now responsive is more
than just viewport width.

00:06:17.510 --> 00:06:18.947
Even if it were just viewport width,

00:06:18.947 --> 00:06:21.520
the scrolling table might not cut it.

00:06:21.520 --> 00:06:23.360
I'm still using tables as the example,

00:06:23.360 --> 00:06:25.690
but your requirements might demand

00:06:25.690 --> 00:06:27.363
some visual restructuring.

00:06:28.210 --> 00:06:31.070
One example is having your
tables respond to print,

00:06:31.070 --> 00:06:34.200
because print is a media
query, just like width,

00:06:34.200 --> 00:06:36.893
so you ideally would
still need to support it.

00:06:37.830 --> 00:06:40.190
Similarly, there's
Windows high contrast mode

00:06:40.190 --> 00:06:42.080
or other display settings.

00:06:42.080 --> 00:06:44.450
And these are feature queries.

00:06:44.450 --> 00:06:46.740
Ideally, you do nothing on a simple table.

00:06:46.740 --> 00:06:49.680
If you're using background
colors or background images,

00:06:49.680 --> 00:06:51.830
obviously this can
complicate things a bit.

00:06:55.470 --> 00:06:58.530
Now you might want to try a more novel way

00:06:58.530 --> 00:07:00.510
of adapting to a narrow width.

00:07:00.510 --> 00:07:05.510
One thing you can do is rearrange
the table cells using CSS.

00:07:05.540 --> 00:07:08.870
CSS display properties,
block, grid and flex,

00:07:08.870 --> 00:07:11.270
can all be pretty powerful to do this.

00:07:11.270 --> 00:07:13.210
In the animated example here,

00:07:13.210 --> 00:07:14.620
I'm showing how the table gets

00:07:14.620 --> 00:07:16.990
narrower and narrower and the text wraps

00:07:16.990 --> 00:07:18.870
up to the point where
it becomes too narrow

00:07:18.870 --> 00:07:21.470
and then the table restructures itself

00:07:21.470 --> 00:07:24.640
and it stacks all the cells
on top of one another.

00:07:24.640 --> 00:07:27.140
And even when the viewport is too narrow

00:07:27.140 --> 00:07:29.970
to fit all of the width of the text,

00:07:29.970 --> 00:07:32.180
there's still a scroll bar on it.

00:07:32.180 --> 00:07:34.180
So I've got sort of best of both worlds.

00:07:34.180 --> 00:07:37.510
I can still stack it and,
in those very rare cases

00:07:37.510 --> 00:07:39.270
where somebody scaled the text a lot

00:07:39.270 --> 00:07:41.020
and they're on a smaller device,

00:07:41.020 --> 00:07:43.470
they can still at least
scroll to see everything.

00:07:45.560 --> 00:07:48.710
The CSS I'm showing here,
pretty straightforward.

00:07:48.710 --> 00:07:51.170
I convert everything in the table to block

00:07:51.170 --> 00:07:54.420
the table the tr and the
td to make the layout easier,

00:07:54.420 --> 00:07:57.590
dumping all of the table
row and cell styling.

00:07:57.590 --> 00:07:59.660
And then for the individual cells,

00:07:59.660 --> 00:08:04.660
to make the layout easier,
I set it as display: grid.

00:08:04.730 --> 00:08:07.530
And then I add my headings,
the column headings,

00:08:07.530 --> 00:08:08.913
as inline text.

00:08:11.080 --> 00:08:15.260
Just a little bit of a
view of it in the editor

00:08:15.260 --> 00:08:17.510
so you can see how
everything comes together.

00:08:19.040 --> 00:08:22.820
Now let's talk a little bit
about CSS display properties.

00:08:22.820 --> 00:08:25.210
The following properties
are going to override

00:08:25.210 --> 00:08:27.600
native semantics in the browser.

00:08:27.600 --> 00:08:29.870
This isn't necessarily how it should be.

00:08:29.870 --> 00:08:34.870
But display: block, inline,
grid, flex, or contents

00:08:34.920 --> 00:08:37.777
are all going to remove the semantics.

00:08:37.777 --> 00:08:40.730
You can't use CSS to
add it back in either.

00:08:40.730 --> 00:08:43.480
So if you're using any of
these display properties,

00:08:43.480 --> 00:08:46.970
there's the risk that whatever
your structure semantics are

00:08:46.970 --> 00:08:48.193
can be blown away.

00:08:49.230 --> 00:08:53.843
Nothing in the HTML nor CSS
specifications mandates this.

00:08:55.970 --> 00:08:59.450
Again can't add display:
table or display: table-cell

00:08:59.450 --> 00:09:01.723
and make the semantics
magically come back.

00:09:03.090 --> 00:09:05.640
When it comes to assistive technology,

00:09:05.640 --> 00:09:08.300
the browsers aren't
conveying those semantics

00:09:08.300 --> 00:09:09.880
to assistive technology.

00:09:09.880 --> 00:09:11.640
So a screen reader, for example,

00:09:11.640 --> 00:09:15.020
isn't going to know that
something is a table.

00:09:15.020 --> 00:09:19.640
So for users who rely on
the semantics from a table,

00:09:19.640 --> 00:09:21.000
they can be stranded.

00:09:21.000 --> 00:09:23.210
They might not be able
to understand the content

00:09:23.210 --> 00:09:26.840
of rows and columns and those
relationships fall apart.

00:09:26.840 --> 00:09:28.340
It also means they might not be able

00:09:28.340 --> 00:09:31.670
to navigate the content,
maybe the entire page

00:09:31.670 --> 00:09:34.130
depending on how much
information you have.

00:09:34.130 --> 00:09:38.603
So I look at tables as sort
of a canary in a coal mine.

00:09:39.600 --> 00:09:41.330
Breaking semantics of any single

00:09:41.330 --> 00:09:43.180
required child element of a table

00:09:43.180 --> 00:09:45.210
can break the entire table.

00:09:45.210 --> 00:09:49.010
If you're missing a row
or a column or row header,

00:09:49.010 --> 00:09:52.250
or if the parent table has rows in spans

00:09:52.250 --> 00:09:56.260
that have been overridden
by CSS display properties,

00:09:56.260 --> 00:09:57.740
the whole thing falls down.

00:09:57.740 --> 00:10:00.100
You can get a miscount of rows or columns,

00:10:00.100 --> 00:10:02.700
so it tells you a number
that isn't accurate,

00:10:02.700 --> 00:10:05.620
headers can be associated
with the wrong data.

00:10:05.620 --> 00:10:07.380
And it's hard to see this in action

00:10:07.380 --> 00:10:10.470
with elements that don't have
so many required children.

00:10:10.470 --> 00:10:13.690
Lists don't make this as visible.

00:10:13.690 --> 00:10:16.400
So think of tables as sort of code smell.

00:10:16.400 --> 00:10:19.250
If your table is broken because of CSS,

00:10:19.250 --> 00:10:22.283
you might have this problem
somewhere else in your code.

00:10:23.410 --> 00:10:25.520
Now I have an example here of GitHub

00:10:25.520 --> 00:10:28.650
and how it implements tables by default.

00:10:28.650 --> 00:10:30.950
It wants tables to scroll,

00:10:30.950 --> 00:10:33.540
because it's very easy
for a table to become

00:10:33.540 --> 00:10:36.430
wider than their layout, not the viewport,

00:10:36.430 --> 00:10:38.520
but their fixed width layout

00:10:38.520 --> 00:10:40.520
or their maximum fixed width layout.

00:10:40.520 --> 00:10:44.800
So what they do is they put display: block

00:10:44.800 --> 00:10:46.800
on the table element instead.

00:10:46.800 --> 00:10:48.640
They don't put it in
a scrolling container,

00:10:48.640 --> 00:10:51.053
they make the table scrollable.

00:10:51.053 --> 00:10:56.053
And they do that with
.markdown-body table display: block.

00:10:56.780 --> 00:10:59.740
That makes the table useless
to screen reader users

00:10:59.740 --> 00:11:01.490
and useless to keyboard users

00:11:01.490 --> 00:11:03.480
because there's not even a tab stop,

00:11:03.480 --> 00:11:05.750
there's no tabindex=0
on that table

00:11:05.750 --> 00:11:08.520
to allow them to scroll back and forth.

00:11:08.520 --> 00:11:12.330
So looking at the example
table I had before,

00:11:12.330 --> 00:11:16.310
if I restructure that
layout just as it is,

00:11:16.310 --> 00:11:18.540
don't do anything else, except use the CSS

00:11:18.540 --> 00:11:22.550
to make it responsive, it
falls down in screen reader.

00:11:22.550 --> 00:11:27.170
So what I've done here is I've
paired up Firefox with NVDA.

00:11:27.170 --> 00:11:29.280
I'm probably not gonna
let the whole thing play,

00:11:29.280 --> 00:11:32.480
but essentially I'm hitting
T to get to the table,

00:11:32.480 --> 00:11:34.660
then I'm using control, alt and arrow keys

00:11:34.660 --> 00:11:35.833
to navigate the table.

00:11:38.360 --> 00:11:39.410
- [NVDA] Books I May or May Not Have Read.

00:11:39.410 --> 00:11:40.620
Region, Books I May or Not Have Read.

00:11:40.620 --> 00:11:41.950
Table with seven rows and five columns,

00:11:41.950 --> 00:11:43.590
Books I May or May Not Have Read.

00:11:43.590 --> 00:11:45.610
- [Adrian] I should qualify
that this is actually

00:11:45.610 --> 00:11:47.930
is the table with the correct semantics

00:11:47.930 --> 00:11:50.523
before I've applied
the display properties.

00:11:51.990 --> 00:11:56.023
And then I've gone and broken
it, because I jumped ahead.

00:11:57.160 --> 00:11:58.210
- [NVDA] Books I May or May Not Have Read.

00:11:58.210 --> 00:11:59.430
Region, Books I May or Not Have Read.

00:11:59.430 --> 00:12:00.750
Table with seven rows and five columns,

00:12:00.750 --> 00:12:03.000
Books I May or May Not Have Read.

00:12:03.000 --> 00:12:05.170
Row one, column one, Author.

00:12:05.170 --> 00:12:06.620
Row two, Miguel De Cervantes.

00:12:07.490 --> 00:12:08.870
Title, column two, The Ingenious Gentleman

00:12:08.870 --> 00:12:10.240
Don Quixote of La Mancha.

00:12:10.240 --> 00:12:12.680
Year, column three, 1605.

00:12:12.680 --> 00:12:15.160
Row three, 1818.

00:12:15.160 --> 00:12:16.697
Title, column two, Frankeinstein;

00:12:16.697 --> 00:12:18.700
or, The Modern Prometheus.

00:12:18.700 --> 00:12:20.460
Author, column one, Mary Shelley.

00:12:20.460 --> 00:12:24.170
- [Adrian] So we could hear
that the table that NVDA rather

00:12:24.170 --> 00:12:27.390
was announcing the
columns as I jumped around

00:12:27.390 --> 00:12:31.290
and it told me the column
position and row position.

00:12:31.290 --> 00:12:33.510
Once I add display properties, though,

00:12:33.510 --> 00:12:34.820
and I use those same commands

00:12:34.820 --> 00:12:36.530
to try to navigate the table,

00:12:36.530 --> 00:12:38.900
things are little bit different.

00:12:38.900 --> 00:12:40.280
- [NVDA] No next table.

00:12:40.280 --> 00:12:41.580
Not in the table cell.

00:12:41.580 --> 00:12:42.870
Author: Miguel De Cervantes.

00:12:42.870 --> 00:12:45.010
Title: "The Ingenious Gentleman
Don Quixote of La Mancha".

00:12:45.010 --> 00:12:46.883
Year: 1605.

00:12:47.720 --> 00:12:49.558
Not in the table cell.

00:12:49.558 --> 00:12:52.120
ISBN-13: 9783--

00:12:52.120 --> 00:12:54.730
- [Adrian] The gist there is that

00:12:54.730 --> 00:12:57.370
it doesn't recognize that
there's a table on the page

00:12:57.370 --> 00:12:59.690
and I can no longer navigate

00:12:59.690 --> 00:13:02.100
using standard screen reader navigation,

00:13:02.100 --> 00:13:03.990
table navigation commands.

00:13:03.990 --> 00:13:07.700
That's why NVDA keeps saying
not in a table cell.

00:13:07.700 --> 00:13:09.490
So all those relationships are gone,

00:13:09.490 --> 00:13:12.773
I no longer have any sense
of where I am in the table.

00:13:14.640 --> 00:13:16.960
Now it's important to understand

00:13:16.960 --> 00:13:20.110
the role of the accessibility
tree in all of this.

00:13:20.110 --> 00:13:24.000
The accessibility tree is
essentially a subset/super-set

00:13:24.000 --> 00:13:25.800
of the DOM depending.

00:13:25.800 --> 00:13:29.320
It includes user interface
objects of the browser

00:13:29.320 --> 00:13:30.883
and objects of the document.

00:13:32.260 --> 00:13:36.030
So what it does is for anything that fires

00:13:36.030 --> 00:13:38.900
an accessibility event or
has a property relationship

00:13:38.900 --> 00:13:42.940
or feature which needs to
exposed, and it's in the DOM,

00:13:42.940 --> 00:13:45.630
it gets added to the accessibility tree.

00:13:45.630 --> 00:13:47.010
What we're seeing when we look

00:13:47.010 --> 00:13:50.200
at the accessibility inspector
in the developer tools

00:13:50.200 --> 00:13:53.210
in Firefox or Chrome is an abstraction.

00:13:53.210 --> 00:13:54.750
It's not a one-to-one correlation

00:13:54.750 --> 00:13:57.470
for what the accessibility
tree looks like.

00:13:57.470 --> 00:14:00.650
So I have here side-by-side images

00:14:00.650 --> 00:14:03.060
comparing what the accessibility tree

00:14:03.060 --> 00:14:05.540
in Chrome's inspector should look like,

00:14:05.540 --> 00:14:10.540
for a standard table, compared
to what it looks like

00:14:10.940 --> 00:14:13.580
in the accessibility
inspector when you've added

00:14:13.580 --> 00:14:15.860
any display properties.

00:14:15.860 --> 00:14:18.510
On the left, the first
image, it shows it's a table,

00:14:18.510 --> 00:14:20.790
with a caption, it has rows.

00:14:20.790 --> 00:14:22.440
One of those rows has the column headers,

00:14:22.440 --> 00:14:24.450
the other rows have cells.

00:14:24.450 --> 00:14:28.110
The second image, just by
adding that display property,

00:14:28.110 --> 00:14:30.710
it now shows it as ignored.

00:14:30.710 --> 00:14:32.290
It has no computed properties,

00:14:32.290 --> 00:14:34.730
the accessibility node is not exposed,

00:14:34.730 --> 00:14:37.100
and that entire accessibility tree

00:14:37.100 --> 00:14:38.633
for the table has gone away.

00:14:39.870 --> 00:14:44.140
Similarly, for the caption,
in both cases I see a caption.

00:14:44.140 --> 00:14:47.560
The difference is once I
add those display properties

00:14:47.560 --> 00:14:50.080
that caption isn't
associated with anything.

00:14:50.080 --> 00:14:51.730
It's just a piece of text,

00:14:51.730 --> 00:14:53.480
floating in the accessibility tree.

00:14:54.650 --> 00:14:56.580
Ths go from being a column header

00:14:57.930 --> 00:15:00.020
to becoming just an ignored element

00:15:00.020 --> 00:15:01.903
that has no accessibility properties.

00:15:03.090 --> 00:15:06.030
Same is true with td cells.

00:15:06.030 --> 00:15:07.790
They go from being grid cells,

00:15:07.790 --> 00:15:11.150
which is the default way
that they are exposed

00:15:11.150 --> 00:15:13.630
in the Chrome accessibility inspector.

00:15:13.630 --> 00:15:16.470
They go from being grid
cells to being nothing.

00:15:16.470 --> 00:15:18.080
They have no structure,

00:15:18.080 --> 00:15:21.090
they are not exposed in
the accessibility tree,

00:15:21.090 --> 00:15:24.090
and they have no correlation
to anything else on the screen.

00:15:27.240 --> 00:15:29.823
So this is where things go all wobbly.

00:15:30.770 --> 00:15:34.730
Chrome version 80 was
released on February 19, 2020.

00:15:34.730 --> 00:15:37.450
And one of the things
that it explicitly does

00:15:37.450 --> 00:15:40.900
is it fixes the flex bug on tables.

00:15:40.900 --> 00:15:45.760
What that means is it no longer
ignores the table semantics

00:15:45.760 --> 00:15:48.430
if you add display: flex to a table.

00:15:48.430 --> 00:15:50.050
So this caused me to re-examine

00:15:50.050 --> 00:15:52.370
everything I had been looking at overall,

00:15:52.370 --> 00:15:56.400
which meant a bit of
panicked slide editing

00:15:56.400 --> 00:15:59.370
just a couple of weeks before CSUN.

00:15:59.370 --> 00:16:01.330
There are other fixes and changes

00:16:01.330 --> 00:16:03.720
that are part of Chrome version 80,

00:16:03.720 --> 00:16:06.380
and I'll talk a little
bit about some of those.

00:16:06.380 --> 00:16:08.891
Any browsers that are based on Blink,

00:16:08.891 --> 00:16:10.610
the core engine of Chrome,

00:16:10.610 --> 00:16:12.770
are gonna benefit from this change.

00:16:12.770 --> 00:16:15.930
The latest release of Edge, ChromiEdge,

00:16:15.930 --> 00:16:19.373
as opposed to the Legacy Edge,
will also benefit from this.

00:16:21.000 --> 00:16:26.000
So I have a screen showing a
table with display properties

00:16:26.540 --> 00:16:29.610
and I have them set to flex.

00:16:29.610 --> 00:16:33.090
And when I look at the
accessibility inspector in Chrome

00:16:33.090 --> 00:16:36.080
I can see that even with flex applied

00:16:36.080 --> 00:16:40.670
I'm still in a table, in a
row, and in a specific cell

00:16:40.670 --> 00:16:44.800
when I'm looking at any
particular cell in the table.

00:16:44.800 --> 00:16:47.930
This is good because it
maintains the semantics,

00:16:47.930 --> 00:16:50.370
it creates all the structures I need,

00:16:50.370 --> 00:16:52.600
or at least retains those structures,

00:16:52.600 --> 00:16:55.513
and it all lives there in
the accessibility tree.

00:16:56.650 --> 00:16:59.420
The thing that I've
highlighted is a flex item

00:16:59.420 --> 00:17:01.200
in a flex container.

00:17:01.200 --> 00:17:04.583
So the good news here is progress.

00:17:05.510 --> 00:17:06.840
But there's a little bit of bad news

00:17:06.840 --> 00:17:08.440
associated with this as well.

00:17:08.440 --> 00:17:10.483
Namely, the web is not Chrome.

00:17:12.500 --> 00:17:14.850
The slide that I'm showing here

00:17:14.850 --> 00:17:18.720
is data from the WebAIM Screen
Reader Survey number eight,

00:17:18.720 --> 00:17:22.410
which was released in September of 2019.

00:17:22.410 --> 00:17:24.640
So it's the most recent I have.

00:17:24.640 --> 00:17:26.660
It's a survey, which means it's not

00:17:26.660 --> 00:17:29.520
exactly perfect research.

00:17:29.520 --> 00:17:32.770
And the folks who are
answering the questions

00:17:32.770 --> 00:17:34.860
skew towards more technically savvy,

00:17:34.860 --> 00:17:37.030
but it's still some good insight.

00:17:37.030 --> 00:17:40.230
What this shows is that JAWS with Chrome

00:17:40.230 --> 00:17:43.550
makes up only 22% of screen reader users.

00:17:43.550 --> 00:17:47.640
NVDA with Chrome is another 18%.

00:17:47.640 --> 00:17:50.210
We don't know how other
assistive technology

00:17:50.210 --> 00:17:54.840
is handling how tables
are exposed or navigated,

00:17:54.840 --> 00:17:57.363
mostly because I ran
out of time to test it.

00:17:58.950 --> 00:18:03.950
Now I put together some slides
comparing what I have found.

00:18:04.420 --> 00:18:06.600
Generally, Chrome 80 on Windows 10

00:18:06.600 --> 00:18:10.683
does well with flex, grid,
block, inline-block and contents.

00:18:11.770 --> 00:18:14.360
Tables do just fine.

00:18:14.360 --> 00:18:16.770
Headers, buttons all do fine.

00:18:16.770 --> 00:18:19.500
The caveat is any lists that have

00:18:19.500 --> 00:18:22.200
display: contents set to them fall down

00:18:22.200 --> 00:18:24.050
and they lose all of their semantics.

00:18:25.950 --> 00:18:30.170
Firefox 73 on Windows 10 has problems

00:18:30.170 --> 00:18:33.380
with these display properties on tables.

00:18:33.380 --> 00:18:36.570
So ths with flex and grid
are announced as cells.

00:18:36.570 --> 00:18:39.940
That means they lose their
column or row header status.

00:18:39.940 --> 00:18:43.370
And a table with display:
contents just falls apart.

00:18:43.370 --> 00:18:46.030
Lists seem to fare pretty well

00:18:46.030 --> 00:18:49.310
when it comes to display:
inline-block or display: contents

00:18:49.310 --> 00:18:52.120
and inserts a text leaf
between each list item.

00:18:52.120 --> 00:18:53.120
Bit of a pickle.

00:18:53.120 --> 00:18:56.600
And then buttons, when they
have display: contents,

00:18:56.600 --> 00:18:59.093
Firefox will issue a keyboard use warning.

00:19:00.920 --> 00:19:05.920
Safari on macOS 10.15.2 tables are a mess.

00:19:08.080 --> 00:19:10.247
Display: flex, grid, block,
inline-block, or contents

00:19:10.247 --> 00:19:12.500
the tables fall apart, period.

00:19:12.500 --> 00:19:17.110
Your lists fall apart for
block, inline-block, or contents

00:19:17.110 --> 00:19:21.170
with the exception of dl,
definition list, description list,

00:19:21.170 --> 00:19:23.830
dictionary list or whatever
the kids are using.

00:19:23.830 --> 00:19:27.360
Headers and buttons fall
apart on display: contents.

00:19:27.360 --> 00:19:31.530
So right now Safari on macOS 10.15.2

00:19:31.530 --> 00:19:34.743
has the most trouble with
CSS display properties.

00:19:36.370 --> 00:19:41.300
Chrome 80 on Android
10 matches pretty well

00:19:41.300 --> 00:19:44.850
with the desktop, desktop
version of Chrome 80.

00:19:44.850 --> 00:19:47.220
It does well with flex,
grid, block, inline-block,

00:19:47.220 --> 00:19:51.370
and contents for tables, for
lists, for headers and buttons

00:19:51.370 --> 00:19:55.896
with the exception of
display: contents on lists.

00:19:55.896 --> 00:19:57.713
It will ruin your lists.

00:19:58.870 --> 00:20:03.870
Safari on iOS just as
broken as desktop Safari.

00:20:04.950 --> 00:20:08.060
Worth noting that if
you have display: block,

00:20:08.060 --> 00:20:10.500
inline-block, or contents on a table,

00:20:10.500 --> 00:20:14.040
then it treats all cells
as belonging in column one.

00:20:14.040 --> 00:20:15.380
Kind of annoying.

00:20:15.380 --> 00:20:17.500
And a button with display: contents

00:20:17.500 --> 00:20:20.790
still fires on double tap with VoiceOver.

00:20:20.790 --> 00:20:23.080
So it won't announce it as a button.

00:20:23.080 --> 00:20:25.690
But if you accidentally
double tap your screen

00:20:25.690 --> 00:20:28.380
while doing explore by
touch or using the rotor,

00:20:28.380 --> 00:20:30.653
you can accidentally trigger something.

00:20:32.520 --> 00:20:36.440
Now I mentioned CSS display: table before.

00:20:36.440 --> 00:20:39.820
Display: table, table-caption,
table-row and table-cell

00:20:39.820 --> 00:20:44.480
are all CSS properties that
people have used for years

00:20:44.480 --> 00:20:47.570
to try to replicate something
like vertical centering,

00:20:47.570 --> 00:20:51.133
which wasn't always easy to do with CSS.

00:20:52.330 --> 00:20:55.020
Each of these display properties will add

00:20:55.020 --> 00:20:57.803
layout table semantics
in Chrome version 80.

00:20:59.160 --> 00:21:02.880
There's no CSS display
property to create column

00:21:02.880 --> 00:21:05.550
or row headers, though,
and it still requires

00:21:05.550 --> 00:21:07.150
a well-structured DOM.

00:21:07.150 --> 00:21:09.840
And this is not a
workaround, it's not a fix,

00:21:09.840 --> 00:21:12.930
and it doesn't mean it's
okay to use divs as tables.

00:21:12.930 --> 00:21:15.883
This is a hack and it's
probably not ideal.

00:21:16.800 --> 00:21:19.840
Also Chrome doesn't really call it a table

00:21:19.840 --> 00:21:22.010
in its accessibility inspector.

00:21:22.010 --> 00:21:24.650
It refers to it as a layout table.

00:21:24.650 --> 00:21:26.683
So I'm showing the inspector,

00:21:28.220 --> 00:21:30.080
specifically the accessibility inspector

00:21:30.080 --> 00:21:33.430
pointing at where it should be a table

00:21:33.430 --> 00:21:35.910
with a row and grid cell.

00:21:35.910 --> 00:21:40.640
I have layout table, layout row
table and layout cell table.

00:21:40.640 --> 00:21:41.963
This is problematic.

00:21:43.120 --> 00:21:46.580
JAWS and Narrator will
read this as a table,

00:21:46.580 --> 00:21:50.280
but it will not recognize
any column or row headers,

00:21:50.280 --> 00:21:53.230
because there is no CSS display property

00:21:53.230 --> 00:21:54.530
that corresponds to those.

00:21:55.370 --> 00:22:00.113
NVDA, VoiceOver and TalkBack
will not read this as a table.

00:22:01.870 --> 00:22:05.690
A slightly future curveball
in Chrome version 82,

00:22:05.690 --> 00:22:07.820
it's going to support flex's,

00:22:07.820 --> 00:22:10.313
align-items property on buttons.

00:22:10.313 --> 00:22:12.890
It's not just flex, but also grid.

00:22:12.890 --> 00:22:15.850
So if you're using display: grid, flex,

00:22:15.850 --> 00:22:19.860
inline-grid or inline-flex,
and use align-items,

00:22:19.860 --> 00:22:20.793
this can help.

00:22:22.020 --> 00:22:25.500
Primarily, the lack of
support for align-items

00:22:25.500 --> 00:22:29.170
has hampered uptake of button in layouts

00:22:29.170 --> 00:22:30.910
that are grid or flex-based.

00:22:30.910 --> 00:22:33.930
Because people couldn't get,
or designers couldn't get

00:22:33.930 --> 00:22:36.900
the vertical centering
or vertical positioning

00:22:36.900 --> 00:22:40.660
that they wanted because
it would break everything.

00:22:40.660 --> 00:22:42.490
So you can expect to see more buttons

00:22:42.490 --> 00:22:43.780
with more display properties,

00:22:43.780 --> 00:22:46.630
which means more testing will be required

00:22:46.630 --> 00:22:49.030
to make sure the semantics
are not being dumped.

00:22:51.660 --> 00:22:54.690
Now there is a longer version to tables

00:22:54.690 --> 00:22:56.580
owing to their misuse for layout,

00:22:56.580 --> 00:22:58.600
and people will try other elements

00:22:58.600 --> 00:23:01.460
and then try to throw ARIA at them.

00:23:01.460 --> 00:23:05.470
I'm really not a fan of
using ARIA to fix stuff,

00:23:05.470 --> 00:23:07.260
but what we have is a potential

00:23:07.260 --> 00:23:09.680
stop-gap measure we can use here.

00:23:09.680 --> 00:23:13.160
You can use ARIA to
reinsert lost semantics.

00:23:13.160 --> 00:23:15.670
So if you make table with a role table,

00:23:15.670 --> 00:23:18.130
caption role caption, oh, I should note,

00:23:18.130 --> 00:23:20.033
role caption is coming in ARIA 1.2.

00:23:21.080 --> 00:23:22.453
It does not exist today.

00:23:23.900 --> 00:23:27.000
A thead, tbody, tfoot
would get role rowgroup;

00:23:27.000 --> 00:23:30.870
a tr gets role of row; role cell on td;

00:23:30.870 --> 00:23:33.527
any th with the scope col
would be row columnheader;

00:23:33.527 --> 00:23:36.917
and any th with the scope
row would be role rowheader.

00:23:38.200 --> 00:23:40.370
So you're reinserting semantics.

00:23:40.370 --> 00:23:42.980
This is potentially good.

00:23:42.980 --> 00:23:45.350
This isn't gonna address
re-ordered content.

00:23:45.350 --> 00:23:47.900
So if you re-layout your table

00:23:47.900 --> 00:23:49.650
and move things around dramatically,

00:23:49.650 --> 00:23:52.420
you still gonna have some
reading order issues potentially.

00:23:52.420 --> 00:23:55.293
This also doesn't address any
content that you've hidden.

00:23:56.750 --> 00:24:01.280
Now I wanna caution you that
you should not use grid roles

00:24:02.350 --> 00:24:04.950
and you definitely should
test with a screen reader.

00:24:05.950 --> 00:24:08.570
If your tables are
generated from any scripts,

00:24:08.570 --> 00:24:10.050
you might wanna update the script

00:24:10.050 --> 00:24:13.030
so that it adds these roles
for you automatically.

00:24:13.030 --> 00:24:14.801
Just builds them in.

00:24:14.801 --> 00:24:18.070
Incidentally, on the my site,
I have a JavaScript function

00:24:18.070 --> 00:24:20.563
that will add these roles for you.

00:24:21.690 --> 00:24:24.160
I don't think I included a
link at the end of the slides,

00:24:24.160 --> 00:24:27.803
but you can pester me afterward
and I will point you to it.

00:24:30.160 --> 00:24:34.020
Here is what your table
with all of this extra ARIA

00:24:34.020 --> 00:24:35.110
might look like.

00:24:35.110 --> 00:24:36.940
It's a lot more verbose.

00:24:36.940 --> 00:24:39.400
Definitely those ths with
role of columnheader.

00:24:39.400 --> 00:24:42.240
It certainly got more
code going on in there.

00:24:42.240 --> 00:24:44.970
The advantage, though,
is when I fire this up

00:24:44.970 --> 00:24:47.800
in a screen reader and browser combination

00:24:47.800 --> 00:24:51.170
that is not Chrome 80,

00:24:51.170 --> 00:24:54.570
we'll hear that it's going
to recognize the table.

00:24:54.570 --> 00:24:59.500
So using NVDA, I'm gonna
hit T to get to the table

00:24:59.500 --> 00:25:01.680
and I'll use control, alt and arrow keys

00:25:01.680 --> 00:25:03.500
to navigate the table.

00:25:03.500 --> 00:25:06.510
And if you can see what's going on,

00:25:06.510 --> 00:25:10.330
you'll note that it's navigating
a table as if it's a table,

00:25:10.330 --> 00:25:12.330
but all the content is visually stacked.

00:25:13.600 --> 00:25:14.650
- [NVDA] Books I May or May Not Have Read.

00:25:14.650 --> 00:25:16.200
Region, table, with six
rows and five columns,

00:25:16.200 --> 00:25:18.090
Books I May or May Not Have Read.

00:25:18.090 --> 00:25:20.500
Row one, column one,
Author: Miguel De Cervantes.

00:25:20.500 --> 00:25:22.190
Row two, Author: Mary Shelley.

00:25:22.190 --> 00:25:23.950
Row three, Author: Herman Melville.

00:25:23.950 --> 00:25:26.960
Column two, Title:
"Moby-Dick"; or, "The Whale".

00:25:26.960 --> 00:25:29.700
Column three, Year: 1851.

00:25:29.700 --> 00:25:32.340
Row four, Year: 1888.

00:25:32.340 --> 00:25:34.130
Column two, Title: "The Hidden Hand".

00:25:34.130 --> 00:25:36.020
Row five, Title: "The Great Gatsby".

00:25:36.020 --> 00:25:37.843
Row six, Title: 1984.

00:25:38.970 --> 00:25:41.630
- [Adrian] So the gist there is that

00:25:41.630 --> 00:25:43.580
I am still able to navigate this,

00:25:43.580 --> 00:25:45.860
regardless of how it looks.

00:25:45.860 --> 00:25:49.630
As a screen reader user, for
that set of screen readers,

00:25:49.630 --> 00:25:51.500
screen reader users who genuinely don't care

00:25:51.500 --> 00:25:53.543
what a table looks like, this is good.

00:25:55.800 --> 00:25:57.680
I mentioned ARIA grid.

00:25:57.680 --> 00:26:01.390
Do not use ARIA grid
roles for simple tables.

00:26:01.390 --> 00:26:05.313
ARIA grid is intended to mimic
Excel-style spreadsheets.

00:26:06.350 --> 00:26:08.620
You don't wanna use this for data tables.

00:26:08.620 --> 00:26:11.993
And I'm not covering much
more than this in the talk.

00:26:12.860 --> 00:26:15.350
Also bear in mind that ARIA grid roles

00:26:15.350 --> 00:26:17.130
create a composite widget,

00:26:17.130 --> 00:26:20.590
which means your grid, not CSS grid,

00:26:20.590 --> 00:26:24.620
but your ARIA grid is one
tab-stop in the sequence

00:26:24.620 --> 00:26:27.300
and it contains multiple
interactive controls.

00:26:27.300 --> 00:26:29.300
Every cell is editable.

00:26:29.300 --> 00:26:31.570
That's usually not the
case with the data table.

00:26:31.570 --> 00:26:33.760
And it also means you, as a developer,

00:26:33.760 --> 00:26:36.053
have to manage the
focus within that table.

00:26:38.130 --> 00:26:39.550
Display: contents.

00:26:39.550 --> 00:26:42.540
I am seeing this become
sort of the new hotness,

00:26:42.540 --> 00:26:45.040
or at least I've seen it
become the new hotness.

00:26:45.040 --> 00:26:48.230
It is something I wanna
call out specifically,

00:26:48.230 --> 00:26:51.470
primarily because I see
some developers using it

00:26:51.470 --> 00:26:54.933
as a sort of weird CSS reset.

00:26:56.600 --> 00:26:59.080
The way it's a quasi CSS reset

00:26:59.080 --> 00:27:01.350
is because it takes the element

00:27:01.350 --> 00:27:04.420
and makes it not generate any boxes.

00:27:04.420 --> 00:27:06.530
Its children and pseudo-elements
still generate boxes,

00:27:06.530 --> 00:27:09.550
but otherwise it's just a
string of text on the page.

00:27:09.550 --> 00:27:14.170
It's almost as if the element
has been replaced in the tree

00:27:14.170 --> 00:27:16.530
by its contents, by its, as if its opening

00:27:16.530 --> 00:27:18.640
and closing tags were removed.

00:27:18.640 --> 00:27:21.620
It also yanks things right
out of the accessibility tree,

00:27:21.620 --> 00:27:23.120
completely.

00:27:23.120 --> 00:27:27.610
You can't add it back into the
accessibility tree with ARIA.

00:27:27.610 --> 00:27:30.880
You can give it an accessible
name and all these properties

00:27:30.880 --> 00:27:32.430
and all the roles that you want,

00:27:32.430 --> 00:27:35.130
but the browser doesn't recognize it

00:27:35.130 --> 00:27:38.053
and therefore does not pass
it along to screen readers.

00:27:39.190 --> 00:27:41.230
So be very careful.

00:27:41.230 --> 00:27:43.320
'Cause if you're using display: contents,

00:27:43.320 --> 00:27:46.370
it's going to hide all
the important reasons

00:27:46.370 --> 00:27:49.973
you chose that semantic element
from assistive technology.

00:27:52.720 --> 00:27:56.730
We know Chrome 80 has just
addressed a bunch of issues

00:27:56.730 --> 00:27:59.690
and I covered it in the previous slides,

00:27:59.690 --> 00:28:01.960
so I'm gonna show an
older version of Chrome

00:28:01.960 --> 00:28:05.480
in the following slides,
which is kinda hard to do

00:28:05.480 --> 00:28:08.270
when it's always auto-updating.

00:28:08.270 --> 00:28:11.180
But this will demonstrate
how you can confirm support

00:28:11.180 --> 00:28:14.320
within the browser before
you even have to fire up

00:28:14.320 --> 00:28:16.570
your screen reader to
do some of the testing.

00:28:18.220 --> 00:28:21.710
The image on the left shows the inspector

00:28:21.710 --> 00:28:24.310
and what the table looks like before any

00:28:24.310 --> 00:28:26.900
CSS display properties are in place.

00:28:26.900 --> 00:28:30.310
We can see that the computed properties

00:28:30.310 --> 00:28:34.350
give it a role of table and
it gets its accessible name

00:28:34.350 --> 00:28:35.750
from the caption.

00:28:35.750 --> 00:28:38.660
The image on the right shows how

00:28:38.660 --> 00:28:41.850
once I've added my display properties

00:28:41.850 --> 00:28:43.900
the whole thing falls apart.

00:28:43.900 --> 00:28:45.640
Once I've added display:
contents, I'm sorry.

00:28:45.640 --> 00:28:47.880
Once I've added display: contents

00:28:47.880 --> 00:28:50.117
it has no computed properties at all,

00:28:50.117 --> 00:28:52.810
the accessibility node is not exposed,

00:28:52.810 --> 00:28:56.010
the element is not rendered
in the accessibility tree.

00:28:56.010 --> 00:28:59.070
And you can see under the
ARIA attributes section

00:28:59.070 --> 00:29:02.403
of the accessibility inspector
it still has role of table,

00:29:03.830 --> 00:29:07.130
but it's not computed as a
table so it's not handed off.

00:29:07.130 --> 00:29:10.620
The same is true in on ordered lists.

00:29:10.620 --> 00:29:14.060
On the left, it's computed as a list.

00:29:14.060 --> 00:29:17.430
On the right, the
accessibility is not exposed

00:29:17.430 --> 00:29:20.113
even though I'm forcing a role of list.

00:29:21.340 --> 00:29:22.490
Same thing with button.

00:29:23.460 --> 00:29:27.990
I have ensured that it is
a button by using button

00:29:27.990 --> 00:29:29.750
and its accessible name comes

00:29:29.750 --> 00:29:31.660
from the contents of the button,

00:29:31.660 --> 00:29:35.250
and is listening for user
entry and other handlers.

00:29:35.250 --> 00:29:39.020
I add role button while
it has display: contents,

00:29:39.020 --> 00:29:41.880
no dice, it's still just a piece of text,

00:29:41.880 --> 00:29:44.340
no accessibility information.

00:29:44.340 --> 00:29:49.340
With the h2, even when
I add aria-level 2

00:29:50.840 --> 00:29:52.850
to make it an h2 with a role of heading

00:29:52.850 --> 00:29:54.310
it doesn't get exposed.

00:29:54.310 --> 00:29:55.780
Typically, the computed properties

00:29:55.780 --> 00:29:58.350
would tell me it's a heading at level two,

00:29:58.350 --> 00:30:00.200
but not once I add display: contents.

00:30:02.010 --> 00:30:06.290
Taking the example that I
showed you a few screens ago,

00:30:06.290 --> 00:30:10.040
I have a page which has a table and a list

00:30:10.040 --> 00:30:11.310
and a button and a heading,

00:30:11.310 --> 00:30:14.000
and I've set display:
contents on all of them.

00:30:14.000 --> 00:30:15.850
I'm gonna have a few seconds here

00:30:15.850 --> 00:30:20.673
of trying to navigate
that with NVDA in Firefox.

00:30:21.920 --> 00:30:23.370
- [NVDA] No next table.

00:30:23.370 --> 00:30:24.203
No next list.

00:30:25.120 --> 00:30:25.953
No next button.

00:30:27.200 --> 00:30:28.080
Table with display

00:30:28.080 --> 00:30:29.840
contents heading level two.

00:30:29.840 --> 00:30:30.890
Books I May or May Not Have Read.

00:30:30.890 --> 00:30:32.810
Author, Title, Year, ISBN-13, ISBN-10,

00:30:32.810 --> 00:30:34.780
Miguel De Cervantes, The Ingenious,

00:30:34.780 --> 00:30:36.440
Gentleman Don Quixote of--

00:30:36.440 --> 00:30:40.770
- [Adrian] So I'll stop it
there, because I wanna point out,

00:30:40.770 --> 00:30:43.360
I tried to navigate to
each of those element types

00:30:43.360 --> 00:30:45.120
by hitting the associated key.

00:30:45.120 --> 00:30:47.790
T for table, B for button, for example.

00:30:47.790 --> 00:30:51.600
And NVDA did not recognize them.

00:30:51.600 --> 00:30:54.850
When I start to cursor through
and go right to the table,

00:30:54.850 --> 00:30:58.140
instead of announcing as columns and rows,

00:30:58.140 --> 00:31:00.770
it reads off all the
text from the first row,

00:31:00.770 --> 00:31:04.750
which are my columns, and then
text into the first two cells

00:31:04.750 --> 00:31:06.030
of the first row.

00:31:06.030 --> 00:31:08.040
That's a bit of a problem.

00:31:08.040 --> 00:31:10.340
Now bugs have been filed.

00:31:10.340 --> 00:31:14.520
Firefox, Chromium, Safari,
and the CSS Working Group

00:31:14.520 --> 00:31:16.830
all have open bugs on this.

00:31:16.830 --> 00:31:19.580
Even the fixes in Chrome version 80

00:31:19.580 --> 00:31:22.530
do not close that Chromium issue.

00:31:22.530 --> 00:31:25.830
It's still an open bug,
specifically elements

00:31:25.830 --> 00:31:27.630
not exposed to accessibility tree

00:31:27.630 --> 00:31:29.750
when it is set to display: contents.

00:31:29.750 --> 00:31:31.550
So the bugs are out there,

00:31:31.550 --> 00:31:34.980
browser makers just need
to do something about this.

00:31:34.980 --> 00:31:38.860
So you might ask yourself,
"Where is my beautiful table,"

00:31:38.860 --> 00:31:41.590
you may ask yourself, "Where
are the table semantics,"

00:31:41.590 --> 00:31:45.200
and you may ask yourself,
"Why is this so broken?"

00:31:45.200 --> 00:31:46.600
Really, how is this a thing?

00:31:47.510 --> 00:31:50.060
Assistive technology is not at fault here.

00:31:50.060 --> 00:31:51.660
So it's not the screen reader's fault.

00:31:51.660 --> 00:31:54.310
The accessibility information
comes from the browser.

00:31:55.800 --> 00:31:58.740
Because developers used layout
tables for so many years,

00:31:58.740 --> 00:32:01.320
screen readers have had to improvise.

00:32:01.320 --> 00:32:03.690
They need more than the
DOM to understand the page.

00:32:03.690 --> 00:32:07.670
So they have developed
heuristics for reading tables,

00:32:07.670 --> 00:32:10.783
for understanding if it's a
layout table or a data table.

00:32:12.430 --> 00:32:15.400
It can't really tell when
the browser isn't handing

00:32:15.400 --> 00:32:16.913
any information at all.

00:32:18.650 --> 00:32:21.740
Remember, I'm still
using tables as my proxy,

00:32:21.740 --> 00:32:23.240
as my canary in the coal mine.

00:32:25.550 --> 00:32:27.920
You can't rely on detecting
assistive technology

00:32:27.920 --> 00:32:30.523
to try and turn off
your display properties.

00:32:31.920 --> 00:32:34.610
First of all, users don't
want to be discovered

00:32:34.610 --> 00:32:35.700
as using screen readers.

00:32:35.700 --> 00:32:37.950
That's a general problem.

00:32:37.950 --> 00:32:39.310
There are some who are fine with it

00:32:39.310 --> 00:32:42.400
if they can get a genuinely
more accessible experience,

00:32:42.400 --> 00:32:45.720
but evidence suggests that
doesn't really pan out.

00:32:45.720 --> 00:32:48.290
Mouse user or mouse
actions are a poor proxy

00:32:48.290 --> 00:32:50.340
to identify sighted screen reader users.

00:32:50.340 --> 00:32:53.220
It also doesn't map
well to people who have

00:32:53.220 --> 00:32:55.740
mobility impairments or are using

00:32:55.740 --> 00:32:58.003
mobile screen reader with touch gestures.

00:32:59.140 --> 00:33:03.140
Disabling a site's CSS for
screen readers is impractical.

00:33:03.140 --> 00:33:04.183
Do not do it.

00:33:05.490 --> 00:33:07.743
CSS itself is not blameless.

00:33:09.020 --> 00:33:11.130
CSS already impacts HTML semantics,

00:33:11.130 --> 00:33:13.150
so this isn't a new thing really.

00:33:13.150 --> 00:33:15.920
Display: none does that today.

00:33:15.920 --> 00:33:17.510
Using display: table on its own

00:33:17.510 --> 00:33:20.430
does not impart HTML table semantics.

00:33:20.430 --> 00:33:23.130
It does give some layout
table semantics in Chrome,

00:33:23.130 --> 00:33:24.330
but that's not the same.

00:33:25.890 --> 00:33:29.240
CSS flex or grid makes
it easy for content order

00:33:29.240 --> 00:33:30.870
and source order to disagree.

00:33:30.870 --> 00:33:33.160
And it's not just flex and grid.

00:33:33.160 --> 00:33:36.890
But ever since we've had
absolute positioning and floats,

00:33:36.890 --> 00:33:38.453
we've had this problem.

00:33:40.970 --> 00:33:43.270
Think about how we've used CSS

00:33:43.270 --> 00:33:45.090
to vertically center stuff.

00:33:45.090 --> 00:33:46.360
I mentioned that for a while.

00:33:46.360 --> 00:33:49.907
That's part of how we
got into where we are,

00:33:49.907 --> 00:33:54.130
assigning table-cell
display properties to divs

00:33:54.130 --> 00:33:56.080
just so we could do vertical centering.

00:33:57.150 --> 00:34:01.210
And, remember, if you use
CSS display: grid properties

00:34:01.210 --> 00:34:03.890
to layout an HTML table, it still won't

00:34:03.890 --> 00:34:05.223
semantically be a table.

00:34:07.010 --> 00:34:10.390
First rule of ARIA, don't use ARIA.

00:34:10.390 --> 00:34:11.640
Not if you don't have to.

00:34:13.610 --> 00:34:15.670
But, yeah, if you are gonna use ARIA,

00:34:15.670 --> 00:34:19.110
because this is the only
way to fix it right now,

00:34:19.110 --> 00:34:22.540
you must understand ARIA,
the ARIA that you're using

00:34:22.540 --> 00:34:26.000
and the table structure
that you're rebuilding.

00:34:26.000 --> 00:34:28.150
So it's also gonna require
you to keep current

00:34:28.150 --> 00:34:32.100
on screen reader and browser
support, 'cause things change.

00:34:32.100 --> 00:34:35.280
Things change rapidly
now that we have browsers

00:34:35.280 --> 00:34:39.450
in development cycles that are six weeks,

00:34:39.450 --> 00:34:40.773
potentially four weeks.

00:34:41.820 --> 00:34:44.620
You'll also have to manage
content that you hide

00:34:44.620 --> 00:34:47.570
when you reflow the tables
such as the column headers.

00:34:47.570 --> 00:34:49.180
And you'll have to consider what happens

00:34:49.180 --> 00:34:52.263
when your CSS does not
load for whatever reason.

00:34:53.130 --> 00:34:55.020
So this is not the purpose of ARIA.

00:34:55.020 --> 00:34:57.683
Everything I've shown
here is just a stop-gap.

00:34:59.020 --> 00:35:02.760
I also want to point out
the browser is not right.

00:35:02.760 --> 00:35:05.380
The CSS spec does not state that semantics

00:35:05.380 --> 00:35:06.710
should be dropped.

00:35:06.710 --> 00:35:08.990
This is a weird decision
that browsers made

00:35:08.990 --> 00:35:10.990
that doesn't seem to come from anywhere.

00:35:12.530 --> 00:35:14.280
There's no reason to remove the semantics

00:35:14.280 --> 00:35:16.360
just because of display properties.

00:35:16.360 --> 00:35:20.810
The accessibility tree should
not care about most visuals.

00:35:20.810 --> 00:35:23.840
Again display: none is a
great example where it should.

00:35:23.840 --> 00:35:26.680
But, otherwise, it shouldn't
break the semantics

00:35:26.680 --> 00:35:29.630
for something that's just
changing its layout a little bit.

00:35:31.730 --> 00:35:36.730
To wrap this up, I have a slide
with a bunch of references.

00:35:36.970 --> 00:35:38.390
I've written a few things about it.

00:35:38.390 --> 00:35:41.500
The first, let's see, one,
two, three, four, five.

00:35:41.500 --> 00:35:44.230
Well, everything in the left
column is stuff I've written

00:35:44.230 --> 00:35:47.590
with the exception of the
GitHub Contributions Chart.

00:35:47.590 --> 00:35:49.550
That's the example that
I showed partway through

00:35:49.550 --> 00:35:53.280
where I put the, they try to
make the table itself scroll

00:35:53.280 --> 00:35:55.260
instead of putting it in a container.

00:35:55.260 --> 00:35:57.850
Steve Faulkner has talked
about display properties

00:35:57.850 --> 00:35:59.360
and table semantics.

00:35:59.360 --> 00:36:00.920
Heydon Pickering has some information

00:36:00.920 --> 00:36:02.893
in his "Data Tables" article.

00:36:04.750 --> 00:36:07.440
Ire Aderinokun talks about it

00:36:07.440 --> 00:36:09.610
in "How display: contents; Works",

00:36:09.610 --> 00:36:12.980
specifically some of the benefits
of using display: contents

00:36:12.980 --> 00:36:15.940
and balancing a little bit
against some of these challenges.

00:36:15.940 --> 00:36:18.770
And if you're curious, CSS3, Appendix B

00:36:18.770 --> 00:36:20.900
talks about the Effects
of display: contents

00:36:20.900 --> 00:36:23.000
on Unusual Elements.

00:36:23.000 --> 00:36:25.470
These are all handy resources to

00:36:25.470 --> 00:36:27.640
maybe try to understand where we are,

00:36:27.640 --> 00:36:29.773
or to file bugs on your own.

00:36:32.730 --> 00:36:35.170
Again thank you for attending the talk

00:36:35.170 --> 00:36:38.193
CSS Display Properties
versus HTML Semantics.

00:36:39.100 --> 00:36:40.730
I'm not standing right in front of you

00:36:40.730 --> 00:36:43.053
so you can ping me with questions.

00:36:43.920 --> 00:36:45.830
Find me on Twitter is
probably the easiest way

00:36:45.830 --> 00:36:49.040
after this is all over and
I'm happy to help you out.

00:36:49.040 --> 00:36:54.040
Again I am on Twitter
@aardrian, A-A-R-D-R-I-A-N.

00:36:55.320 --> 00:36:56.343
Thank you again.
