WebAIM - Web Accessibility In Mind

E-mail List Archives

Re: Table Structure Policy question

for

From: Jared Smith
Date: Dec 10, 2010 4:03PM


On Fri, Dec 10, 2010 at 1:58 PM, Duff Johnson < <EMAIL REMOVED> > wrote:

> a) no spanning cells, and
> b) only 1 logical level of both row headings and column headings, and
> c) only 1 actual row of column headers.

If I understand this correctly, it might be easier to state b) as "No
cell has more than one column header and no more than one row header".

> 1) For simple tables, the use of "scope" is perfectly acceptable.

Why not "the use of scope is required"? "Perfectly acceptable" means
"perfectly optional" to developers.

> 2) For complex tables, the use of "scope" is not acceptable. The id/headers method must be used.

Scope is valid for complex tables with multiple levels of column
and/or row headers. It's also acceptable for spanned column/row
headers. However, you can see how it would be confusing for a screen
reader user to determine the structure of a table if more than 2
headers are being read - there's currently no way to know which are
the row headers and which are the column headers. This could be
resolved if screen readers identified whether each was a row or column
header in instances where more than one of either existed for a cell.

However, no modern screen reader (that I know of) has implemented
proper support for instances where a cell might have more than one
column or more than one row header even if scope is properly
implemented. They will either ignore the extra headers, ignore some or
all of the headers, or read the WRONG headers.

NVDA doesn't support scope at all (at least for me in 2010.2, though
it's supposed to). Window-Eyes supports scope partially and some of
the time. JAWS supports one level of scope (at most one row and one
column header). VoiceOver supports one level of scope="col", but reads
the headers incorrectly if there are any empty cells in the header row
(http://www.accessibleculture.org/research/voiceover-and-tables-with-an-empty-first-header-cell/)
and doesn't yet support row headers.

In short, support for scope is pretty poor. And if support for scope
is poor, then screen reader support for id/headers is abysmal. No
screen reader properly supports it yet. JAWS comes closest, but it
only reads at most two headings (and the two it reads seem quite
random).

Fortunately, the use of id/headers would only be necessary in a table
in cases where a header's scope would apply to a cell that doesn't
actually belong to that header. This is quite rare and can usually be
alleviated by simply splitting the table into multiple tables, which
will be usually be better for everyone anyway.

> 3) Colspan and rowspan attributes are considered to have no role in providing logical structure (since spanning cells trigger a requirement for IDs/headers under this policy).

I don't understand this statement. Again, the presence of spanned
cells doesn't automatically make using scope an insufficient
technique. As noted above, it's the best technique except in rare and
very complex cases.

> 4) In complex tables, the use of "TH" in row heading cells is said to be OPTIONAL (due to the use of the id/headers method).

Identifying the actual headers with <th> would be much more vital to
accessibility than associating the data cells to them with the headers
attribute or scope. Because there's no way to differentiate a data
table from a layout table, screen readers often look for the presence
of <th>s to tell what type it is. If there are no headers, the screen
reader is likely to treat it as a layout table, thus id/headers
(assuming they were actually supported), wouldn't be recognized. <th>
is vital for all table headers.

> I recognize this policy as related to the advice given here:
>
> http://webaim.org/techniques/tables/data#headers

We probably should update this page to reflect the actuality of table
accessibility, not the way it's supposed to be. Do note that the
simple id/headers example on that page could be made accessible using
only scope - that is if screen readers supported it correctly. No
screen reader I tested currently handles even this simple example
correctly when using either scope or headers/id.

So, you can require headers/id that is overly complex and doesn't ever
work, or you can require scope, which is simple and might sometimes
work. As such, I'd recommend dropping any requirement for id/headers.
I'd maybe go with something like this:
- Identify all table headers with <th>.
- Do not use <th> for anything other than a non-empty table header.
- Where possible, simplify or 'flatten' tables so that no data cell
has more than one column header and no more than one row header.
- Provide the appropriate scope attribute value (row or col) to each <th>.
- When any cell within the scope of a row or column header does not
belong to that header (e.g., very complex tables with spanned cells or
headers), separate into multiple tables to ensure accessibility.

Jared