Skip to Main Content

Tables

Tables are made up of rows and columns that give structure to data in a way that makes it easier to understand.

Use when:

  • You want to make a large data set easy to understand.
  • You want to present all available options to the user.
  • Users would benefit from comparing or filtering information.

Interactive component

Title
This is an optional caption Footnotes for this table will appear below.
Column heading Column heading Column heading Column heading
Subheading
Row heading Cell content Cell content Cell content Footnote 1
Row heading Cell content Cell content Cell content
Row heading Cell content Cell contentFootnote 1 Cell content
Subheading
Row heading Cell content Cell content Cell content
Row heading Cell content Cell content Cell contentFootnote *
Subheading
Row heading Cell content Cell content Cell content
Row heading Cell content Cell content Cell content
Row heading Cell content Cell content Cell content

Footnote

Title
This is an optional caption Footnotes for this table will appear below.
Column heading Column heading Column heading Column heading
Subheading
Row heading Cell content Cell content Cell content Footnote 1
Row heading Cell content Cell content Cell content
Row heading Cell content Cell contentFootnote 1 Cell content
Subheading
Row heading Cell content Cell content Cell content
Row heading Cell content Cell content Cell contentFootnote *
Subheading
Row heading Cell content Cell content Cell content
Row heading Cell content Cell content Cell content
Row heading Cell content Cell content Cell content

Footnote

Library integration

Use the codes below to add this component to your project. Download the latest version of the library to easily implement our full range of components.

Angular

Step 1. Install

Execute the following command to install this component.

npm i [NPM-PLACE-HOLDER]/ds-table

Step 2. Import

Import the following into your app.module.ts file.

import { DsTableModule } from 'ds-table';

Code snippets

Table - Desktop View
<cpc-ds-table title="Title" [accordionMobileView]="false" tableDataURL='url to json file'></cpc-ds-table>
Table - Mobile View
<cpc-ds-table title="Title" [accordionMobileView]="true" tableDataURL='url to json file'></cpc-ds-table>

HTML

Step 1: Import CSS

Import the following into your theme or page.

<link type="text/css" href="[CSS-PLACE-HOLDER]" rel="stylesheet">

Step 2: Import JS

Import the following into your theme or page.

<script src="[JS-PLACE-HOLDER]"></script> 

Code snippets

