Table
About
What does it do?
- A table is used to make information easier for users to compare and scan
When to use it?
- Use the table component to let users compare information in rows and columns.
When not to use it?
- Never use the table component to layout content on a page. Instead, use the grid system.
How it works
- You need to create a heading (title) for the table using
<caption>
tags. A caption helps users find, navigate and understand tables. - Use table headers to tell users what the rows and columns represent. Use the scope attribute to help users of assistive technology distinguish between row and column headers.
- When comparing columns of numbers, align the numbers to the right in table cells.
- If you are trying to display lots of columns, contact Design Team to discuss how best to achieve this.
Table with Headers
Header 1 | Header 2 | Header 3 |
---|---|---|
Cell 1 | Cell 2 | Cell 3 |
Cell 1 | Cell 2 | Cell 3 |
HTML markup
<table class="wmnds-table">
<h3>
Table title
</h3>
<caption class="wmnds-table__caption">
Table caption
</caption>
<thead>
<tr>
<th scope="col">Header 1</th>
<th scope="col">Header 2</th>
<th scope="col">Header 3</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" data-header="Header 1">
Cell 1
</th>
<td data-header="Header 2">
Cell 2
</td>
<td data-header="Header 3">
Cell 3
</td>
</tr>
<tr>
<th scope="row" data-header="Header 1">
Cell 1
</th>
<td data-header="Header 2">
Cell 2
</td>
<td data-header="Header 3">
Cell 3
</td>
</tr>
</tbody>
</table>
Nunjucks markup
{% from "wmnds/components/table/_table.njk" import wmndsTable %}
{{
wmndsTable(
{
caption: "Table Caption",
title: "Table Title",
firstCellIsHeader: true,
classes: "wmnds-m-b-xl",
rows: [
[
{
contentText: "Cell 1",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Cell 2",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Cell 3",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
}
],
[
{
contentText: "Cell 1",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Cell 2",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Cell 3",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
}
]
],
head: [
{
contentText: "Header 1",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Header 2",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Header 3",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
}
],
hideHeader: false
})
}}
Nunjucks properties
Name | Type | Description |
---|---|---|
caption | string | Caption text |
title | string | Table title (displayed as h3) |
firstCellIsHeader | boolean | If set to false , first cell in table row will be a td instead of a th . Default value is true |
classes | string | Additional classes to add to the table container. |
rows | array | Required. Array of table rows and cells. See options for rows below. |
head | array | Array of table head cells. See options for head below. Will not show if hideHeader is true. |
hideHeader | boolean | Determines whether to display a table header row (thead ) at the top of the table. Set to false by default. |
Options for rows
Name | Type | Description |
---|---|---|
contentText | string | Required. If html is set, this is not required. Text for cells in table rows. If html is provided, the contentText argument will be ignored. |
contentHTML | string | Required. If contentText is set, this is not required. HTML for cells in table rows. If contentHTML is provided, the contentText argument will be ignored |
classes | string | Additional classes to add to the table row cell. |
colspan | integer | Specify how many columns a cell extends. |
rowspan | integer | Specify how many rows a cell extends. |
Options for head
Name | Type | Description |
---|---|---|
contentText | string | Required. Text for cells in table head. If contentHTML is provided, the contentText argument will be used for mobile headers. |
contentHTML | string | Required. If contentText is set, this is not required. HTML for cells in table rows. If contentHTML is provided, the contentText argument will be ignored |
classes | string | Additional classes to add to the table row cell. |
colspan | integer | Specify how many columns a cell extends. |
rowspan | integer | Specify how many rows a cell extends. |
Recommended javascript (browser compatible)
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var tableJS = function tableJS() {
var tables = document.querySelectorAll('.wmnds-table');
var getTableHeadChildren = function getTableHeadChildren(table) {
var tHeadChildren = table.querySelectorAll('thead tr > *'); // Using querySelectorAll as it has a fallback of an empty node list. Using children returns HTMLCollection which we can't forEach through.
return tHeadChildren; // Return node list
};
var iterateTables = function iterateTables(table) {
var theadChildren = getTableHeadChildren(table); // Get all children from thead section
if (!theadChildren.length) return table.classList.add('wmnds-table--without-header'); // If no headers found, add without-header class
// Otherwise...
// If our node list is greater than 1, then there are headers
var tRows = table.querySelectorAll('tbody > tr'); // Get all table rows in our table body section
return tRows.forEach(function(tRow) {
var cells = tRow.querySelectorAll('td'); // Get all cells within our row
// Loop through each cell within our row...
cells.forEach(function(cell, i) {
var newCell = cell; // Map to new var to avoid mutating original
var tHeadText = theadChildren[i].innerText; // Map the index of the cell to the index of the header we want as it will be in the same column of the table
newCell.dataset.header = tHeadText; // Change the data-header on our cell to the header text so it appears on mobile
});
});
};
// START HERE
if (tables.length) tables.forEach(iterateTables);
};
var _default = tableJS();
exports["default"] = _default;
Recommended javascript (ES6)
const tableJS = () => {
const tables = document.querySelectorAll('.wmnds-table');
const getTableHeadChildren = table => {
const tHeadChildren = table.querySelectorAll('thead tr > *'); // Using querySelectorAll as it has a fallback of an empty node list. Using children returns HTMLCollection which we can't forEach through.
return tHeadChildren; // Return node list
};
const iterateTables = table => {
const theadChildren = getTableHeadChildren(table); // Get all children from thead section
if (!theadChildren.length) return table.classList.add('wmnds-table--without-header'); // If no headers found, add without-header class
// Otherwise...
// If our node list is greater than 1, then there are headers
const tRows = table.querySelectorAll('tbody > tr'); // Get all table rows in our table body section
return tRows.forEach(tRow => {
const cells = tRow.querySelectorAll('td'); // Get all cells within our row
// Loop through each cell within our row...
cells.forEach((cell, i) => {
const newCell = cell; // Map to new var to avoid mutating original
const tHeadText = theadChildren[i].innerText; // Map the index of the cell to the index of the header we want as it will be in the same column of the table
newCell.dataset.header = tHeadText; // Change the data-header on our cell to the header text so it appears on mobile
});
});
};
// START HERE
if (tables.length) tables.forEach(iterateTables);
};
export default tableJS();
Table without Headers
Cell 1 | Cell 2 |
---|---|
Cell 1 | Cell 2 |
HTML markup
<table class="wmnds-table wmnds-table--without-header">
<caption class="wmnds-table__caption">
Table Title
</caption>
<tbody>
<tr>
<th scope="row" data-header="Header 1">
Cell 1
</th>
<td data-header="Header 2">
Cell 2
</td>
</tr>
<tr>
<th scope="row" data-header="Header 1">
Cell 1
</th>
<td data-header="Header 2">
Cell 2
</td>
</tr>
</tbody>
</table>
Nunjucks markup
{% from "wmnds/components/table/_table.njk" import wmndsTable %}
{{
wmndsTable(
{
caption: "Table Caption",
title: "Table Title",
firstCellIsHeader: true,
classes: "wmnds-m-b-xl",
rows: [
[
{
contentText: "Cell 1",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Cell 2",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Cell 3",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
}
],
[
{
contentText: "Cell 1",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Cell 2",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Cell 3",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
}
]
],
head: [
{
contentText: "Header 1",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Header 2",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
},
{
contentText: "Header 3",
contentHTML: null,
classes: null,
colspan: 1,
rowspan: 1,
}
],
hideHeader: false
})
}}
Nunjucks properties
Name | Type | Description |
---|---|---|
caption | string | Caption text |
title | string | Table title (displayed as h3) |
firstCellIsHeader | boolean | If set to false , first cell in table row will be a td instead of a th . Default value is true |
classes | string | Additional classes to add to the table container. |
rows | array | Required. Array of table rows and cells. See options for rows below. |
head | array | Array of table head cells. See options for head below. Will not show if hideHeader is true. |
hideHeader | boolean | Determines whether to display a table header row (thead ) at the top of the table. Set to false by default. |
Options for rows
Name | Type | Description |
---|---|---|
contentText | string | Required. If html is set, this is not required. Text for cells in table rows. If html is provided, the contentText argument will be ignored. |
contentHTML | string | Required. If contentText is set, this is not required. HTML for cells in table rows. If contentHTML is provided, the contentText argument will be ignored |
classes | string | Additional classes to add to the table row cell. |
colspan | integer | Specify how many columns a cell extends. |
rowspan | integer | Specify how many rows a cell extends. |
Options for head
Name | Type | Description |
---|---|---|
contentText | string | Required. Text for cells in table head. If contentHTML is provided, the contentText argument will be used for mobile headers. |
contentHTML | string | Required. If contentText is set, this is not required. HTML for cells in table rows. If contentHTML is provided, the contentText argument will be ignored |
classes | string | Additional classes to add to the table row cell. |
colspan | integer | Specify how many columns a cell extends. |
rowspan | integer | Specify how many rows a cell extends. |
Recommended javascript (browser compatible)
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var tableJS = function tableJS() {
var tables = document.querySelectorAll('.wmnds-table');
var getTableHeadChildren = function getTableHeadChildren(table) {
var tHeadChildren = table.querySelectorAll('thead tr > *'); // Using querySelectorAll as it has a fallback of an empty node list. Using children returns HTMLCollection which we can't forEach through.
return tHeadChildren; // Return node list
};
var iterateTables = function iterateTables(table) {
var theadChildren = getTableHeadChildren(table); // Get all children from thead section
if (!theadChildren.length) return table.classList.add('wmnds-table--without-header'); // If no headers found, add without-header class
// Otherwise...
// If our node list is greater than 1, then there are headers
var tRows = table.querySelectorAll('tbody > tr'); // Get all table rows in our table body section
return tRows.forEach(function(tRow) {
var cells = tRow.querySelectorAll('td'); // Get all cells within our row
// Loop through each cell within our row...
cells.forEach(function(cell, i) {
var newCell = cell; // Map to new var to avoid mutating original
var tHeadText = theadChildren[i].innerText; // Map the index of the cell to the index of the header we want as it will be in the same column of the table
newCell.dataset.header = tHeadText; // Change the data-header on our cell to the header text so it appears on mobile
});
});
};
// START HERE
if (tables.length) tables.forEach(iterateTables);
};
var _default = tableJS();
exports["default"] = _default;
Recommended javascript (ES6)
const tableJS = () => {
const tables = document.querySelectorAll('.wmnds-table');
const getTableHeadChildren = table => {
const tHeadChildren = table.querySelectorAll('thead tr > *'); // Using querySelectorAll as it has a fallback of an empty node list. Using children returns HTMLCollection which we can't forEach through.
return tHeadChildren; // Return node list
};
const iterateTables = table => {
const theadChildren = getTableHeadChildren(table); // Get all children from thead section
if (!theadChildren.length) return table.classList.add('wmnds-table--without-header'); // If no headers found, add without-header class
// Otherwise...
// If our node list is greater than 1, then there are headers
const tRows = table.querySelectorAll('tbody > tr'); // Get all table rows in our table body section
return tRows.forEach(tRow => {
const cells = tRow.querySelectorAll('td'); // Get all cells within our row
// Loop through each cell within our row...
cells.forEach((cell, i) => {
const newCell = cell; // Map to new var to avoid mutating original
const tHeadText = theadChildren[i].innerText; // Map the index of the cell to the index of the header we want as it will be in the same column of the table
newCell.dataset.header = tHeadText; // Change the data-header on our cell to the header text so it appears on mobile
});
});
};
// START HERE
if (tables.length) tables.forEach(iterateTables);
};
export default tableJS();