Accessible Content Creation – Tables

When I covered the content structure, I explained paragraphs, lists, and blockquote elements. These are the most common elements you will use in your content, and it’s important to understand those elements. Because tables are less common and significantly more complex, we are covering them in a separate tutorial. 

Tables have traditionally been one of the most misused elements in web design. They were introduced in the early days of the internet and designers started using them to position and control content. It worked more or less, but that was never the intent. Eventually, there were new ways to create the same layouts with less complexity, so the practice has improved but has not gone away. Often content creators want to arrange content into a grid, so they think “Perfect! I can use a table.” This may not be a good idea for two reasons: responsive design and accessibility.

Responsive design in tables

Tables are often really poor choices for responsive design. They don’t “reflow” which means content can’t rearrange to fit the screen. This requires complex scripts and styles to fix. Other tools can create the grid layout without this major limitation.

Accessibility in tables

The responsive design issue is also an accessibility issue because it affects how users on mobile devices access your content. Remember, accessibility is about making the content easy to consume for all users, not just disabled users.

However, when it comes to screen readers, tables have a special mode for traversing content. A screen reader user can enter a table using the table navigation mode and use arrow or gesture navigation to move around cells, similar  to how you might navigate a spreadsheet. 

The screen reader will read correctly coded headings to describe cells.

This is very good when a table is used correctly, but often tables are not used correctly and the result is unlabeled tables, rows, columns, and cells. A screen reader user is left with no context as they navigate the tables.

When to use tables

By now you may be thinking, “I should never use a table.” Because of the complexity, this may be a safe starting point, but there are times when a table should be used.

If you have tabular data, you should use a table. That’s a bit of circular reasoning, but it’s helpful to understand what tabular data is.

Ask yourself, is this content something I would put in a spreadsheet or in a doc? Even if you put it in a doc as a table, that doesn’t mean it’s tabular data. Let’s say you were keeping an aquarium and every morning you measure ammonia, nitrite, nitrate, pH, and CO2 levels. Would you keep this information in a doc or a spreadsheet?

The best way to track that data is a spreadsheet. This allows you to build graphs, sort content, and find trends. You would have 2 axis labels to work with:

  • Date
  • Levels
    • Ammonia
    • Nitrite
    • Nitrate
    • pH
    • CO2

This is tabular data.

Date Ammonia Nitrite Nitrate pH CO2
Aquarium Data
May 1 0 0 5 7.3 18
May 2 0.1 0 8 7.3 20
May 3 0 0.1 12 7.4 16

Tabular data could be inserted using layout logic, but it’s best when inserted using tables. There are a few rules for using it.

Table markup

At this time, the table block is not accessible. The caption has the wrong HTML markup and it isn’t possible to define a cell or column as a header with the correct scope for rows.

If you have a single table on the page and there is a single axis for the data, it would be acceptable to use the table block. However, if the left column is a label for the row, as in the example above, it is impossible to make the table accessible using the core block right now. 

Additionally, the caption field is marked up using an alternate approach that is not compatible with table mode on all screen readers. This may be acceptable if there is only a single table, but for multiple tables, it will cause confusion.

It is possible to use the table block in its current form, but in an extremely limited scope. The following table was inserted using the table block.

ColorMaterialPower Modes
Walnut StainMapleBasic powered
Maple StainOakPremium powered
Features for a standing desk

This has a single axis that lists the possible features for a standing desk. If we look at this block in the editor, we see that the top row is a header row. This automatically marks it up to allow screen readers to read the header with the cell like “Material: Oak” when the “Oak” cell comes into focus. 

If this were a comparison table listing products and the features they include, it would become a two-axis table because the top row and first column become the labels for the cells just like in the “aquarium data” table. 

For two-axis tables, I recommend using an HTML block with correctly coded HTML for the table. I tried several tools online and discovered that most do not build accessible tables, even if the word “accessible” is in their name. 

One I did find appears to use the tinyMCE editor, which is the classic editor, to allow building HTML. This tool allowed setting all the important fields for a properly coded and accessible table. I’ll demonstrate how to use it and the most important features of an accessible table. Visit HTML Cleaner – Online to build your own accessible tables.

Insert Table

The first thing I will do is remove all the existing content within the HTML Cleaner tool by clicking in the editor and using command+a to select all. On a PC that is ctrl+a. Then I’ll use the delete or backspace key to remove the content.

Now I can click the table button in the toolbar to insert a table. This is a multifunction button that we will use to edit the table, rows, and cells after inserting the table. 

I can navigate to the “insert table” submenu and then use the grid to generate a 6×4 table, which is what I need for my table structure. This will insert a table.

Table caption

Tables should have a label. This is probably the most often overlooked aspect of a table. Screen readers can find a table but without the label, they won’t know what a given table means. If there is more than one table, this is a real issue. 

