HTML5 and Accessible Data Tables - Pro HTML5 Accessibility: Building an Inclusive Web (2012)

Pro HTML5 Accessibility: Building an Inclusive Web (2012)

C H A P T E R 7

HTML5 and Accessible Data Tables

In this chapter, you'll learn all you need to know about creating both simple and more complex accessible data tables using HTML5.

Data tables are commonly used as ways of visually presenting tabular data. This data can be about anything of interest to the author. The table layout allows authors to present information so that web site users can easily associate data in any given cell with various categories or relationships, which are usually defined at the start of every column or row.

This is usually done in a layout that is common to many of us, the individual data cells are related to different columns and rows. The user of the web site can look at the individual data cells and quickly scan to see what columns and rows they relate to. They can then quickly grasp what the data in each cell means.

The Trouble with Tables

For a sighted person, figuring out these relationships is straightforward and often happens very quickly. If a table is well designed and therefore makes understanding these relationships easier in the first place, most sighted users have no problems figuring them out. They start with focusing on what the table data is-in other words, what topic it relates to—and then determining what the information contained within the table actually means.

For a nonsighted person to finish both of these steps successfully takes more work on the part of the developer. There are several reasons for this, but primarily it's because when a table is shown in a browser, a sighted user often just quickly gets these relationships. A nonsighted user will be accessing the data in a table in a very different way—in a linear fashion, one item after another.

Before a nonsighted person even starts to investigate or interrogate (I love using this term as it relates to data tables and accessibility) the data table, she first needs a way to easily understand what the purpose of the table is. This boils down to the user asking, “What is this table for?”, quickly followed by “What does it mean?”

Screen Readers and Data Tables

Creating a table that a sighted person can easily understand is rather easy (as long as the initial data you are trying to represent is straightforward). You create some headings for each column, perhaps add boldface styling to them, and then add rows, and perhaps add boldface styling to the first item in each row. Pretty simple. If this was a paper document, that would be fine.

However, to make a data table accessible in HTML5 you must think of a way to define the relationships between the data cells and their corresponding columns and rows programmatically. Doing so helps user agents like assistive technologies (AT) understand the relationships between the data cells and their corresponding columns and rows, and therefore it enable AT to inform the nonsighted user in a way the user can understand.

For users of screen readers, the HTML5 language has ways of defining these relationships and therefore making data tables easy first to understand second to navigate, and then, if the table isn't relevant to the user's needs, to bypass.

Image Note A screen reader is a linear output device. This means it outputs information to the user one piece at a time. For a nonsighted user to have a gestalt view of HTML content, you need to use appropriate code to help that person. This is often done by writing text overviews of the content and programmatically associating it with the table so that it will be announced when a table has focus. I'll say more on how to do this later in the chapter.

Common Patterns for Data Tables

Most data tables you are likely to author will be simple and follow a well-worn path in terms of their form. I can hear you cry in outrage, “Are you suggesting I won't be creating complex, multicolumn irregular data tables?” Yes, I am. The tables you create might have more or less columns or rows, but they will be mostly a basic grid with headers at the top of your columns and corresponding rows.

They might take the form shown in Table 7-1.

Image

The table might be square or rectangular, and although it will not always be the case, by and large your tables will take the form shown in Table 7-1. So the techniques we'll look at to make the table accessible will apply equally to the simple table just shown and to one with a large number of columns and rows. In this case, size doesn't matter.

You need to be able to do two things. First, for sighted visual users, you need to create the table so that they can look at the information at the top of the table (the header info) and then, more often than not, at the first column in each row. Then they can look across the table to make the necessary associations for each data cell. By doing this, they can see what the data in each cell relates to.

Second, for the tables to be accessible to a screen-reader user, you need to use HTML5 to associate the data in each cell with its corresponding column header and row so that the screen reader itself can announce to the user which header relates to each data cell.

Using HTML5 to mark up your data cells correctly accomplishes two practical functions. First, it informs the screen-reader user of the column and row combination each cell relates to when it has focus; second, it allows the user to understand where he is within the table as he navigates through it.

Screen-reader users can navigate between data cells easily using cursor keys. What I show you in the remainder of this chapter will help you make your tables really accessible in simple steps.

TMI?

