Back to Freecodecamp

What Are Best Practices for Tables and Accessibility?

curriculum/challenges/english/blocks/lecture-accessible-tables-forms/672a539b887ec68c593cdc4b.md

latest7.0 KB
Original Source

--interactive--

When we see a table, we immediately start making visual associations between the data and the headers.

For example, let's say we have a table representing our pets. We have two dogs and two cats and the table is showing us their names and ages. While a sighted person may be able to understand the relationships in this table, making the connections between the values and the headers is much harder for people who use screen readers to navigate the table.

As a web developer, you are in charge of creating these associations and structuring your HTML markup in a way that is also easy for screen reader users to interpret.

So, let's see how you can create accessible tables that everyone can understand. The first best practice that we will cover is using table caption. With the caption element, you can write the caption (or title) of a table, so users, especially those who use assistive technologies, can quickly understand the table's purpose and content. You should place the caption element immediately after the opening tag of the table element. This way, screen readers and other assistive technologies can provide more context by announcing the caption before reading the content.

html
<table>
  <caption>Our Pets</caption>
  <!-- Table Rows and Columns -->
</table>

Now let's talk about row and column headers. Headers are special cells, typically found at the start of a row or column, that describe the type of data stored in the row or column. You can define a row or column header with the table header element, th.

For example, the code below creates a table for two pets. Every row has a row header (the name of the pet) and every column has a column header, which describes what the data in the column represents (age and type).

:::interactive_editor

html
<table>
  <caption>Our Pets</caption>
  <thead>
    <tr>
      <!-- Column Headers -->
      <th>Name</th>
      <th>Age</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>Nora</th> <!-- Row Header -->
      <td>5</td>
      <td>Dog</td>
    </tr>
    <tr>
      <th>Gino</th> <!-- Row Header -->
      <td>2</td>
      <td>Cat</td>
    </tr>
  </tbody>
</table>

:::

Notice that the above code has a caption element immediately after the opening table element. Then, inside the table head (thead) element, it has the column headers (Name, Age, and Type). In the second and third rows, inside the table body (tbody) element, we find the data for each one of our pets. The names of the pets are the row headers because they are inside table header elements (th).

Associating the data cells with their corresponding headers is also very important for screen readers. The scope attribute determines if a header is a row header or a column header. Screen readers may guess this correctly from the table's structure, but it's usually recommended to explicitly indicate the scope to ensure clarity.

The scope attribute has four possible values. The two you will use most often are col for column and row for row. In the code below, you can see that we added the scope attribute to the column and row headers. The three column headers (Name, Age, and Type) have a scope of col, column.

The two row headers (Nora and Gino) have a scope of row.

:::interactive_editor

html
<table>
  <caption>Our Pets</caption>
  <thead>
    <tr>
      <!-- Now they have scope -->
      <th scope="col">Name</th>
      <th scope="col">Age</th>
      <th scope="col">Type</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Nora</th>
      <td>5</td>
      <td>Dog</td>
    </tr>
    <tr>
      <th scope="row">Gino</th>
      <td>2</td>
      <td>Cat</td>
    </tr>
  </tbody>
</table>

:::

If a column or row header spans across multiple cells, the scope will also be applied to each one of the cells individually. Here's an example of that:

:::interactive_editor

html
<table>
  <tbody>
    <tr>
      <td></td>
      <th scope="col">Name</th>
      <th scope="col">Age</th>
    </tr>
    <tr>
      <th rowspan="2" scope="row">Dogs</th>
      <th scope="row">Nora</th>
      <td>5</td>
    </tr>
    <tr>
      <th scope="row">Gino</th>
      <td>2</td>
    </tr>
    <tr>
      <th rowspan="2" scope="row">Cats</th>
      <th scope="row">Lulu</th>
      <td>10</td>
    </tr>
    <tr>
      <th scope="row">Elizabeth</th>
      <td>6</td>
    </tr>
  </tbody>
</table>

:::

In this table, the cell with Nora's age (5) will have one column header (Age) and two row headers (Dogs and Nora). Gino's age (2) will also have one column header (Age) and two row headers (Dogs and Gino).

However, some screen readers may not be able to interpret tables with complex structures, so you should also try to flatten the table as much as possible to avoid row and column headers that span across multiple cells.

Your goal should always be to make sure users can access this information, even if their screen readers can handle complex table structures.

Now, for cell width, it's recommended to avoid using fixed values. You should use relative values instead, like percentages. Also, try to avoid defining cell height. This will allow users to adjust the text size to fit their needs.

And finally, you should let the browser determine the table width whenever possible, to reduce the need for horizontal scrolling.

HTML tables are essential for presenting structured data in an accessible and understandable format. By following these accessibility guidelines, you can create tables that are easy to understand for everyone.

--questions--

--text--

Which HTML element is used to specify the title of a table?

--answers--

thead

--feedback--

Think about how you would describe the table.


caption


tbody

--feedback--

Think about how you would describe the table.


tr

--feedback--

Think about how you would describe the table.

--video-solution--

2

--text--

What is the purpose of the scope attribute in a table header cell (th)?

--answers--

To specify the colspan and rowspan of the cell.

--feedback--

Think about how screen readers interpret table structure.


To indicate whether the header applies to a row or a column.


To define the style of the header cell.

--feedback--

Think about how screen readers interpret table structure.


To add a tooltip to the header cell.

--feedback--

Think about how screen readers interpret table structure.

--video-solution--

2

--text--

Which of the following is a best practice for creating accessible tables?

--answers--

Using complex and long table headers.

--feedback--

Think about how table complexity affects accessibility.


Not providing alternative text for images within table cells.

--feedback--

Think about how table complexity affects accessibility.


Using simple table structures with row and column headers.


Nesting tables within tables.

--feedback--

Think about how table complexity affects accessibility.

--video-solution--

3