Using the HTML Cleaner tool, I can set the caption by following these steps:

  1. Click on the table I wish to edit in the MCE editor window
  2. Click the table button in the MCE toolbar
  3. Click “Table Properties” in the table submenu
  4. In the modal that pops up, check the “caption” box to ensure the caption is enabled
  5. Click the “ok” button to close the modal
  6. Click into the new field at the top of the table
  7. Type my caption

As a bonus, the table properties will let you set borders and other options for the table. These aren’t strictly required for accessibility, but it’s helpful to know.

Table head

Often, tables will use the first row to create the x-axis heading. By itself, the table heading row has no specific accessibility meaning, but it can be styled differently to create visual hierarchy. For long tables it could be styled in a fixed position with some added CSS so it floats at the top of the table, which can be helpful.

In the HTML Cleaner tool, it is possible to make a row into a header row. Watch as I follow these instructions:

  1. Click the row I will be editing in the MCE editor window
  2. Click the table button in the MCE toolbar
  3. Navigate to the “Row” submenu. Select the “Row properties item from the flyout.
  4. Use the “row type” dropdown in the modal that pops up to select “header”
  5. Click “ok” to save the changes and close the modal

Heading Cells

The heading row doesn’t specifically help with markup, so it is necessary to set the individual cells as “heading cells” and to define the scope. This will make it clear which data cells are controlled by which heading cells. 

The cell must be set as a heading and the scope must be defined for each cell. The scope is set to “column: for the top row cells and to row for the leftmost column of cells. This means that the cells that fall under a heading cell in the top row are labeled by that cell and cells that are to the right of a left column header are defined by that cell.

Watch as I set the heading status for a couple of cells following these directions:

  1. Click the cell in the MCE editor window
  2. Click the table icon in the MCE toolbar
  3. Navigate to the “cell” submenu item. Select the “Cell properties” item from the flyout. 
  4. In the modal that comes up, select “Header cell” for the “Cell type” select control
  5. In the same modal select “Row” or “Column” for the “Scope” select control
  6. Click “ok” to save the changes and close the modal

For the first cell, I am clicking in the header row, so I will set this to be a header cell and select “Column” for the scope.

On the next cell, I’ll pick one of the left column cells. Now I can make it a header cell and select “Row” for the scope. I’ll repeat this process for each cell in the top row and left column, making sure to get the correct scope.

You may have noticed some additional controls. These aren’t specifically required for accessibility, but they can help improve the visual layout of the table. I would recommend exploring the controls in order to learn how to build tables that have the look and feel you are after.

Now my table is complete and I’ve added some visual styling using the controls in the editor. The cells are all marked up with the correct heading and scope values.

Screen readers can use the heading and scope information to provide context for the other cells as users navigate. Different screen readers will handle this differently, but they will read something like, “pH May1 7.3” when reaching the cell under pH and to the right of May 1. This is much more helpful than “7.3” with no context, which is what screen readers will get if the table is not built correctly.

Using the HTML block to insert the table

Now that the table is complete, I can insert it into my content. 

First, I’ll click into the HTML field on the right of the MCE editor window. Now I’ll use the keyboard shortcut command+a (which is ctrl+a on a PC) to select all. Next I can use command+c (or ctrl+c) to copy.

The next step is to go to the WordPress block editor I have open and to insert an HTML block. This allows me to paste in raw HTML. After inserting the block, I can paste the code I copied earlier using command+v (ctrl+v) and preview my changes.

Now I have a fully accessible table with my example tabular data.

Layout without tables

Tables work great for tabular data, but often you may want a grid-like layout but don’t have tabular data. This is content you might put into a document and use a table to align it, but the content isn’t really suited to a spreadsheet. The information would be something a user could review linearly, starting from a heading and moving along a row in the layout. 

Column Layout

This is content that is arranged into columns. For this demo, there are 2 columns. This could have more than 2. 

Adding Column Blocks

In the block editor 

  • Add a column block
  • Select the layout
  • Add content
  • Use headings for the first row if appropriate
  • Continue adding column blocks for each row

Responsive Columns

Unlike a table that doesn’t reflow, the column blocks are built to be responsive. On mobile devices, this will automatically arrange rows into columns. If you add a heading in the first column, it means the content of each section will start with a heading.

Accessible columns

The columns have a role of “presentation” which means they behave like the content on the rest of the page. Using headings will make it navigable by section. Otherwise, there isn’t anything special to do when using columns to build your grid layout for accessibility.

As you can see, this makes the layout quick and solves a lot of issues that come with tables. 

The important takeaways here are: 

  • Use tables for tabular data
  • Use column blocks for layouts

Next time we’ll be talking about contrast.

Get the latest from Reaktiv