HTML & CSS

How to Make Web Tables Accessible for Everyone

Basically, the HTML elements available for defining tables are semantic elements.

 

Thus, for example, browsers (and other user agents such as screen readers) will recognize directly from the element that a <table> element is actually a table. In the same way, they recognize a table heading by the <th> element and a row of a table by the <tr> element. Nevertheless, even with tables, besides the correct use of the corresponding HTML elements, some additional aspects should be considered with regard to accessibility.

 

The Basic Table Structure

First, you should enclose table headers in a surrounding <thead> element (an exception will be discussed shortly) and surround the individual rows (the data records represented in the table body) with a <tbody> element. In addition, you can optionally add a footer to the table using the <tfoot> element.

 

Display of the Table (Adjusted with Some CSS)

 

Below shows some HTML code for defining an accessible table. This includes the <caption> element, which adds a short description to a table. This information is particularly helpful for users who want to quickly get an idea of what content the table represents. If this element were missing, screen reader users, for example, would first have the contents of some cells read out to them to determine the table’s meaning for themselves.

 

<!DOCTYPE html>

<html lang="en">

   <head>

       <title>Users</title>

       <meta charset="utf-8">

   </head>

   <body>

       <h1>Users</h1>

       <table>

           <caption>Users</caption>

           <thead>

               <tr>

                   <th>First Name</th>

                       <th>Last Name</th>

                   <th>Title</th>

               </tr>

           </thead>

           <tbody>

               <tr>

                    <td>Riana</td>

                   <td>Fresh</td>

                   <td>District Assurance Producer</td>

               </tr>

               <tr>

                   <td>Oscar</td>

                   <td>Spielvogel</td>

                   <td>Product Optimization Analyst</td>

               </tr>

               <tr>

                   <td>Lynn</td>

                   <td>Berning</td>

                   <td>Lead Accountability Administrator</td>

               </tr>

               <tr>

                   <td>Carolin</td>

                   <td>Plass</td>

                   <td>Investor Usability Strategist</td>

               </tr>

               <tr>

                   <td>Claas</td>

                   <td>Plotzitzka</td>

                   <td>Chief Implementation Analyst</td>

               </tr>

           </tbody>

           <tfoot>

               <tr>

                   <th>First Name</th>

                   <th>Last Name</th>

                   <th>Title</th>

               </tr>

           </tfoot>

       </table>

   </body>

</html>

 

Vertical and Horizontal Table Headings

The scope attribute, which can be assigned to <th> elements, specify whether the respective table heading refers to the associated column or the associated row (i.e., whether the heading is a vertical or horizontal heading).

 

By default, a table heading refers to the associated column (so the heading is vertical), which means that, in this case, the scope attribute is optional. Nevertheless, as shown below, a better approach is to explicitly specify the col value anyway to accommodate screen readers and get used to the correct usage directly yourself.

 

<!DOCTYPE html>

<html lang="en">

   <head>

       <title>Users</title>

       <meta charset="utf-8">

   </head>

   <body>

       <h1>Users</h1>

       <table>

           <thead>

               <tr>

                   <th scope="col">First Name</th>

                   <th scope="col">Last Name</th>

                   <th scope="col">Title</th>

               </tr>

           </thead>

           <tbody>

                 ...

           </tbody>

           <tfoot>

                 ...

           <table/tfoot

       </table>

   </body>

</html>

 

However, if the structure of a table requires the definition of table headings that refer to the corresponding table rows (such as the timetable shown in the below figure), you should use the row value for the scope attribute of the corresponding table headings.

 

Table with Vertical and Horizontal Table Headers

 

The listing below shows the corresponding source code. Notice how both horizontal headings (for defining the times) and vertical headings (for defining the days of the week) are used in this example.

 

<!DOCTYPE html>

<html lang="en">

<head>

   <title>Timetable</title>

   <link rel="stylesheet" href="styles.css">

   <meta charset="utf-8">

</head>

<body>

   <table>

       <caption>Timetable</caption>

       <tr>

           <td></td>

           <th scope="col">Monday</th>

           <th scope="col">Tuesday</th>

           <th scope="col">Wednesday</th>

           <th scope="col">Thursday</th>

           <th scope="col">Friday</th>

       </tr>

       <tr>

            <th scope="row">7.55 - 8.40</th>

           <td>English</td>

           <td>Music</td>

           <td>German</td>

             <td>Math</td>

           <td>PE</td>

       </tr>

       <tr>

           <th scope="row">8.45 - 9.30</th>

           <td>English</td>

           <td>German</td>

           <td>German</td>

           <td>Math</td>

           <td>PE</td>

       </tr>

       <tr>

           <th scope="row">9.30 - 9.50</th>

           <td>Recess</td>

           <td>Recess</td>

           <td>Recess</td>

           <td>Recess</td>

           <td>Recess</td>

       </tr>

       ...

   </table>

</body>

</html>

 

Note: Since in horizontal table headers the <th> elements are inside different <tr> elements, they cannot be “grouped” using a <thead> element. So, in this case, omitting the <thead> element is fine (the exception mentioned earlier).

 

Additional Information

Further information regarding the accessible construction of tables can be found again at the W3C’s WAI website, specifically at https://www.w3.org/WAI/tutorials/tables/. You’ll also find some useful information on what you need to consider with nested table headings.

 

Editor’s note: This post has been adapted from a section of the book Full Stack Web Development: The Comprehensive Guide by Philip Ackermann.

Recommendation

Full Stack Web Development
Full Stack Web Development

Full stack web developers are always in demand—do you have the skillset? Between these pages you’ll learn to design websites with CSS, structure them with HTML, and add interactivity with JavaScript. You’ll master the different web protocols, formats, and architectures and see how and when to use APIs, PHP, web services, and other tools and languages. With information on testing, deploying, securing, and optimizing web applications, you’ll get the full frontend and backend instructions you need!

Learn More
Rheinwerk Computing
by Rheinwerk Computing

Rheinwerk Computing is an imprint of Rheinwerk Publishing and publishes books by leading experts in the fields of programming, administration, security, analytics, and more.

Comments