Table
<div data-title="TABLE">
                <h2 class="section-heading">Table</h2>
                <div class="table-title">Title</div>
                <table class="responsive-table">
                <caption>Caption (optional) <span class="wb-inv-caption">Footnotes for this table will appear below.</span></caption>
                <thead>
                    <tr>
                    <th class="col" scope="col">Film title</th>
                    <th class="col" scope="col">Released</th>
                    <th class="col" scope="col">Studio</th>
                    <th class="col" scope="col">Budget</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                    <td id="subheading-kids" scope="row" class="subheading" colspan="4">Kids ABS BS BSB SBS BS BSB SBS BS SB SB S SB sjhdd ksad aksdh ak</td>
                    </tr>
                    <tr aria-labelledby="subheading-kids" class="trow">
                    <th scope="row">Minions</th>
                    <td data-title="Released">2015</td>
                    <td data-title="Studio">Universal</td>
                    <td data-title="Column heading content aligns to the bottom of the cell.">$1,159,444,662 <sup tab-id="subheading-kids"><a class="by-keyboard" id="fn1-1-rf" href="#fn1"><span class="wb-inv">Footnote </span>1</a></sup></td>
                    </tr> 
                    <tr aria-labelledby="subheading-kids" class="trow">
                    <th scope="row">Toy Story 4</th>
                    <td data-title="Released">2019</td>
                    <td data-title="Studio">Disney Pixar</td>
                    <td data-title="Column heading content aligns to the bottom of the cell.">$1,073,394,593</td>
                    </tr>
                    <tr aria-labelledby="subheading-kids" class="trow-last">
                    <th scope="row">Toy Story 3</th>
                    <td data-title="Released">2010</td>
                    <td data-title="Studio">Disney Pixar <sup tab-id="subheading-kids"><a class="by-keyboard" id="fn1-2-rf" href="#fn1"><span class="wb-inv">Footnote </span>1</a></sup></td>
                    <td data-title="Column heading content aligns to the bottom of the cell.">$1,066,970,811</td>
                    </tr>

                    
                    <tr>
                    <td id="subheading-fantasy" scope="row" class="subheading" colspan="4">Subheading</td>
                    </tr>
                    <tr aria-labelledby="subheading-fantasy" class="trow">
                    <th scope="row">Despicable Me 3</th>
                    <td data-title="Released">2017</td>
                    <td data-title="Studio">Universal</td>
                    <td data-title="Column heading content aligns to the bottom of the cell.">$1,034,800,131</td>
                    </tr>
                    <tr aria-labelledby="subheading-fantasy" class="trow-last">
                    <th scope="row">Finding Dory</th>
                    <td data-title="Released">2016</td>
                    <td data-title="Studio">Disney Pixar</td>
                    <td data-title="Column heading content aligns to the bottom of the cell.">$1,028,570,942<sup tab-id="subheading-fantasy"><a class="by-keyboard" id="fn*-1-rf" href="#fn*"><span class="wb-inv">Footnote </span>*</a></sup></td>
                    </tr>


                    <tr>
                    <td id="subheading-action" scope="row" class="subheading" colspan="4">Action</td>
                    </tr>
                    <tr aria-labelledby="subheading-action" class="trow">
                    <th scope="row">Gladiator</th>
                    <td data-title="Released">2017</td>
                    <td data-title="Studio">Universal</td>
                    <td data-title="Column heading content aligns to the bottom of the cell.">$1,034,800,131</td>
                    </tr>
                    <tr aria-labelledby="subheading-action" class="trow">
                    <th scope="row">Terminator</th>
                    <td data-title="Released">2017</td>
                    <td data-title="Studio">Universal</td>
                    <td data-title="Column heading content aligns to the bottom of the cell.">$1,034,800,131</td>
                    </tr>
                    <tr aria-labelledby="subheading-action" class="trow-last">
                    <th scope="row">Predator</th>
                    <td data-title="Released">2016</td>
                    <td data-title="Studio">Disney Pixar</td>
                    <td data-title="Column heading content aligns to the bottom of the cell.">$1,028,570,942</td>
                    </tr>
                </tbody>
                </table>
                <h2 class="wb-inv-ref" id="footnote">Footnote</h2>
                <ul id="tfooter" class="tfooter" role="list" aria-labelledby="footnote">
                    <li>
                    <div>
                        <a class="by-keyboard footnote" onclick="checkTabState('fn*')" id="fn*" href="#fn*-1-rf"><span class="wb-inv">Go to reference for footnote </span>*</a>
                    </div>
                    <div>Percentages are based on numbers rounded to the nearest thousand and have been adjusted for trading (business) or paid days, where applicable.</div>
                    </li>
                    <li>
                    <div>
                        <a class="by-keyboard footnote" onclick="checkTabState('fn1')" id="fn1" href="#fn1-1-rf"><span class="wb-inv">Go to reference for footnote </span>1</a>
                    </div>
                    <div>Percentages are based on numbers rounded to the nearest thousand and have been adjusted for trading (business) or paid days, where applicable.</div>
                    </li>
                </ul>
                <div class="spacer"></div>
            </div>

Code Samples

Basic

Note that this component may require additional styling.

Angular

Interaction

Tables let users easily digest large amounts of content and find what they’re looking for. They can help users understand entire data sets or specific attributes in a range of data.

Structure

A data table contains:
  • 2 or more columns and rows
  • Headers that clearly describe the content in each column

Use lines to separate the content featured in rows. If your data set features rows that need to be grouped into categories, consider a separate header for each category of rows. Columns and rows should be organized logically.

  • Don’t use zebra striping in your tables.

Actions

If you’re presenting information that has 1 action applying to the entire table, place the button at the foot of the table and left-align it. If users can take action on individual items within the table, consider applying menu actions to individual rows.

Let users scan, analyze, compare, filter, sort and manipulate the information in the table so they can understand it in a way that makes sense to them.

Data alignment

Numbers, text, headers and icons (when applicable) should all be left-aligned.
  • Centre-aligning the information in a table makes it difficult for the user to scan.

Row selection

When a row is selected, change the background colour to let the user know it has been selected. If a user needs to select or manipulate data, there should be a checkbox in each row. Use the selected state of a checkbox.

Column sorting

In some cases, it’s necessary to give the user an option to sort the information in a table. When this happens, it’s important to let the user know how it will be sorted and which column the information is being sorted by.

General guidelines

Tables allow information to be organized in a way that’s easily parsed through by the user. This can be a set of data in a spectrum and with variations. Tables often have a header row containing one set of information, with subsequent rows and columns.

  Guidelines Examples