Before we look at how to approach making your data tables accessible, I suggest that you do the following:

1. Try to make the data table as simple as possible in the first place. If the table is complex and busy, the code will be too. Although it is possible to create complex tables that are accessible, it will help if you can simplify the architecture of the table in the first place.

2. Try not to span multiple cells/rows. Again, a more simple, well-presented table is often much easier to make accessible.

3. Finally, consider the following question: Can the information you are trying to present be included in the body text of your site? In other words, do you really need a table at all?

How to Create Accessible Tables

Figure 7-1, which you'll see later in the chapter, shows a table that expands on the “animal sanctuary” theme presented in some of the other examples in this book. The table outlines the upcoming workshops that are taking place in our animal sanctuary.

Ok, first things first. As mentioned earlier, a sighted person can look at the table and tell what it is pretty much from the get-go. How can you do this for a nonsighted person? The answer is, by adding a <caption> element.

The <caption> element is a way of giving both the sighted user and the screen-reader user a way of understanding the purpose of the table. The HTML5 specification describes the <caption> element as providing a title for the table. This isn't a bad way of thinking of it. Adding the<caption> element is easy, and whatever text string you add to the <caption> element is programmatically associated with the table. As soon as the table receives focus from a screen, it will be announced to the user without any more interaction required. This is very useful and is the first important step in making your data table accessible. It's also good for sighted users as it is presented visually and can be styled using CSS.

Adding the <caption> element to a data table takes the following form:

<section>
<h1>Animal Sanctuary workshops</h1>
<table>
<caption>An overview of upcoming animal sanctuary workshops in 2012</caption>

[…]
</table>

Using the <caption> element or title for the table is useful for helping the screen reader understand what a table is. Adding <caption> in this way really comes into its own if you consider a webpage with five or six (or even more) data tables on it. A sighted person can quickly scan the page and figure out what all of these tables are. As mentioned previously, screen-reader users can use their AT to navigate a webpage by selecting various HTML elements-such as headings, and links. They can do the same thing using any <table> elements that are present on a page. For example, pressing the T key in JAWS causes the AT to bounce the user from the first table to the last one (and back again). If there is no suitable <caption> on each table, the screen reader just announces “Table,” “Table,” and lets the user know how many rows, columns, and so on the table has, but it won't be able to tell the user what the table is for. Adding <caption> fills in the gaps. A data table with a suitable <caption> announces the contents on focus. So if all tables on my suggested page with six tables have <caption> elements, the screen-reader user can easily find what she is looking for—because when each table is given focus, the contents of the <caption> element are announced. Neat!

Image Tip When a table is more complex, you can add a summary attribute (@summary) to the table element. This attribute is designed to provide an overview for a screen-reader user of more complex data tables, but it's now obsolete in HTML5, unfortunately. I still think @summary is very useful because it is announced to the screen-reader user as soon as he focuses on a table. I often use @summary in my projects to provide supplementary information if I think it can help the user understand the table or, in general, have a better user experience. This is slightly out of scope for what it is designed to do, but it works well in my experience. For many simple data tables, @summary isn't really required because a useful <caption> is enough. @summary is hidden from sighted users, but it will be picked up by the screen reader.

I think @summary should be retained and used, but the HTML5 working group made the decision to make it obsolete. Along with other friends and colleagues in the accessibility community, I repeatedly made the case to retain it—but to no avail. If you want to know the grizzly details, you can have a look at the logs in the working group's “Issue Tracker” at www.w3.org/html/wg/tracker/issues/32 or visit the W3C ESW wiki at www.w3.org/html/wg/wiki/SummaryForTABLE.

Doing these things covers informing the screen-reader user of what a table is about. What about navigating the table itself and understanding what data cell relates to what column and row?

Creating Programmatic Associations Between Data Cells, Table Headers, and Rows

There are a couple of common ways of marking up HTML5 tables to make them accessible and also more backward-compatible with older AT (for which there are many users!). The first method involves the use of header/ID combinations to identify the contents of each table cell. The second method uses header/scope combinations.

Accessible Tables Method 1: Use of Header/ID Combinations

