|
| 1 | +--- |
| 2 | +title: Table Elements |
| 3 | +intro: Learn how to build accessible and responsive tables using semantic HTML and CMS Design System utility classes. |
| 4 | +--- |
| 5 | +import { Alert } from '@cmsgov/design-system' |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +The CMS Design System encourages using semantic HTML table elements (`<table>`, `<thead>`, `<caption>`, `<tbody>`, `<tr>`, `<th>`, and `<td>`) in combination with our utility CSS classes. |
| 10 | +This approach improves accessibility and supports framework-agnostic implementations. |
| 11 | + |
| 12 | +This guidance outlines how to replicate the core functionality of our React `Table` component using native HTML and Design System classes. |
| 13 | + |
| 14 | +<Alert variation="warn" heading="Deprecation Notice"> |
| 15 | + The React <code>Table</code> component will eventually be deprecated in favor of these HTML-based patterns. |
| 16 | +</Alert> |
| 17 | + |
| 18 | +### Simple Table |
| 19 | + |
| 20 | +Use a simple table when you need to display static, tabular data with a single header row and consistent column structure. |
| 21 | + |
| 22 | +#### How to build a simple table |
| 23 | + |
| 24 | +- Use the `ds-c-table` class on the `<table>` to apply base styling. |
| 25 | +- Use `ds-c-table__caption` for visible captions to provide context. |
| 26 | +- Use the `ds-u-text-align--left` class on headers and cells to apply consistent alignment. |
| 27 | +- Follow semantic HTML best practices for accessibility, such as using `<th scope="col">` for column headers and `<caption>` for context. |
| 28 | + |
| 29 | +Here’s an example: |
| 30 | +<table class="ds-c-table"> |
| 31 | + <caption class="ds-c-table__caption">Founding documents</caption> |
| 32 | + <thead role="rowgroup"> |
| 33 | + <tr role="row"> |
| 34 | + <th class="ds-u-text-align--left" role="columnheader" scope="col" id="documentTitle">Document title</th> |
| 35 | + <th class="ds-u-text-align--left" role="columnheader" scope="col" id="description">Description</th> |
| 36 | + <th class="ds-u-text-align--left" role="columnheader" scope="col" id="links">Links</th> |
| 37 | + <th class="ds-u-text-align--left" role="columnheader" scope="col" id="year">Year</th> |
| 38 | + </tr> |
| 39 | + </thead> |
| 40 | + <tbody role="rowgroup"> |
| 41 | + <tr role="row"> |
| 42 | + <td class="ds-u-text-align--left" role="cell" headers="documentTitle" data-title="Document title">Declaration of Independence</td> |
| 43 | + <td class="ds-u-text-align--left" role="cell" headers="description" data-title="Description">Statement adopted by the Continental Congress declaring independence from the British Empire.</td> |
| 44 | + <td class="ds-u-text-align--left" role="cell" headers="links" data-title="Links"> |
| 45 | + <a href="https://billofrightsinstitute.org/founding-documents/declaration-of-independence/">View</a> |
| 46 | + </td> |
| 47 | + <td class="ds-u-text-align--left" role="cell" headers="year" data-title="Year">1776</td> |
| 48 | + </tr> |
| 49 | + <tr role="row"> |
| 50 | + <td class="ds-u-text-align--left" role="cell" headers="documentTitle" data-title="Document title">Articles of Confederation</td> |
| 51 | + <td class="ds-u-text-align--left" role="cell" headers="description" data-title="Description">This document served as the United Statesʼ first constitution.</td> |
| 52 | + <td class="ds-u-text-align--left" role="cell" headers="links" data-title="Links"> |
| 53 | + <a href="https://www.archives.gov/milestone-documents/articles-of-confederation">View</a> |
| 54 | + </td> |
| 55 | + <td class="ds-u-text-align--left" role="cell" headers="year" data-title="Year">1777</td> |
| 56 | + </tr> |
| 57 | + <tr role="row"> |
| 58 | + <td class="ds-u-text-align--left" role="cell" headers="documentTitle" data-title="Document title">The Constitution</td> |
| 59 | + <td class="ds-u-text-align--left" role="cell" headers="description" data-title="Description">Replaced the Articles of Confederation with a new form of government. It created a federal system with a national government composed of 3 separated powers, and included both reserved and concurrent powers of states</td> |
| 60 | + <td class="ds-u-text-align--left" role="cell" headers="links" data-title="Links"> |
| 61 | + <a href="https://billofrightsinstitute.org/primary-sources/constitution">View</a> |
| 62 | + </td> |
| 63 | + <td class="ds-u-text-align--left" role="cell" headers="year" data-title="Year">1787</td> |
| 64 | + </tr> |
| 65 | + <tr role="row"> |
| 66 | + <td class="ds-u-text-align--left" role="cell" headers="documentTitle" data-title="Document title">Bill of Rights</td> |
| 67 | + <td class="ds-u-text-align--left" role="cell" headers="description" data-title="Description">The first ten amendments of the U.S. Constitution guaranteeing rights and freedoms.</td> |
| 68 | + <td class="ds-u-text-align--left" role="cell" headers="links" data-title="Links"> |
| 69 | + <a href="https://billofrightsinstitute.org/founding-documents/bill-of-rights/">View</a> |
| 70 | + </td> |
| 71 | + <td class="ds-u-text-align--left" role="cell" headers="year" data-title="Year">1791</td> |
| 72 | + </tr> |
| 73 | + </tbody> |
| 74 | +</table> |
| 75 | + |
| 76 | +### Multi-header Table |
| 77 | + |
| 78 | +Use a multi-header table when your data requires grouped columns with separate subheaders. |
| 79 | + |
| 80 | +#### How to build a multi-header table |
| 81 | + |
| 82 | +- To group related columns in the first header row, use `<th colspan="X">`, where X is the number of columns that belong to the group. |
| 83 | +- In the second header row, use `<th scope="col">` for each individual sub-column. |
| 84 | +- Assign `scope="row"` to the first `<th>` in each body row for accessibility. |
| 85 | +- Use `ds-u-text-align--left` for consistent alignment with other table variants. |
| 86 | + |
| 87 | +Here’s an example: |
| 88 | + |
| 89 | +<table class="ds-c-table"> |
| 90 | + <caption class="ds-c-table__caption">Household members</caption> |
| 91 | + <colgroup span="2"></colgroup> |
| 92 | + <colgroup span="2"></colgroup> |
| 93 | + <thead role="rowgroup"> |
| 94 | + <tr role="row"> |
| 95 | + <th class="ds-u-text-align--left" role="columnheader" scope="col"></th> |
| 96 | + <th class="ds-u-text-align--left" role="columnheader" scope="colgroup" colspan="2">Address</th> |
| 97 | + <th class="ds-u-text-align--left" role="columnheader" scope="colgroup" colspan="2">Employment</th> |
| 98 | + </tr> |
| 99 | + <tr role="row"> |
| 100 | + <th class="ds-u-text-align--left" role="columnheader" scope="col">Name</th> |
| 101 | + <th class="ds-u-text-align--left" role="columnheader" scope="col">Street</th> |
| 102 | + <th class="ds-u-text-align--left" role="columnheader" scope="col">ZIP code</th> |
| 103 | + <th class="ds-u-text-align--left" role="columnheader" scope="col">Employer</th> |
| 104 | + <th class="ds-u-text-align--left" role="columnheader" scope="col">Industry</th> |
| 105 | + </tr> |
| 106 | + </thead> |
| 107 | + <tbody role="rowgroup"> |
| 108 | + <tr role="row"> |
| 109 | + <th class="ds-u-text-align--left" role="rowheader" scope="row">John Doe</th> |
| 110 | + <td class="ds-u-text-align--left" role="cell">123 Braavos Ave.</td> |
| 111 | + <td class="ds-u-text-align--left" role="cell">20005</td> |
| 112 | + <td class="ds-u-text-align--left" role="cell">Acme Co.</td> |
| 113 | + <td class="ds-u-text-align--left" role="cell">Healthcare</td> |
| 114 | + </tr> |
| 115 | + <tr role="row"> |
| 116 | + <th class="ds-u-text-align--left" role="rowheader" scope="row">Jane Doe</th> |
| 117 | + <td class="ds-u-text-align--left" role="cell">456 King's Landing</td> |
| 118 | + <td class="ds-u-text-align--left" role="cell">20005</td> |
| 119 | + <td class="ds-u-text-align--left" role="cell">Acme Co.</td> |
| 120 | + <td class="ds-u-text-align--left" role="cell">Healthcare</td> |
| 121 | + </tr> |
| 122 | + </tbody> |
| 123 | +</table> |
| 124 | + |
| 125 | + |
| 126 | +### Stackable Table |
| 127 | + |
| 128 | +Stackable tables are useful when you need to display tabular data on small screens. On narrow viewports, each row stacks vertically, and each cell includes a bolded label pulled from its `data-title` attribute. |
| 129 | + |
| 130 | +#### How to build a stackable table |
| 131 | + |
| 132 | +- Add the `ds-c-table ds-c-table--stacked` classes to your `<table>`. See the next section to choose the appropriate `stacked` variant for your use case. |
| 133 | +- For each `<td>` cell, include a `data-title="[Column name]"` attribute that matches its corresponding header. |
| 134 | +- Use `ds-u-text-align--left` for consistent alignment with other table variants. |
| 135 | + |
| 136 | +#### Choosing a stackable variant |
| 137 | + |
| 138 | +The Design System provides size-based modifiers that control when the table switches to a stacked layout. |
| 139 | + |
| 140 | +| Class | Stacking behavior | Breakpoint | |
| 141 | +|-------|-------------------|------------| |
| 142 | +| `ds-c-table--stacked` | Always stacked, on all screen sizes | — | |
| 143 | +| `ds-c-sm-table--stacked` | Stacked on small screens only | `≤ 544px` | |
| 144 | +| `ds-c-md-table--stacked` | Stacked on medium screens and below | `≤ 768px` | |
| 145 | +| `ds-c-lg-table--stacked` | Stacked on large screens and below | `≤ 1024px` | |
| 146 | + |
| 147 | +The example below uses the `ds-c-table--stacked` class: |
| 148 | + |
| 149 | +<table class="ds-c-table ds-c-table--stacked"> |
| 150 | + <caption class="ds-c-table__caption">Founding documents</caption> |
| 151 | + <thead> |
| 152 | + <tr> |
| 153 | + <th class="ds-u-text-align--left" scope="col">Document title</th> |
| 154 | + <th class="ds-u-text-align--left" scope="col">Description</th> |
| 155 | + <th class="ds-u-text-align--left" scope="col">Links</th> |
| 156 | + <th class="ds-u-text-align--left" scope="col">Year</th> |
| 157 | + </tr> |
| 158 | + </thead> |
| 159 | + <tbody> |
| 160 | + <tr> |
| 161 | + <td class="ds-u-text-align--left" data-title="Document title">Declaration of Independence</td> |
| 162 | + <td class="ds-u-text-align--left" data-title="Description">Statement adopted by the Continental Congress declaring independence from the British Empire.</td> |
| 163 | + <td class="ds-u-text-align--left" data-title="Links"> |
| 164 | + <a href="https://billofrightsinstitute.org/founding-documents/declaration-of-independence/">View</a> |
| 165 | + </td> |
| 166 | + <td class="ds-u-text-align--left" data-title="Year">1776</td> |
| 167 | + </tr> |
| 168 | + <tr> |
| 169 | + <td class="ds-u-text-align--left" data-title="Document title">Articles of Confederation</td> |
| 170 | + <td class="ds-u-text-align--left" data-title="Description">This document served as the United Statesʼ first constitution.</td> |
| 171 | + <td class="ds-u-text-align--left" data-title="Links"> |
| 172 | + <a href="https://www.archives.gov/milestone-documents/articles-of-confederation">View</a> |
| 173 | + </td> |
| 174 | + <td class="ds-u-text-align--left" data-title="Year">1777</td> |
| 175 | + </tr> |
| 176 | + <tr> |
| 177 | + <td class="ds-u-text-align--left" data-title="Document title">The Constitution</td> |
| 178 | + <td class="ds-u-text-align--left" data-title="Description">Replaced the Articles of Confederation with a new form of government. It created a federal system with a national government composed of 3 separated powers, and included both reserved and concurrent powers of states</td> |
| 179 | + <td class="ds-u-text-align--left" data-title="Links"> |
| 180 | + <a href="https://billofrightsinstitute.org/primary-sources/constitution">View</a> |
| 181 | + </td> |
| 182 | + <td class="ds-u-text-align--left" data-title="Year">1787</td> |
| 183 | + </tr> |
| 184 | + <tr> |
| 185 | + <td class="ds-u-text-align--left" data-title="Document title">Bill of Rights</td> |
| 186 | + <td class="ds-u-text-align--left" data-title="Description">The first ten amendments of the U.S. Constitution guaranteeing rights and freedoms.</td> |
| 187 | + <td class="ds-u-text-align--left" data-title="Links"> |
| 188 | + <a href="https://billofrightsinstitute.org/founding-documents/bill-of-rights/">View</a> |
| 189 | + </td> |
| 190 | + <td class="ds-u-text-align--left" data-title="Year">1791</td> |
| 191 | + </tr> |
| 192 | + </tbody> |
| 193 | +</table> |
| 194 | + |
| 195 | +<Alert heading="Coming soon"> |
| 196 | + The Design System will offer guidance and tooling for implementing scrollable tables in both HTML and React. Stay tuned for updates! |
| 197 | +</Alert> |
| 198 | + |
0 commit comments