Tables provide a structured way to present data, allowing users to view and compare information easily.
Rows and columns make it easy to compare information, and you can add headers to give users a quick overview of each section. With several configuration options, you have precise control over how the table behaves.
When to use this component
Use a table when you have large sets of data that need to be displayed in an organised, easy-to-read format. This helps users compare and analyse information quickly without feeling overwhelmed by cluttered content. Aim to include clear headers and consistent formatting to make the data easy to navigate.
For smaller sets of data, or content that doesn't require a grid structure, consider using lists or simple text displays instead.
Tables are also ideal for presenting structured information that benefits from sorting, filtering, or pagination, as they provide an efficient way to manage and display large amounts of content without overwhelming the page.
Examples in GOSS products
- The default table layout when you create a table in the article editor
- The summary tables generated by the HTML fields in the forms designer
- In Self-Service, Assisted Service, and Task Management to display users and their associated tasks
Accessibility considerations
When creating tables, it's essential to make them accessible to all users, especially those using assistive technologies. Ensure that the table has clear headings for rows and columns, so users can easily understand the context of the data. Adding a brief description or summary of the table's content helps users quickly grasp its purpose. Grouping the table's content logically also makes it easier for everyone to navigate.
It's also important to make tables easy to navigate with a keyboard, allowing users to move through the data using arrow keys. Avoid using tables for layout purposes—only use them to present data. If the table is part of a form, provide clear instructions and error handling to guide users.
Basic table
A table with no additional styling, displaying a typical data collection in rows and columns.
n | n2 | n3 | n4 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 4 | 8 | 16 |
3 | 9 | 27 | 81 |
<table style="width: 100%">
<caption>
Caption goes here
</caption>
<thead>
<tr>
<th><em>n</em></th>
<th><em>n</em><sup>2</sup></th>
<th><em>n</em><sup>3</sup></th>
<th><em>n</em><sup>4</sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
<td>16</td>
</tr>
<tr>
<td>3</td>
<td>9</td>
<td>27</td>
<td>81</td>
</tr>
</tbody>
</table>
No border
A table with no border CSS modifier, displaying a data in rows and columns.
<table class="tablenoborder">...</table>
This format is ideal for layouts where the focus is on the content rather than the structure, and it works well when you want to create a subtle, seamless integration of the table into the design.
n | n2 | n3 | n4 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 4 | 8 | 16 |
3 | 9 | 27 | 81 |
<table class="tablenoborder" style="width: 100%">
<caption>
Caption goes here
</caption>
<thead>
<tr>
<th><em>n</em></th>
<th><em>n</em><sup>2</sup></th>
<th><em>n</em><sup>3</sup></th>
<th><em>n</em><sup>4</sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
<td>16</td>
</tr>
<tr>
<td>3</td>
<td>9</td>
<td>27</td>
<td>81</td>
</tr>
</tbody>
</table>
Dark
A table with dark CSS modifier.
<table class="tabledark">...</table>
This format is ideal for layouts where the content needs to stand out, creating a stylish contrast while keeping the focus on the data rather than the table structure.
n | n2 | n3 | n4 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 4 | 8 | 16 |
3 | 9 | 27 | 81 |
<table class="tabledark" style="width: 100%">
<caption>
Caption goes here
</caption>
<thead>
<tr>
<th><em>n</em></th>
<th><em>n</em><sup>2</sup></th>
<th><em>n</em><sup>3</sup></th>
<th><em>n</em><sup>4</sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
<td>16</td>
</tr>
<tr>
<td>3</td>
<td>9</td>
<td>27</td>
<td>81</td>
</tr>
</tbody>
</table>
Light
A table with light CSS modifier.
<table class="tablelight">...</table>
This format is ideal for layouts where the content needs to be easily readable against a lighter background, offering a subtle yet effective contrast while keeping the focus on the data.
n | n2 | n3 | n4 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 4 | 8 | 16 |
3 | 9 | 27 | 81 |
<table class="tablelight" style="width: 100%">
<caption>
Caption goes here
</caption>
<thead>
<tr>
<th><em>n</em></th>
<th><em>n</em><sup>2</sup></th>
<th><em>n</em><sup>3</sup></th>
<th><em>n</em><sup>4</sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
<td>16</td>
</tr>
<tr>
<td>3</td>
<td>9</td>
<td>27</td>
<td>81</td>
</tr>
</tbody>
</table>
Primary
A table with primary CSS modifier.
<table class="tableprimary">...</table>
This format is ideal for layouts where the brand's colour scheme should be integrated into the design, ensuring the table blends with the overall look while keeping the focus on the content.
n | n2 | n3 | n4 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 4 | 8 | 16 |
3 | 9 | 27 | 81 |
<table class="tableprimary" style="width: 100%">
<caption>
Caption goes here
</caption>
<thead>
<tr>
<th><em>n</em></th>
<th><em>n</em><sup>2</sup></th>
<th><em>n</em><sup>3</sup></th>
<th><em>n</em><sup>4</sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
<td>16</td>
</tr>
<tr>
<td>3</td>
<td>9</td>
<td>27</td>
<td>81</td>
</tr>
</tbody>
</table>
Secondary
A table with secondary CSS modifier.
<table class="tablesecondary">...</table>
This format is ideal for layouts where the brand's secondary colour can be used to create a cohesive look, providing contrast and focus without overwhelming the content.
n | n2 | n3 | n4 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 4 | 8 | 16 |
3 | 9 | 27 | 81 |
<table class="tablesecondary" style="width: 100%">
<caption>
Caption goes here
</caption>
<thead>
<tr>
<th><em>n</em></th>
<th><em>n</em><sup>2</sup></th>
<th><em>n</em><sup>3</sup></th>
<th><em>n</em><sup>4</sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
<td>16</td>
</tr>
<tr>
<td>3</td>
<td>9</td>
<td>27</td>
<td>81</td>
</tr>
</tbody>
</table>
Horizontal
A table with horizontal CSS modifier.
<table class="tablehorizontal">...</table>
This format is ideal for layouts where a horizontal structure works better for comparing data across multiple categories, offering a more intuitive view without cluttering the design.
n | n2 | n3 | n4 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 4 | 8 | 16 |
3 | 9 | 27 | 81 |
<table class="tablehorizontal" style="width: 100%">
<caption>
Caption goes here
</caption>
<thead>
<tr>
<th><em>n</em></th>
<th><em>n</em><sup>2</sup></th>
<th><em>n</em><sup>3</sup></th>
<th><em>n</em><sup>4</sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
<td>16</td>
</tr>
<tr>
<td>3</td>
<td>9</td>
<td>27</td>
<td>81</td>
</tr>
</tbody>
</table>
Case management
A table with case management CSS modifier.
<table class="tablecm">...</table>
This format is ideal for layouts where you need to organise and display case-related data in a way that is easy to navigate, providing a clear overview of key information and ensuring quick access to important details.
n | n2 | n3 | n4 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 4 | 8 | 16 |
3 | 9 | 27 | 81 |
<table class="tablecm" style="width: 100%">
<caption>
Caption goes here
</caption>
<thead>
<tr>
<th><em>n</em></th>
<th><em>n</em><sup>2</sup></th>
<th><em>n</em><sup>3</sup></th>
<th><em>n</em><sup>4</sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>8</td>
<td>16</td>
</tr>
<tr>
<td>3</td>
<td>9</td>
<td>27</td>
<td>81</td>
</tr>
</tbody>
</table>
Form data
A table with form data CSS modifier.
<div class="icmformdata">
<table class="icmformdatapagetable">...</table>
</div>
This format is perfect for layouts where each row contains a label paired with its corresponding value, making it easy to read and understand the data, especially in forms or detailed records.
Title of the section | |
---|---|
Label | Value of the label |
Label | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus at feugiat est. Nam eleifend libero metus, maximus aliquam tortor rutrum ac. Ut gravida ligula massa, nec pulvinar nulla fermentum ut. Pellentesque in dui nec tellus tristique tincidunt. Nunc vel ipsum ultricies, venenatis sapien at, porttitor tellus. |
<div class="icmformdata">
<table class="icmformdatapagetable">
<tbody>
<tr>
<th colspan="2" class="icmformdatacontainer">Title of the section</th>
</tr>
<tr>
<td class="icmformdatalabel">Label</td>
<td class="icmformdatavalue">Value of the label</td>
</tr>
<tr>
<td class="icmformdatalabel">Label</td>
<td class="icmformdatavalue">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus at feugiat est. Nam eleifend libero metus, maximus aliquam tortor rutrum ac. Ut gravida ligula massa, nec pulvinar nulla fermentum ut. Pellentesque in dui nec tellus tristique tincidunt. Nunc vel ipsum ultricies, venenatis sapien at, porttitor tellus.</td>
</tr>
</tbody>
</table>
</div>
Data table
A table with datatable CSS modifier.
<div class="datatable">
<table aria-colcount="4" aria-describedby="example-table-example" aria-label="Example datatable example" aria-rowcount="124" class="datatable__content" data-async-sorting="true" data-loaded="true" data-page="1" data-page-size="2" data-total="8" data-url="#" id="tasks_example" role="grid">...</table>
</div>
By adding the data table CSS modifier on the table, it can be used when you want to present information in a structured, accessible format with features that enhance usability, such as sorting, paging, and improved accessibility for screen readers.
This format offers several benefits, including:
- aria-colcount and aria-rowcount for defining the number of columns and rows, improving accessibility
- aria-describedby and aria-label for providing context to screen readers
- data-async-sorting for enabling dynamic sorting of table data
- data-loaded, data-page, data-page-size, and data-total for managing pagination and displaying a specific set of results per page
This layout is ideal for presenting large datasets in a way that's both accessible and easy to navigate, allowing users to quickly find the information they need while ensuring an inclusive user experience.
Note that this example just shows the styling, it doesn't include the functionality needed to perform the sorting.
Header link with no sort | Header with no link | Header link with descending sort | Header link with descending sort |
---|---|---|---|
Example text | Example text | NVP example with text Example text | 29 June 2021 12:25:57 |
Example text | Example text | NVP example with text Example text | 29 June 2021 12:25:57 |
Example text | Example text | NVP example with text Example text | 29 June 2021 12:25:57 |
Example text | Example text | NVP example with text Example text | 29 June 2021 12:25:57 |
Example text | Example text | NVP example with text Example text | 29 June 2021 12:25:57 |
Example text | Example text | NVP example with text Example text | 29 June 2021 12:25:57 |
Example text | Example text | NVP example with text Example text | 29 June 2021 12:25:57 |
Example text | Example text | NVP example with text Example text | 29 June 2021 12:25:57 |
Example text disabled | Example text disabled | NVP example with text disabled Example text | 29 June 2021 12:25:57 |
<div class="datatable">
<table
aria-colcount="4"
aria-describedby="example-table-example"
aria-label="Example datatable example"
aria-rowcount="124"
class="datatable__content"
data-async-sorting="true"
data-loaded="true"
data-page="1"
data-page-size="2"
data-total="8"
data-url="#"
id="tasks_example"
role="grid"
>
<thead>
<tr>
<th class="datatable__heading">
<a
class="datatable__sort"
href="#"
data-sort-field="header-no-description"
data-sort-order="NONE"
role="button"
tabindex="0"
>Header link with no sort</a
>
</th>
<th
class="datatable__heading"
tabindex="-1"
>
Header with no link
</th>
<th class="datatable__heading">
<a
class="datatable__sort datatable__sort--desc"
href="#"
data-sort-field="header-desc"
data-sort-order="DESC"
role="button"
tabindex="-1"
>Header link with descending sort</a
>
</th>
<th class="datatable__heading">
<a
class="datatable__sort datatable__sort--asc"
href="#"
data-sort-field="head-asc"
data-sort-order="ASC"
role="button"
tabindex="-1"
>Header link with descending sort</a
>
</th>
</tr>
</thead>
<tbody aria-live="polite">
<tr class="datatable__row">
<td class="datatable__cell" tabindex="-1">
Example text
</td>
<td class="datatable__cell">
Example text
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date " tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
<tr class="datatable__row">
<td class="datatable__cell" tabindex="-1">
Example text
</td>
<td class="datatable__cell">
Example text
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date " tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
<tr class="datatable__row">
<td class="datatable__cell" tabindex="-1">
Example text
</td>
<td class="datatable__cell">
Example text
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date " tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
<tr class="datatable__row">
<td class="datatable__cell" tabindex="-1">
Example text
</td>
<td class="datatable__cell">
Example text
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date " tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
<tr class="datatable__row">
<td class="datatable__cell" tabindex="-1">
Example text
</td>
<td class="datatable__cell">
Example text
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date " tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
<tr class="datatable__row">
<td class="datatable__cell" tabindex="-1">
Example text
</td>
<td class="datatable__cell">
Example text
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date " tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
<tr class="datatable__row">
<td class="datatable__cell" tabindex="-1">
Example text
</td>
<td class="datatable__cell">
Example text
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date " tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
<tr class="datatable__row">
<td class="datatable__cell" tabindex="-1">
Example text
</td>
<td class="datatable__cell">
Example text
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date " tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
<tr class="datatable__row" disabled="true">
<td class="datatable__cell" tabindex="-1">
Example text disabled
</td>
<td class="datatable__cell">
Example text disabled
</td>
<td class="datatable__cell" tabindex="-1">
<span class="nvp">
<span class="nvp__label">
NVP example with text disabled
</span>
<span class="nvp__value">
Example text
</span>
</span>
</td>
<td class="datatable__cell datatable__cell--date" tabindex="-1">
<span class="nvp">
<span class="nvp__value">
<span class="nvp__date">29 June 2021</span>
<span class="nvp__time">12:25:57</span>
</span>
</span>
</td>
</tr>
</tbody>
</table>
</div>