Recommended length 1 to 3 words for column and row headings Cost
Line wrap Avoid Shipping speed
Phrasing Words or phrases Minimum quantity
Case Sentence case without period Regional

Dos and don’ts

Readability

Tables can be overwhelming given that they present different pieces of information all at the same time. Full sentences can contribute to visual overload. Use short phrases that help with skimming readability.

  • Address customers directly
  • Make your customers feel valued with a personalized direct mail piece they’re more likely to open.

Rows and columns

Labels for column and row headings should be as brief as possible. Introduce trademarked terms in text before the table. This will avoid having the trademark symbol (TM) in a heading.

  • Reach every mailbox with Neighbourhood Mail
  • Reach every mailbox with Canada Post Neighbourhood MailTM

Best practices

Think about how a table will appear across mobile devices and consider where another solution might be needed.

Accessibility considerations

Table caption

It can be helpful to include an accessible table caption specifically for users who rely on assistive technology. This way, they will be able to understand the visual elements of the table before they access it.

Customized table caption

  • The first and second columns show the dates and times of corresponding delivery status updates shown in the third column.

Guidelines

Focus halo

Tables have no focus halo of their own, but interactive controls in a table have a prominent focus outline when they're focused or hovered.

In mobile view, the table component is converted to a dataset represented by accordions instead of a grid. The accordion buttons have a prominent visual change when they're tapped.

Keyboard interaction

Tables themselves aren't interactive but can have interactive elements in them (for functions like sorting data or manipulating the contents of the table). Tables shouldn't be used for laying out a page.

Interactive elements inside a table are presented in the page tab order. Elements like links, buttons, and checkboxes inside a table should follow their respective keyboard interactions.

ARIA properties

A table can have the following ARIA properties:

  • The role of “table” (this isn’t required when the HTML <table> element is being used).
  • A “caption”, along with any visible or invisible summary text as a part of the “caption” element.
  • Aria-sort set to “ascending” or “descending” on the sorted table column header.
  • Headers associated to their respective data cells using the “scope” attribute.
  • Multiple header levels using spanned colgroup and rowgroup to associate the headers with their data cells.
  • For tables where the “header” association is complex: Attribute headers and ID’s that can be used to associate the data cells with their respective headers (when possible). We recommended exploring different UI presentations to avoid such complexity.

Caption

A caption is a table title or heading that briefly tells the user what's in the table. A caption can be used to provide a descriptive title for the table. While not all tables need to have a visible caption, they're helpful for users to understand the table’s context.

Captions can also be used to convey the following information to users, either visible on screen or invisible and announced only to screen readers:

  • That the table contains footnotes
  • The location of the footnotes
  • The current state of the table, including whether the table is sortable, has columns that can be modified or deleted, and other data manipulation features
  • A brief summary of the table’s intent or layout

Caption examples

Here are a some examples of caption text:

  • Students currently enrolled in DATA STRUCTURES 101 for the coming semester.
  • Students currently enrolled in DATA STRUCTURES 101 for the coming semester. Footnotes for this table will appear below.
  • Students currently enrolled in DATA STRUCTURES 101 for the coming semester, sorted ascending by first name.

Footnotes

Key features of table footnotes:

  • Footnotes must be presented in an unordered list.
  • Footnotes must have a visible heading and the heading must be programmatically associated with the footnotes list using the aria-labelledby attribute.
  • Each footnote link must target to a reference note, and vice versa.
  • Footnotes must have a functional loopback to their respective references. Users can use a reference link to move to the footnote, read it, and then use a link in the footnote to return to where the footnote was initially linked from. For a working example of how footnote loopbacks work, refer to the interactive component at the top of this page.

Testing

When testing a table, the tester must ensure:

  • The table is fully keyboard operable. 
  • The screen reader announces the table role, number of rows and columns, and caption (both visible and invisible).
  • The table is properly coded in HTML as a <table> with a “table” role. Using something that only looks like a table (for example, a list visually styled as a grid) doesn't have the needed semantics to support understanding and navigation for screen reader users. A test for this would be to press the ‘T’ key while using a screen reader from anywhere but the table body on the page and observing whether the screen reader moves too and if it announces the table.
  • Table headers aren't empty and that they're properly scoped. If a table header needs to look like it’s empty, non-visible text must be provided as a label.
  • The table’s caption conveys the title of the table, the presence of footnotes, and the state information for sortable tables. The caption may also include other information necessary to understand or navigate the table.
  • Table footnotes are arranged in an unordered list and have a visible heading that's announced with the footnote list.
  • Reference loopback works as expected for footnotes.

Related content