maxshuty
maxshuty

Reputation: 10662

Making a vertical table accessible

I have some very basic data, like this:

{
  "name": "John Doe",
  "city": "Minneapolis",
  "state": "Minnesota",
  "country": "United States",
  "age": "42"
}

I need to display it like this:

| name    | John Doe      |
| city    | Minneapolis   |
| state   | Minnesota     |
| country | United States |
| age     | 42            |

As you can see the table above has the headers left justified and the row values are all aligned.

According to W3, the way to do a vertical table is like the snippet below, but they also call out:

Note: Some screen readers will read “Date – Event – Venue” in the “Venue” cell because the direction of the <th> elements is ambiguous.

table th {
 text-align: left;
}
<table>
  <tr>
    <th>Name</th>
    <td>John Doe</td>
  </tr>
  <tr>
    <th>City</th>
    <td>Minneapolis</td>
  </tr>
  <tr>
    <th>State</th>
    <td>Minnesota</td>
  </tr>
  <tr>
    <th>Country</th>
    <td>United States</td>
  </tr>
  <tr>
    <th>Age</th>
    <td>42</td>
  </tr>
</table>

My question is how accessible is a vertical table like this, and would I be better off using a <ul> with some flexbox or grid magic to get my styling requirements and setting the data as a list? Is there an alternative I'm not considering?

Upvotes: 3

Views: 656

Answers (2)

Sean
Sean

Reputation: 8032

Since there's not multiple people and you're listing key/value pairs, a description list element would be more appropriate than a table element.

The <dl> HTML element represents a description list. The element encloses a list of groups of terms (specified using the <dt> element) and descriptions (provided by <dd> elements). Common uses for this element are...to display metadata (a list of key-value pairs).

dl {
  display: grid;
  grid-template: auto / auto auto;
  justify-content: start;
  column-gap: 1ch;
}
dd {
  margin: 0;
}
<dl>
  <dt>name</dt>
  <dd>John Doe</dd>
  <dt>city</dt>
  <dd>Minneapolis</dd>
  <dt>state</dt>
  <dd>Minnesota</dd>
  <dt>country</dt>
  <dd>United States</dd>
  <dt>age</dt>
  <dd>42</dd>
</dl>

Upvotes: 1

slugolicious
slugolicious

Reputation: 17475

Tables are absolutely accessible to screen readers when coded properly. The only thing missing in your example (and the W3 example) is the scope of the <th>. You should always specify the scope attribute so that it specifically says if the table header is for a row or a column. Don't rely on the browser or the screen reader to "guess" at the meaning when you leave scope out.

There is nothing ambiguous about the direction of the header when scope is specified.

<table>
  <tr>
    <th scope="row">Name</th>
    <td>John Doe</td>
  </tr>
  <tr>
    <th scope="row">City</th>
    <td>Minneapolis</td>
  </tr>
  <tr>
    <th scope="row">State</th>
    <td>Minnesota</td>
  </tr>
  <tr>
    <th scope="row">Country</th>
    <td>United States</td>
  </tr>
  <tr>
    <th scope="row">Age</th>
    <td>42</td>
  </tr>
</table>

Now when a screen reader user navigates to a data cell, for example "Minneapolis", and then they navigate to the next cell down using a table navigation key (such as ctrl+alt+downarrow), they will hear the row label announced first and then the data cell value, such as "State, Minnesota".

Upvotes: 6

Related Questions