Overview
Overview
Tables are available in light and dark styles. They can be borderless or contained and can have the option for vertical and horizontal scrolling.
Examples
Borderless
When seeking to integrate and expand the information that accompanies a text, a borderless table can prove advantageous. It imparts a sense of continuity and cohesion, making the data feel more seamlessly integrated with the surrounding text.
| Header | Header | Header |
|---|---|---|
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Footer | Footer | Footer |
<table class="qld__table">
<caption>Table caption
<span class="qld__caption">Table is ordered by</span></caption>
<thead>
<tr>
<th scope="col">Header</th>
<th scope="col">Header</th>
<th scope="col">Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
</tr>
</tfoot>
</table>
Contained
A contained table style features visible borders around the table, its rows, and columns, creating a clear and well-defined structure. The borders help separate data and improve readability by emphasising individual cells.
| Header | Header | Header |
|---|---|---|
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Footer | Footer | Footer |
<div class="qld__table--contained">
<table class="qld__table">
<caption>Table caption
<span class="qld__caption">Table is ordered by</span></caption>
<thead>
<tr>
<th scope="col">Header</th>
<th scope="col">Header</th>
<th scope="col">Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
</tr>
</tfoot>
</table>
</div>
Vertical Scrolling
A scrollable table is ideal for dense data. Tables that are extremely long can have vertical scroll turned on via the vertical scroll class. On desktop these tables will scroll vertically after 1000px and on mobile they will scroll vertically after 640px.
| Header | Header | ||
|---|---|---|---|
| Header | Header | Header | |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Cell | Cell | Cell | Cell |
| Footer | Footer | Footer | Footer |
<div class="qld__table--scroll" tabindex="0">
<table class="qld__table qld__table--striped qld__table__col-2-left-border qld__table__col-3-left-border"><caption>Table caption <span class="qld__caption">Table is ordered by</span></caption>
<thead>
<tr>
<th rowspan="2" scope="col">Header</th>
<th colspan="3" class="qld__table__cell-left-border qld__table__cell--middle">Header</th>
</tr>
<tr>
<th scope="col" class="qld__table__cell-left-border">Header</th>
<th scope="col" class="qld__table__cell-left-border">Header</th>
<th scope="col" class="qld__table__cell-left-border">Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
</tr>
</tfoot>
</table>
</div>
Custom widths
You can apply custom widths based on the expected length of the data within a corresponding column by applying a utlity class to the <th> elements.
By default tables are fluid and scale to the full width of the page, however a table can set to a desired width using the grid system and then use the qld__table__wrapper which will turn on horizontal scrolling on smaller devices.
| Header | Header | Header |
|---|---|---|
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Footer | Footer | Footer |
<!--
15% col width: <th class="qld__table__header--width-15">
20% col width: <th class="qld__table__header--width-20">
25% col width: <th class="qld__table__header--width-25">
33% col width: <th class="qld__table__header--width-33">
40% col width: <th class="qld__table__header--width-40">
50% col width: <th class="qld__table__header--width-50">
75% col width: <th class="qld__table__header--width-75">
-->
<div class="qld__table__wrapper col-xs-10">
<table class="qld__table qld__table__col-2-left-border qld__table__col-3-left-border">
<caption>Table caption
<span class="qld__caption">Table is ordered by</span></caption>
<thead>
<tr>
<th scope="col" class="qld__table__header--width-10">Header</th>
<th scope="col">Header</th>
<th scope="col" class="qld__table__header--width-50">Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
</tr>
</tfoot>
</table>
</div>
Striped/Banded
For data tables with more rows, use the striped alternative. Styling even and odd rows in a different way can be helpful to people who have reading difficulties or who enlarge text. It acts as a visual guide. Highlighting the cell (and row/column) on mouseover and keyboard focus to support people to see where they are.
| Header | Header | Header |
|---|---|---|
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Cell | Cell | Cell |
| Footer | Footer | Footer |
<div class="qld__table--contained">
<table class="qld__table qld__table--striped">
<caption>Table caption
<span class="qld__caption">Table is ordered by</span></caption>
<thead>
<tr>
<th scope="col">Header</th>
<th scope="col">Header</th>
<th scope="col">Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
</tr>
</tfoot>
</table>
</div>
Multilevel headings
Tables with multiple headers may also need to have a caption to identify them and a summary to describe the layout of the table, see Caption & Summary. In many cases, it is worth considering restructuring the information in such tables to make them less complex for all readers.
| Header | Header | ||
|---|---|---|---|
| Header | Header | Number % | |
| Cell | Cell | Cell | 5 |
| Cell | Cell | Cell | 10 |
| Cell | Cell | Cell | 15 |
| Cell | Cell | Cell | 20 |
| Cell | Cell | Cell | 25 |
| Footer | Footer | Footer | Footer |
<div class="qld__table--contained">
<table class="qld__table qld__table--striped qld__table__col-2-left-border qld__table__col-3-left-border qld__table__col-4-num"><caption>Table caption<span class="qld__caption">Table is ordered by</span></caption>
<thead>
<tr>
<th rowspan="2" scope="col">Header</th>
<th colspan="3"
class="qld__table__cell-left-border qld__table__cell--middle">Header</th>
</tr>
<tr>
<th scope="col" class="qld__table__cell-left-border">Header</th>
<th scope="col" class="qld__table__cell-left-border">Header</th>
<th scope="col" class="qld__table__cell-left-border qld__table__cell--numeric">Number %</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>5</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>10</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>15</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>20</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
<td>25</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
</tr>
</tfoot>
</table>
</div>
Usage guidelines
When to use
- Displaying structured data, where each item has multiple properties or attributes.
- Comparing and contrasting multiple data points.
- When listing locations or resources that have similarly structured content for many items (US Government, 2022).
When not to use
- Presenting a small number of items with only one or two properties
- Don’t create a table for only one or two items. Report them in the body of the text instead (Australian Government, 2022).
- Displaying data that's better suited for visualisation, such as charts or graphs
- Don’t make tables with other tables inside them (known as ‘nested’ tables) (Australian Government, 2022).
- Tables shouldn't be used for layout purposes. Use Cascading Style Sheets (CSS) for layout. If there are already layout tables present, don’t use structural elements (like
<th>or<caption>) and attributes discussed in this tutorial, and do addrole="presentation"to the<table>element (WebAIM ,2018). - Long-form content. Table cell content should be brief and scannable. If you find yourself drafting multiple bullet points or paragraphs within a single table cell, the content is likely better off under conventional page headers or in an accordion.
- Groups of items with different structures.
How to use
Some people will look at tables before they read the text. For this reason, design tables so they're self-explanatory. You must still refer to the table to in the body of the text. Place the table immediately after the reference to it in the text (Australian Government, 2022).
You must give a table:
- a title (also called a caption)
- row and column headings
- information (entries)
- a cross-reference in the text.
You may also need to add notes below the table to help users understand the information and where it comes from.
Do
- Align text to the left and numeric data to the right (in left-to-right languages).
- The first column should be a human-readable record identifier instead of a “mystery meat” automatically generated ID (Laubheimer, 2022). This design will allow users to scan and locate a record of interest.
- Ensure the default order of the columns reflects the importance of the data. Once a user has located a potential record of interest, don’t force them to move their eyes back and forth between column 1 and column 20 because those are the most relevant columns (Laubheimer, 2022).
- Keep it simple, complex tables are more work for content creators as well as being harder to interpret for users. It’s usually better to break up complex tables into simple individual tables, each containing the data for one sub-topic (US Government, 2022).
- Keep the number of columns to a minimum as its easier for users to read down a long list of rows than it is to read across a long list of columns (US Government, 2022).
Don't
- Rely on colour as the only visual means of conveying information in tables.
- Leave cells empty. Use ‘zero’ or ‘nil’ or 'n/a' where there is no data. If it's numeric data, use the numeric zero (0). Only use zero if that is the true value.
- Do not to vary units or formatting within the same column (US Government, 2022).
Tips
For more detailed guidelines on table content see Australian Government Style manual for table design.
For more table design tips see W3C Table tips and ticks.