The first method that we'll look at is a little more time consuming, but I consider it more bulletproof. We're going to create associations between the header and ID elements of the table's HTML. This is a way of associating the contents of a data cell with its appropriate header. Doing so causes the screen reader to announce what column the data cell is in before the contents of the cell are announced to the user.

To create header/ID associations, you first deal with the headers and then with the table body.

Start by giving each header a unique ID; it is perfectly fine to give a header the same ID as the contents. For my table about upcoming workshops in my animal sanctuary, my header IDs are as follows:

· Header #1 = “Course”

· Header #2 = “Start”

· Header #3 = “End”

· Header #4 = “Cost”

· Header #5 = “Extras”

In HTML code, the headings look like this:

<th id="Course">Course</th>
<th id="Start">Start Date</th>
<th id="End">End Date</th>
<th id="Cost">Cost</th>

<th id="Extras">Included Extras</th>It can just as easily be the following or something similar to the following:

<th id="header1">Course</th>
<th id="header2">Start Date</th>
<th id="header3">End Date</th>
<th id="header4">Cost</th>
<th id="header5">Included Extras</th>

If you have any naming convention you are happy with, you can certainly use it. The point is that the header IDs are unique because they are used to create a programmatic association with your table data (as you shall see). It seems more natural to me that for them to be related, but it doesn't really matter. Now that you have suitable header IDs, you can go ahead and map the cell contents of each row in the table body to an appropriate header, as shown in Listing 7-1.

Listing 7-1. Mapping the Cell Contents

<th id="Course">Course</th>
<th id="Start">Start Date</th>
<th id="End">End Date</th>
<th id="Cost">Cost</th>
<th id="Extras">Included Extras</th>
<tr>
<td headers="Course">How do you start an Animal Sanctuary</td>
<td headers="Start">June 10</td>
<td headers="End">June 16</td>
<td headers="Cost">650 Euros</td>
<td headers="Extras">includes lunches, one dinner and extensive materials.</td>
</tr>
<tr>
<td headers="Course">Working with Dogs: A beginners workshop</td>
<td headers="Start">April 12</td>
<td headers="End">April 16</td>
<td headers="Cost">300 Euros</td>
<td headers="Extras">includes lunches, and materials.</td>
</tr>

[…]

Final Accessible Table Using Header/ID Combinations

By looking at the example in Listing 7-1 to get started, can you see how the associations between headers and the contents of the data cells are made?

Figure 7-1 is a screen shot of the final table.

Image

Figure 7-1. Accessible data table example

Listing 7-2 shows the final fully coded sample (with a suitable <caption> element also).

Listing 7-2. Final Table Code for Accessible Tables Method 1

<section>
<h1>Animal Sanctuary workshops</h1>
<table>
<caption>An overview of upcoming Animal Sanctuary workshops in 2012</caption>
<th id="Course">Course</th>
<th id="Start">Start Date</th>
<th id="End">End Date</th>
<th id="Cost">Cost</th>
<th id="Extras">Included Extras</th>
<tr>
<td headers="Course">How do you start an Animal Sanctuary</td>
<td headers="Start">June 10</td>
<td headers="End">June 16</td>
<td headers="Cost">650 Euros</td>
<td headers="Extras">includes lunches, one dinner and extensive materials.</td>
</tr>
<tr>
<td headers="Course">Working with Dogs: A beginners workshop</td>
<td headers="Start">April 12</td>
<td headers="End">April 16</td>
<td headers="Cost">300 Euros</td>
<td headers="Extras">includes lunches, and materials.</td>
</tr>
<tr>
<td headers="Course">Massage for You & Your Animals</td>
<td headers="Start">September 29</td>
<td headers="End">October 4</td>
<td headers="Cost">400 Euros. A Half day session is 220 Euros.</td>
<td headers="Extras">includes lunch, and book.</td>
</tr>
<tr>
<td headers="Course">Yoga with Animals</td>
<td headers="Start">May 18</td>
<td headers="End">May 21</td>
<td headers="Cost">300 Euros</td>
<td headers="Extras">includes lunch, dinner and book.</td>
</tr>
<tr>
<td headers="Course">A Creative Artistic workshop and Retreat</td>
<td headers="Start">June 18</td>
<td headers="End">June 23</td>
<td headers="Cost">500 Euros</td>
<td headers="Extras">includes lunch, dinner and art supplies.</td>
</tr>
<tr>
<td headers="Course">Why Compassion for Animals matter: Philosophy and Animals</td>
<td headers="Start">July 12</td>
<td headers="End">July 14</td>
<td headers="Cost">200 Euros</td>
<td headers="Extras">includes lunch, and materials</td>
</tr>
<tr>
<td headers="Course">Sanctuary Basics</td>
<td headers="Start">September 22</td>
<td headers="End">September 24</td>
<td headers="Cost">275 Euros.</td>
<td headers="Extras">includes lunch, and class materials</td>
</tr>
</table>
</section>

