Table β
A Table is a structural component used to arrange data in rows and columns to facilitate the comparison, analysis and management of information.
Athlete | Nation | Rank | Time |
---|---|---|---|
Ken McArthur | South Africa | 1 | 2:36:54.8 |
Christian Gitsham | South Africa | 2 | 2:37:52.0 |
Gaston Strobino | United States | 3 | 2:38:42.4 |
Shizo Kanakuri | Japan | 36 | 54:08:06:05:32:20.3 |
Name | Value |
---|---|
Props | |
caption | |
hideCaption | |
useRowHeaders | |
showVerticalBorders | |
Slots | |
header | |
footer | |
View | |
Reading direction |
Overview β
When to use Table β
The content within a Table needs to be well-structured and optimized for readability and scanning. Tables should be avoided if there is limited space, if the information is too complex, or if the data cannot be easily categorized. Also, consider different presentations for standalone information, or when detailed analysis isn't the primary goal.
Use the Table component when:
- Users need a systematic representation of information that allows them to compare and analyze multiple data points across different categories.
- Users need to perform specific actions to modify items within a dataset, such as editing, deleting, or organizing.
- Users need to sort or filter data.
Use lists, Cards, or text when or other simple layouts when:
- There aren't multiple data points to compare.
- The information doesn't require sorting or filtering.
Use charts or other data visualization methods when:
- The primary goal is to provide a high-level overview rather than detailed analysis of the data.
- The data can't easily be laid out in a Table (e.g. when there are interdependencies between data points).
About Table β
Table includes the following elements.
Header (optional) β
Tables can feature a header section with elements such as a visible caption or actions that can be applied to Table rows in bulk.
Caption β
A caption provides a clear and concise description of the contents and the purpose of the Table. It is important for accessibility, and must always be provided for users of assistive technology. The caption can be visually hidden if a visible caption is not needed (e.g. if there is a heading above the Table that serves as a title).
- A Table's caption should identify its content and context in a concise manner.
Actions (optional) β
Actions that can be applied to all the items within a Table should be made available from the header.
- Use normal or quiet Buttons to represent Table actions.
- Use MenuButton to group and display table actions when space in the header is limited.
- Don't use primary Buttons to represent Table actions, since they could compete with main page actions.
Avoid using Table actions in the header for Tables with 5 rows or fewer. Instead, use inline actions.
Row selection (optional) β
Row selection allows users to target the items that will be affected by Table actions. A custom indicator of the number of selected rows can be included in the Tableβs header for visibility (Refer to the row selection demo).
Headings β
Tables can feature column headings, row headings, or both. Headings are used to describe the type of information or the category of the data contained by the list of elements they label. Column headings are required.
- Always include column headings.
- Don't use icons as column headings.
Sorting (optional) β
Sorting allows users to organize data according to specific criteria (e.g. alphabetically). It facilitates the analysis of data, identification of patterns, and comparison of values within Tables.
Table data β
Table cells are individual units of information, organized at the intersection of rows and columns. They can contain any sort of content, from simple text to iconography, images and components in any necessary order or combination.
Tables can also features a <tfoot>
at the end of the data for things like totals.
- By default, align cell content to the start of the cell. For cells containing numbers that need to be compared, like currencies, align the text to the right of the cell in both reading directionalities.
- Match the alignment of column headings with their data.
- Add vertical borders to Table data if needed for better readability.
Pagination (optional) β
Pagination controls can be included to allow users to page through long datasets. Pagination can be placed above the Table data, below it, or both.
- Don't use pagination if all rows can easily be displayed on one page.
Footer (optional) β
Tables can feature fully customizable footer content.
Learn more about tables
- Web Typography: Designing Tables to be Read, Not Looked At by Richard Rutter
- Inclusive Components: Data Tables, by Heydon Pickering
Examples β
Column sizing β
By default, the width of each Table column will be determined by its content and the available space. If needed, you can set specific widths on some or all columns.
Wave | Years | Overview | Main figures |
---|---|---|---|
First wave | Late 19th to early 20th century | Focused on women's suffrage and legal rights, addressing inequalities in the public sphere. | Susan B. Anthony, Elizabeth Cady Stanton |
Second wave | 1960s to 1980s | Centered on women's liberation and social equality, addressing issues such as reproductive rights, workplace discrimination, and sexual liberation. | Betty Friedan, Gloria Steinem, Simone de Beauvoir |
Third wave | 1990s to early 2000s | Emphasized diversity and intersectionality, addressing issues of race, class, sexuality, and gender identity. Advocated for inclusivity and challenging stereotypes. | bell hooks, KimberlΓ© Crenshaw, Judith Butler |
Fourth wave | Early 2010s to present | Characterized by a focus on the empowerment of women through the use of internet tools, and intersectionality. The fourth wave seeks greater gender equality by focusing on gendered norms and the marginalization of women in society. | Tarana Burke, Chimamanda Ngozi Adichie, Roxane Gay |
Developer notes
The TableColumn type has optional properties for width
and minWidth
so you can customize each column's size. Include the units, e.g. '120px'
or '100%'
.
Custom cell content β
By default, the data provided for a cell will be rendered within it as-is. If needed, you can customize the contents of a whole column or individual cells. For example, you can include a MenuButton of actions to take on that row.
Timestamp | Target | Block parameters | Actions |
---|---|---|---|
16:58, 2023-11-30 | Username1 |
| |
15:16, 2023-11-23 | Username2 |
| |
11:13, 2023-11-12 | Username3 |
|
Developer notes
You can customize the contents of a cell by using the item-[ columnId ]
slots. For example, for a column with the id time
, there is a slot called item-time
. This slot comes with 2 bindings:
item
: the cell contentrow
: data for the entire row
Custom table elements β
The Table component outputs each section of the <table>
element automatically. You can override the output of these elements to customize them. In this example, there is special formatting for the "users" column headings, plus a "total" section that displays sums at the bottom.
Project | No. of wikis | Users | |
---|---|---|---|
Active | All | ||
wikipedias | 342 | 292249 | 113556337 |
wiktionaries | 193 | 5764 | 7275027 |
wikiquotes | 96 | 2042 | 4261041 |
Total: | 631 | 300055 | 125092405 |
Developer notes
You can further customize the layout of your Table by using the thead
, tbody
, and tfoot
slots. Using these slots will override the default implementation of that element within the Table component so you can include your own markup. This example uses the thead
slot to add th
elements with custom colspan
and rowspan
attributes, and the tfoot
slot to add a <tfoot>
with totals below the <tbody>
.
You can use any combination of these slots. Note that in the example below, even though we are including custom thead
markup, we are still passing in the columns
prop so that the Table component can output the data
in the <tbody>
. Always pass in columns
, unless you are using the slots to override both the <thead>
and <tbody>
.
Cell data is aligned to the start of the cell by default. You can use the following CSS classes to change the alignment of cell data:
cdx-table__table__cell--align-center
: Align content to the center of the cell.cdx-table__table__cell--align-end
: Align content to the end of the cell (to the right in LTR and to the left in RTL).cdx-table__table__cell--align-number
: Align content to the right of the cell in both reading directionalities. This is recommended for columns that contain numerical values.
Sorting β
Any number of columns can be made sortable.
Username1 | de.wikipedia | Bahnstromleitung | 06:12, 2023-12-28 | +9 |
Username2 | commons.wikimedia | Xanthium.jpg | 11:12, 2024-01-02 | -70 |
Username3 | de.wikipedia | Berlin | 16:58, 2024-01-04 | +652 |
Username4 | en.wikipedia | Stability Model | 16:25, 2023-12-14 | +42 |
Developer notes
To enable sorting, pass in the sort
prop via v-model
, and make at least one Table column sortable by adding allowSort: true
to its definition.
You can initialize the sort
ref to an empty object if there is no initial sort order, or to an initial sort order as in the Table below, where the initial sort order is { user: 'asc' }
.
Row selection β
Rows can be made selectable. This is useful for selecting rows then choosing a Table action.
Name | Status | English verb to agent noun | |
---|---|---|---|
"illustrate" -> "illustrator" | Connected | Failed | |
"listen" -> "listener" | Connected | Passed | |
"mentor" -> "mentor" | Connected | Passed | |
"swim" -> "swimmer" | Connected | Failed |
Developer notes
To enable row selection, set the useRowSelection
prop to true
, and use v-model
to bind the selectedRows
prop.
Row selection and sort β
Status | English verb to agent noun | ||
---|---|---|---|
"illustrate" -> "illustrator" | Connected | Failed | |
"listen" -> "listener" | Connected | Passed | |
"mentor" -> "mentor" | Connected | Passed | |
"swim" -> "swimmer" | Connected | Failed |
Developer notes
To use both row selection and sorting, you must add a unique identifier to each row:
- Import the
TableRowIdentifier
constant from Codex - Add a property to each row object keyed on
TableRowIdentifier
with a unique ID, e.g.[ TableRowIdentifier ]: 'Q123'
Pagination β
When pagination is enabled, the pager elements will display below the <table>
by default, but can also be displayed above it or in both locations.
Record Name | Record ID |
---|---|
AAAAA | 1001 |
BBBBB | 1002 |
CCCCC | 1003 |
DDDDD | 1004 |
EEEEE | 1005 |
FFFFF | 1006 |
GGGGG | 1007 |
HHHHH | 1008 |
IIIII | 1009 |
JJJJJ | 1010 |
Developer notes
To enable pagination, set the paginate
prop to true. The pagination interface will display below the <table>
by default, but the controls can also be moved to the top (or shown in both places at once) via the paginationPosition
prop.
Additional configuration is also possible. A paginationSizeOptions
prop can be used to provide different options for the number of rows to display per page, and paginationSizeDefault
can set the default number of rows that are displayed prior to the user making a selection. By default, a paginated Table will show 10 results per page and will allow the user to choose between page sizes of 10, 20, and 50.
Empty state β
An empty state message can be displayed via the empty-state
slot.
There is no data available |
Developer notes
If the empty-state
slot is populated, this slot will automatically display the slot content when there are no items in the data
array and the tbody
slot is not overridden.
Technical implementation β
Vue usage β
Props β
Prop name | Description | Type | Default |
---|---|---|---|
caption (required) | Table caption. Required to support users of assistive technology, but can be visually hidden. | string | |
hideCaption | Whether to visually hide the caption. | boolean | false |
columns | Column definitions. | TableColumn[] | [] |
data | Table data. An array of objects, with each object representing the data for a table row. Item keys should align with column IDs, as defined in the columns prop. | TableRow[]|TableRowWithIdentifier[] | [] |
useRowHeaders | Whether to use <th> for the first cell in each row. | boolean | false |
showVerticalBorders | Whether vertical borders separating columns should be rendered. | boolean | false |
useRowSelection | Whether to enable row selection. | boolean | false |
selectedRows | An array of selected row indices. Must be bound with v-model:selected-rows .If sorting is also enabled, this will be an array of TableRowIdentifiers. | (number|string)[] | [] |
sort | Definition of sort order. Column(s) can be sorted ascending, descending, or not sorted. To display data unsorted initially, set to an empty object initially. Must be bound with v-model:sort | TableSort | {} |
pending | Whether the table is waiting for data to be fetched. | boolean | false |
paginate | Whether to enable pagination. | boolean | false |
serverPagination | Whether the table is paginating through remote data. Setting this to "true" will cause the table to emit events indicating that more data should be loaded when the user navigates between pages. | boolean | false |
totalRows | The total number of rows/results available on the server that the user can access via pagination. Providing this value will make for a better user experience when navigating through pages of remote data, but it is not required. | number | NaN |
paginationPosition | Where the pagination controls should appear relative to the table body. | TablePaginationPosition | 'bottom' |
paginationSizeOptions | Pre-defined options for how may rows should be displayed per page. The value of these menu items must be a number. | TablePaginationSizeOption[] | [ { value: 10 }, { value: 20 }, { value: 50 } ] |
paginationSizeDefault | The default number of rows to show per page. For basic pagination, this will default to the value of the first of the pagination options if not provided. For server-side pagination, this will default to the initial number of rows if no default is provided. | number | paginationSizeOptions[ 0 ].value |
Events β
Event name | Properties | Description |
---|---|---|
update:selectedRows | selectedRows string[] - The new selected rows. | When the selected row(s) changes. |
update:sort | sort Object - The new sort order. | When the sort order changes emit an event to update the sort order. |
load-more | offset number - Index of the first visible row on the new page. rows number - Number of rows to display. | When the user requests another page of data from the server. |
last | rows number - Number of rows to display. | When the user requests the last page of data from the server. |
Slots β
Name | Description | Bindings |
---|---|---|
header | Header content. Not to be confused with <thead>; use the thead slot to customize that. | |
thead | Custom <thead>. | |
tbody | Custom <tbody>. | |
'item-' + column.id | Table cell content, per column. | item any - Data for the cellrow TableRow, TableRowWithIdentifier - Data for the row |
empty-state | Empty state content. | |
tfoot | Custom <tfoot>. | |
footer | Footer content. Not to be confused with <tfoot>; use the tfoot slot to add that. |
CSS-only version β
Markup structure β
The CSS-only Table consists of a <table>
element and its child elements, plus some wrapper elements and CSS classes needed to ensure proper styles and accessibility. Refer to the code sample below for details.
Cell data is aligned to the start of the cell by default. You can use the following CSS classes to change the alignment of cell data:
cdx-table__table__cell--align-center
: Align content to the center of the cellcdx-table__table__cell--align-end
: Align content to the end of the cell (to the right in LTR and to the left in RTL)cdx-table__table__cell--align-number
: Align content to the right of the cell in both reading directionalities. This is recommended for columns that contain numerical values.
Note that all cells in a column, including the <th>
in the <thead>
, should have the same text alignment.
Athlete | Nation | Rank | Time |
---|---|---|---|
Ken McArthur | South Africa | 1 | 2:36:54.8 |
Christian Gitsham | South Africa | 2 | 2:37:52.0 |
Gaston Strobino | United States | 3 | 2:38:42.4 |
Shizo Kanakuri | Japan | 36 | 54:08:06:05:32:20.3 |
Visually hidden caption β
To visually hide the header's caption, simply do not add it to the header element (<div class="cdx-table__header">
). If you have no other header content, the entire header element can be removed, as in the example below. Make sure to always include the <caption>
element inside the <table>
, which is visually hidden by default.
Project | No. of wikis | Active users | All users |
---|---|---|---|
wikipedias | 342 | 292249 | 113556337 |
wiktionaries | 193 | 5764 | 7275027 |
wikiquotes | 96 | 2042 | 4261041 |
Total: | 631 | 300055 | 125092405 |
Vertical borders β
To display vertical borders that separate the columns, apply the cdx-table__table--borders-vertical
class to table element. This class may not cover all use cases, therefore apply additional border styles to the element as needed.
Project | No. of wikis | Users | |
---|---|---|---|
Active | All | ||
wikipedias | 342 | 292249 | 113556337 |
wiktionaries | 193 | 5764 | 7275027 |
wikiquotes | 96 | 2042 | 4261041 |
Total: | 631 | 300055 | 125092405 |
Row headers β
In some cases, header information can be found in the top row and first column. All header cells are marked up as th
elements with the appropriate scope
attribute. The scope attribute helps to describe the relationship between header and data cells. Refer to WAI to learn more about Table header row and header column.
Project | No. of wikis | Users | |
---|---|---|---|
Active | All | ||
wikipedias | 342 | 292249 | 113556337 |
wiktionaries | 193 | 5764 | 7275027 |
wikiquotes | 96 | 2042 | 4261041 |
Total: | 631 | 300055 | 125092405 |
With row selection β
Row selection can be done without JavaScript by following these steps:
- Use a
<form>
element as the outermost element with the classcdx-table
- Add a submit button to the header to handle the row selection data
- Omit the "select all" checkbox in the
<thead>
- Give each row's checkbox the same
name
and a uniquevalue
Note that the Table below doesn't actually do anything when you click "Sign up" besides submit the form and reload the page.
Empty state β
You can use the CSS classes, cdx-table__table__empty-state
and cdx-table__table__empty-state-content
, to style the empty state message that indicates that there's no data available. The <td>
element here should also have a colspan
attribute with a value equal to the number of columns in the table, but this can be omitted if the table only has a single column.
There is no data available |
Pagination β
This example demonstrates the markup structure that should be used for visual parity with the Vue.js version of the paginated Table component. In a real-world scenario, the <form>
action
and <button>
values will need to be set in a way that corresponds with whatever back-end is being used. Typical usage will involve a GET request to the URL specified in the form action
, with the select and button values mapped to specific URL parameters.
Buttons for first, next, previous, and last pages use the cdx-button--icon-only
class. The icon images are added automatically.
Team | Driver One | Driver Two | Constructors' Points |
---|---|---|---|
Mercedes | Lewis Hamilton | George Russell | 213 |
Red Bull | Max Verstappen | Sergio Perez | 234 |
McLaren | Lando Norris | Oscar Piastri | 123 |
Ferrari | Carlos Sainz | Charles Leclerc | 100 |
Alpine | Esteban Ocon | Pierre Gasly | 85 |
Alfa Romeo | Valtteri Bottas | Guanyu Zhou | 60 |
Aston Martin | Fernando Alonso | Lance Stroll | 95 |
Haas | Kevin Magnussen | Mick Schumacher | 50 |
Williams | Alexander Albon | Logan Sargeant | 30 |
AlphaTauri | Yuki Tsunoda | Nyck de Vries | 40 |
Keyboard navigation β
Key | Function |
---|---|
Tab | It moves the focus to the next interactive element within the Table. |
Shift+Tab | It moves the focus to the previous interactive element within the Table. |
Up arrow, Down arrow | For assistive technology users, these keys move between the column cells. |
Left arrow, Right arrow | For assistive technology users, these keys move between the row cells. |