Accessible Tables Method 2: Use of Header/Scope Combinations

Another method of marking up the same table is to use the table headers in conjunction with the scope attribute (@scope). The HTML5 specification says this about building data tables using header/scope combinations:

· The headers in the first row all apply directly down to the rows in their column.

· The headers with the explicit scope attributes apply to all the cells in their row group.

· The remaining headers apply just to the cells to the right of them.

This means that you can have irregular tables that would still be considered simple, but they might have headers that should not be included in a particular row, or they might have a row that covers several columns.

The specification gives the example shown in Listing 7-3. Note that, in this case, the headers with the explicit scope attributes apply to all the cells in their row group other than the cells in the first column. See also the new HTML5 syntax of using no closing elements for the <th>, <td>, or<tr> elements or, indeed, no quotes for any of the cell values. You can still code in the older way if you prefer. You can also see the new <thead> (table header) and <tbody> (table body) elements that pretty much do what their names indicate, allowing you to denote blocks of content in your tables. There is also a <tfoot> (table footer) element, which is not shown here.

Listing 7-3. Using the Scope Attribute

<table>
<thead>
<tr> <th> ID <th> Measurement <th> Average <th> Maximum
<tbody>
<tr> <td> <th scope=rowgroup> Cats <td> <td>
<tr> <td> 93 <th scope=row> Legs <td> 3.5 <td> 4
<tr> <td> 10 <th scope=row> Tails <td> 1 <td> 1
<tbody>
<tr> <td> <th scope=rowgroup> English speakers <td> <td>
<tr> <td> 32 <th scope=row> Legs <td> 2.67 <td> 4
<tr> <td> 35 <th scope=row> Tails <td> 0.33 <td> 1
</table>

The code in Listing 7-3 produces the table in Figure 7-2, which is slightly more complex.

Image

Figure 7-2. HTML5 specification data table example

The th element can have a scope content attribute specified. The scope attribute has the following five states (with particular keywords):

· The row keyword, which maps to the row state. The row state means the header cell applies to some of the subsequent cells in the same row(s).

· The col keyword, which maps to the column state. The column state means the header cell applies to some of the subsequent cells in the same column(s).

· The rowgroup keyword, which maps to the row group state. The row group state means the header cell applies to all the remaining cells in the row group.

· The colgroup keyword, which maps to the column group state. The column group state means the header cell applies to all the remaining cells in the column group.

· The auto state. The auto state makes the header cell apply to a set of cells selected based on context.

Figure 7-3 is from the HTML5 specification. It visually demonstrates how the algorithm works.

Image

Figure 7-3. Visualization of HTML5 scope algorithm1

The four arrows that point straight down from the top represent the table headers—“ID,” “Measurement,” and so on—and show that they are associated with all of the contents of their corresponding rows. The presence of a table header (<th>) and this association with all of the data cells in their related rows is very well supported by most browsers and AT, even older AT. This basis programmatic association goes a long way toward making your tables accessible. How it works for a screen-reader user is as follows: when that user encounters a table with appropriate headers, she uses her cursor keys to navigate around the data cells, the AT first announces what the table header is, and then it announces the contents of the data cell.

The other arrows show how the @scope element, as applied in the preceding example, relates to the remaining cell in its row, as well as how the cells apply to the cell to their right.

An Example Using Header/Scope Combinations

If you applied the header/scope method to our table, the markup would resemble that shown in Listing 7-4.

__________

1 www.w3.org/TR/html5/tabular-data.html#attr-th-scope

Image Note In HTML5, the scope attribute on the td element is obsolete. You used to be able to add it to a <td> cell in HTML 4, but you cannot do so any more if you want valid HTML. (I'll talk about validation in Chapter 10, “Tools, Tips, and Tricks: Assessing Your Accessible HTML5 Project.”) For HTML5 data tables, use the scope attribute on a th element instead.

Listing 7-4. Using the Header/Scope Method

<section>
<h1>Animal Sanctuary workshops</h1>
<table>
<caption>An overview of upcoming Animal Sanctuary workshops in 2012</caption>
<th scope="col">Course</th>
<th scope="col">Start Date</th>
<th scope="col">End Date</th>
<th scope="col">Cost</th>
<th scope="col">Included Extras</th>
<tr>
<th scope="row">How do you start an Animal Sanctuary</th>
<td>June 10</td>
<td>June 16</td>
<td>650 Euros</td>
<td>includes lunches, one dinner and extensive materials.</td>
</tr>
<tr>
<th scope="row">Working with Dogs: A beginners workshop</th>
<td>April 12</td>
<td>April 16</td>
<td>300 Euros</td>
<td>includes lunches, and materials.</td>
</tr>
<tr>
<th scope="row">Massage for You & Your Animals</th>
<td>September 29</td>
<td>October 4</td>
<td>400 Euros. A Half day session is 220 Euros.</td>
<td>includes lunch, and book.</td>
</tr>
<tr>
<th scope="row">Yoga with Animals</th>
<td>May 18</td>
<td>May 21</td>
<td>300 Euros.</td>
<td>includes lunch, dinner and book.</td>
</tr>
<tr>
<th scope="row">A Creative Artistic workshop and Retreat</th>
<td>June 18</td>
<td>June 23</td>
<td>500 Euros</td>
<td>includes lunch, dinner and art supplies.</td>
</tr>
<tr>
<th scope="row">Why Compassion for Animals matter: Philosophy and Animals</th>
<td>July 12</td>
<td>July 14</td>
<td>200 Euros.</td>
<td>includes lunch, and materials</td>
</tr>
<tr>
<th scope="row">Sanctuary Basics</th>
<td>September 22</td>
<td>September 24</td>
<td>275 Euros.</td>
<th>includes lunch, and class materials</td>
</tr>
</table>
</section>

“So which is best?” I hear you cry. The second method using headers/@scope is a little less time consuming and easier to author, as you can see from Listing 7-4. The net result for users of screen readers is pretty much the same with both examples, with one exception. The @scope attribute is not very well supported by older screen readers, so for my money the header/ID combination method is more robust and better for backward compatibility.

More Complex Tables

Here is an example of a more advanced version of the preceding table, coded using the headers/@scope method as well as the newer HTML5 syntax. The idea is to display information for both introductory and advanced classes with the name of each course coded to act like a heading and spanning several columns.

Visually, the table looks like the one shown in Figure 7-4.

Image

Figure 7-4. A more advanced table using HTML5 syntax and the headers/@scope method

The code to build it using HTML5 syntax is shown in Listing 7-5.

Listing 7-5. Using the Headers/@scope Method to Create a More Advanced Table

<section>
<h1>Animal Sanctuary workshops</h1>
<table>
<caption>An overview of upcoming Animal Sanctuary workshops in 2012</caption>
<thead>
<tr>
<th>Course Number
<th>Course
<th>Start Date
<th>End Date
<th>Cost
<th>Included Extras
<tbody>
<tr>
<td><th scope=row group>How do you start an Animal Sanctuary<td><td><td><td>
<tr>
<td>#001
<td>Introduction
<td>June 10
<td>June 16
<td>250 Euros
<td>includes lunches, and one dinner.
<tr>
<td>#002
<td>Advanced
<td>August 10
<td>August 16
<td>550 Euros
<td>includes lunches, one dinner and extensive materials.
<tbody>
<tr>
<td><th scope=rowgroup>Working with Dogs: A beginners workshop<td><td><td><td>
<tr>
<td>#003
<td>Introduction
<td>April 12
<td>April 16
<td>100 Euros
<td>includes lunches, and materials.
<tr>
<td>#004
<td>Advanced
<td>May 16
<td>May 20
<td>300 Euros
<td>includes lunches, and materials.
<tbody>
<tr>
<td><th scope=rowgroup>Massage for You & Your Animals<td><td><td><td>
<tbody>
<tr>
<td>#005
<td>Introduction
<td>September 29
<td>October 4
<td>200 Euros. A Half-day session is 110 Euros.
<td>includes lunch.
<tr>
<td>#006
<td>Advanced
<td>November 29
<td>December 4
<td>400 Euros. A Half-day session is 220 Euros.
<td>includes lunch.
<tbody>
<tr>
<td>
<th scope=rowgroup>Yoga with Animals<td><td><td><td>
<tr>
<td>#007
<td>Introduction
<td>May 18
<td>May 21
<td>100 Euros.
<td>includes lunch.
<tr>
<td>#008
<td>Advanced
<td>June 18
<td>June 21
<td>200 Euros.
<td>includes lunch, dinner and book.
<tbody>
<tr>
<td>
<th scope=rowgroup>A Creative Artistic workshop and Retreat<td><td><td><td>
<tr>
<td>#009
<td>Introduction
<td>June 18
<td>June 23
<td>250 Euros
<td>includes lunch.
<tr>
<td>#010
<td>Advanced
<td>June 18
<td>June 23
<td>500 Euros
<td>includes lunch, dinner and art supplies.
<tbody>
<tr>
<td>
<th scope=rowgroup>Why Compassion for Animals matter: Philosophy and Animals<td><td><td><td>
<tr>
<td>#011
<td>Introduction
<td>July 12
<td>July 14
<td>200 Euros.
<td>includes lunch.
<tr>
<td>#012
<td>Advanced
<td>August 12
<td>August 14
<td>400 Euros.
<td>includes lunch, and materials.
<tbody>
<tr>
<td>
<th scope=rowgroup>Sanctuary Basics<td><td><td><td>
<tr>
<td>#013
<td>Introduction
<td>September 22
<td>September 24
<td>275 Euros.
<td>includes lunch.
<tr>
<td>#014
<td>Advanced
<td>September 22
<td>September 24
<td>275 Euros.
<td>includes lunch, and class materials
</table>
</section>

You can also see the headers in the table itself by using a tool like Webaim's WAVE Toolbar (which we'll look at in depth in Chapter 10) to see the headers at both the top of the data table as well as the headers that are contained deeper in the data table. Figure 7-5 shows an overview of the WAVE Toolbar interface.

Image

Figure 7-5. Visual view of the <th> elements in a data table

What about more complex tables? Ultimately, for more complex tables—for example, cells span multiple rows and there are headings nested deeper in the table—you are a little limited in the markup you can apply that will really work (from an accessibility perspective). I seriously suggest always trying to simplify your data table design wherever possible and making sure that you use more bulletproof methods like header/ID combinations. Adding a <caption> element to a table is a big help, and although the use of @summary is currently frowned upon in HTML5, adding one still works with many AT. If that is a bridge too far, you can add aria-describedby to provide more instruction; however, using that method means that the instruction needs to be an on-page description. I would break the law and still add @summary to describe the complex table to a blind user (it is hidden visually). Then again, I think I just have problems with authority.

Should you build complex tables at all? Well, you can certainly have headers for data cells that span more than one column or row, but you really need to ensure that you embed headers in your more tricky tables (see Figure 7-5) and use appropriate IDs to create programmatic associations between these headers and data cells.

Although there are more advanced HTML markup methods that promise to be easier to author or just be 'better' as technology advances, in practice the simple methods outlined here are what you should stick to. For more complex tables—where the use of @scope would be ideal –bear in mind that it is still poorly supported. So even though a markup method may be ‘good’ (from a pure coding perspective) and make sense semantically, you still have to be careful and test, test, test. The rub is that the AT vendors need to play catch up with what authors are doing and what the spec is suggesting. Actually, there is little new in @scope. It has been around for years.

Image Note Regarding the new HTML5 Table Syntax, I must admit that initially I had mixed feelings about it. However, when I was coding the preceding example, I found the leaner syntax easier to write first of all, and then quite good when I was reviewing the code. I like the way it lends itself to thinking in the grid. You can lay out the code in your editor of choice, pretty much as you would—visually—the table cells in your data table. Sure, you can also do this with HTML 4, but the newer syntax is much less cluttered and makes visually parsing the code a little easier. Although I was initially reluctant, I found myself pleasantly surprised.

Use of Scope and AT Support

Although technically the scope attribute is supposedly supported by some screen readers today, in practice it is really rather limited. Support for header/ID combinations (as mentioned earlier), on the other hand, is excellent. The AT vendors might claim to support @scope, but when you build data tables using it, you might notice very little (if any) difference between a table that uses @scope and one that doesn't.

In time, this needs to change for a couple of reasons. First, authoring accessible data tables with headers/@scope is less time consuming for developers; second, the new HTML5 code is much leaner, which means faster page loads and so on. Also, the use of @scope give you the potential to mark up more complex data tables.

Image Note A few years ago, the HTML5 working group took a stance that data tables didn't need headers and that @scope was enough to build data tables. Headers on data tables were going to be dropped from the specification. Thankfully, this didn't happen because this move would have been disastrous for older users of AT (and there are many). If you are interested in the details of the debate, check out the HTML5 Working Group ESW wiki:2

New Ways of Describing HTML5 Tables

Some new ways for describing the table are suggested in the specification, and I am including examples of them here for the sake of completeness. You can use them if you want. However, I take issue with some of them, and currently support for the new elements like <figcaption> and the<details> element is poor. In time, this will change. You need to make a call as to whether you want to provide a textual description of the table before or after it, and then create some programmatic link between them. The argument for this kind of model is that it helps people with cognitive impairments understand the table better, and there is certainly some truth in this. However, often it is unnecessary for simple tables, and more complex tables benefit more from @summary descriptions (which is unfortunately invalid in HTML5) or some equivalent.

Some ways that the specification suggests to describe a data table, which might be either simple or more complex, follow.

Method #1: In Prose, Surrounding the Table

The example in Listing 7-6 uses the <p> element above the table as a verbose text description of what follows. The idea is that the description will suffice for all users because it is presented within the browser.

Listing 7-6. Verbose Text Description of a Data Table

<section>
<p>In the next table the number of animals we have in care are given in the first column,
Number in Care, the animal type is in the second column, Animal Type, and the third column
shows the number that are available currently.</p>
<table>
<caption>The number of animals in care that we have and that are available for immediate re-
housing.</caption>
<thead>
<tr>
<th id="number"> Total in Care
<th> Animal Type<th> Number available
<tbody>
<tr>
<td headers="number row1"> 12
<th id="row1"> Older Dog<td> 7
<tr>
<td headers="number row2"> 9
<th id="row2"> Aging Cat<td> 6
<tr>
<td headers="number row3"> 14 <th id="row3"> Young Puppy<td> 9
<tr>
<td headers="number row4"> 23
<th id="row4"> Kitten <td> 15
<tr>
<td headers="number row5"> 5
<th id="row5"> Pony<td> 4
<tr>
<td headers="number row6"> 3
<th id="row6"> Horse<td> 1
</table>
</section>

__________

2 www.w3.org/html/wg/wiki/IssueTableHeaders

Image Note Listing 7-6 has two headers because the markup is used to reference both the header at the top of the table and one that is inline. The HTML5 spec allows multiple headers to be referenced in this way.

Although having a verbose description immediately above the table is a good idea (and users of screen readers, if they need to, will be able to discover it more easily because it is very close to the table), it is still flawed. This is because there is no programmatic association that is explicit in the code. As you know by now, screen-reader users can bounce around web content using their AT, so an explicit association is very helpful, because it will be announced as soon as the table receives focus. This happens with the <caption> in Listing 7-6.

Method #2: Using aria-describedby with a Data Table

A way around this previously was to add a @summary element that describes the table. It is hidden from sighted users but very useful for screen-reader users. How can you provide a more explicit description that is programmatically associated? You can use a @summary, but you get an error from the Validator (available at http://validator.w3.org). If you can live with that, then fine. An alternative is to use aria-describedby to point at a description on the page. The code is shown in Listing 7-7.

Listing 7-7. Using aria-describedby to Describe the Table

<section>
<p id="desc">In the next table the number of animals we have in care are given in the first
column, Number in Care, the animal type is in the second column, Animal Type, and the third
column shows the number that are available currently.</p>
<table aria-describedby="desc">
<caption>The number of animals in care that we have and that are available for immediate re-
housing.</caption>
<thead>
<tr>
<th id="number"> Total in Care
<th> Animal Type<th> Number available
<tbody>
<tr>
<td headers="number row1"> 12
<th id="row1"> Older Dog<td> 7
<tr>
<td headers="number row2"> 9
<th id="row2"> Aging Cat<td> 6
<tr>
[…]

Coding your table like this allows the screen reader to point to the on-page description. Note that it doesn't have to be directly above or below the table to work, as long as the description is anywhere on the same page as the table it will work.

Method #3: In the Table's <caption>

The HTML5 specification suggests that you can provide these descriptions in the <caption> element. This is similar to the code shown in Listing 7-8.

Listing 7-8. Describing the Table in the <caption>

<section>
<table>
<caption>Table outlining the number of animals we have in care are given in the first column,
Number in Care, the animal type is in the second column, Animal Type, and the third column
shows the number that are available currently.</caption>
<thead>
<tr>
<th id="number"> Total in Care
<th> Animal Type<th> Number available
<tbody>
<tr>
<td headers="number row1"> 12
<th id="row1"> Older Dog<td> 7
<tr>


[…]

Although the example in Listing 7-8 is valid HTML5, I feel it overloads the <caption> with too much information and also changes the purpose of any caption as a short description to a much longer one. Presenting information like this as a longer description might be better marked up using aria-describedby, or it would be perfect for a @summary.

Method #4: In the Table's Caption, in a <details> Element

The HTML5 specification also recommends that the table's <caption> be used in conjunction with the new <details> element to provide a description as shown in Listing 7-9.

Listing 7-9. Using the <details> Element to Describe the Table

<section>
<table>
<caption>
<strong>The number of animals in care that we have and that are available for immediate re-
housing.</strong>
<details>
<summary>Help</summary>
<p>the number of animals we have in care are given in the first column, Number in Care, the
animal type is in the second column, Animal Type, and the third column shows the number that
are available currently.</p>
</details>
</caption>
<thead>
<tr>
<th id="number"> Total in Care
<th> Animal Type<th> Number available
<tbody>
<tr>
<td headers="number row1"> 12
<th id="row1"> Older Dog<td> 7
<tr>

[…]

In the example in Listing 7-9, note two new elements: <summary> and <details>.

The new <details> element represents a disclosure widget from which the user can obtain additional information or controls. You can use it to create accordion-style show/hide controls, for example. Note that it is not appropriate for footnotes. This new element is currently supported by the newer versions of Firefox, IE9, and Safari 5. These descriptions, again, are visible in the browser by default, but they can be hidden using CSS if required.

The <summary> element is a child of the <details> element and is used to represent the summary or legend. It is different from the @summary of the table element from earlier versions of HTML5.

Method #5: Next to the Table, in the Same Figure

This next method, shown in Listing 7-10, wraps the entire table in a <figure> element and uses <figcaption> to provide the initial short description and the <p> element to provide the longer description.

Listing 7-10. Using <figcaption> to Describe the Table

<figure>
<figcaption>The number of animals in care that we have and that are available for immediate
re-housing.</figcaption>
<p>the number of animals we have in care are given in the first column, Number in Care, the
animal type is in the second column, Animal Type, and the third column shows the number that
are available currently.</p>
<table>
<thead>
<tr>
<th id="number"> Total in Care
<th> Animal Type<th> Number available
<tbody>
<tr>
<td headers="number row1"> 12
<th id="row1"> Older Dog<td> 7
<tr>
[…]
</table>
</figure>

The current problem with this method is that apart from the entire <table> being wrapped in a <figure> (a method that is currently not very well supported by AT), there is no other programmatic association between the descriptive text and the table element. So it won't be wise to use this method until support for the <figure> element improves. At the time of writing this, there is some support in Firefox for <figure> and <figcaption>.

Conclusion

As you can see from the preceding examples, there are lots of ways to describe data tables using HTML5 and to make them more accessible. The more tried and trusted methods are usually the best, and the old adage captured in the acronym KISS (Keep It Simple, Stupid) certainly applies. In the next chapter, we will look at HTML5 forms and some of the new elements and form controls you can use to make your forms more responsive, usable, and accessible.