Documentation
Content
Table
Tabular data with sortable headers, row selection, numeric alignment and a sticky header.
components/table.css
Example
Put the table in a dsgn-table-wrap. The wrapper scrolls sideways when the table is wider than the screen, so it is a focusable region with a name: keyboard users can scroll it too.
| Client | Amount (CZK) | |||
|---|---|---|---|---|
| 2026-114 | Studio Kolo s.r.o. | 12 Nov 2026 | 24 200 | |
| 2026-115 | Pekárna u Mlýna | 19 Nov 2026 | 8 650 | |
| 2026-116 | Novák Architects | 2 Dec 2026 | 132 000 |
<div class="dsgn-table-wrap" tabindex="0" role="region" aria-label="Invoices">
<table class="dsgn-table">
<thead>
<tr>
<th scope="col" class="dsgn-table-select"><input type="checkbox" class="dsgn-checkbox" aria-label="Select all"></th>
<th scope="col" aria-sort="ascending"><button class="dsgn-table-sort" type="button">Number<span class="dsgn-icon" aria-hidden="true">arrow_upward</span></button></th>
<th scope="col">Client</th>
<th scope="col"><button class="dsgn-table-sort" type="button">Due<span class="dsgn-icon" aria-hidden="true">unfold_more</span></button></th>
<th scope="col" data-numeric>Amount (CZK)</th>
</tr>
</thead>
<tbody>
<tr aria-selected="true">
<td class="dsgn-table-select"><input type="checkbox" class="dsgn-checkbox" aria-label="Select 2026-114" checked></td>
<td>2026-114</td>
<td>Studio Kolo s.r.o.</td>
<td>12 Nov 2026</td>
<td data-numeric>24 200</td>
</tr>
<tr>
<td class="dsgn-table-select"><input type="checkbox" class="dsgn-checkbox" aria-label="Select 2026-115"></td>
<td>2026-115</td>
<td>Pekárna u Mlýna</td>
<td>19 Nov 2026</td>
<td data-numeric>8 650</td>
</tr>
<tr>
<td class="dsgn-table-select"><input type="checkbox" class="dsgn-checkbox" aria-label="Select 2026-116"></td>
<td>2026-116</td>
<td>Novák Architects</td>
<td>2 Dec 2026</td>
<td data-numeric>132 000</td>
</tr>
</tbody>
</table>
</div>Numbers
data-numeric on a header and its cells aligns them to the end. The whole table uses tabular figures, so digits line up from row to row.
Sorting
A sortable header holds a dsgn-table-sort button with an icon: unfold_more while unsorted, arrow_upward or arrow_downward once sorted. Sorting is visual only: your code sorts the data and sets aria-sort on the <th>, which tells screen readers the order.
Selection
A first column with dsgn-table-select holds a checkbox per row and one in the header to select all. Mark a selected row with aria-selected="true", so it is highlighted and announced.
Row height
A row is one control height plus a small gap above and below: 36 px in density S, 44 px in M and 52 px in L. A row with a checkbox, badge, link or ghost button keeps exactly that height, so a table never jumps when a row gets an action.
Accessibility
- Give every header cell a
scope:colfor column headers,rowfor a header at the start of a row. - Name the table: an
aria-labelon the wrapper, or a<caption>(which can be visually hidden). - Every checkbox needs an
aria-labelthat names its row.
Usage
Row height = control line-height + 2 × row-pad-y (S 36 · M 44 · L 52): one control height plus space-4 above and below, so buttons and inputs in a row never touch its edges. A row with a checkbox, badge, link or ghost button keeps exactly that height. Header sticks to the top of the wrapper when it scrolls. Sorting is visual only: the app sorts the data and sets aria-sort on the <th>. Icons: unfold_more (sortable), arrow_upward (ascending), arrow_downward (descending).
Details
- Classes
.dsgn-table-wrap.dsgn-table.dsgn-table-sort.dsgn-table-select.dsgn-checkbox.dsgn-badge.dsgn-icon-button.dsgn-button.dsgn-icon.dsgn-table-muted- Tokens used
--dsgn-border--dsgn-control-font-size--dsgn-control-line-height--dsgn-control-pad-x--dsgn-control-pad-y--dsgn-control-subtle--dsgn-control-subtle-hover--dsgn-control-subtle-pressed--dsgn-control-text--dsgn-duration-fast--dsgn-ease--dsgn-focus--dsgn-focus-offset--dsgn-focus-width--dsgn-font-sans--dsgn-font-weight-medium--dsgn-inset--dsgn-line-container--dsgn-line-height-caption--dsgn-line-separator--dsgn-neutral-subtle--dsgn-neutral-subtle-hover--dsgn-neutral-subtle-pressed--dsgn-radius-l--dsgn-radius-s--dsgn-row-pad-y--dsgn-shadow-raised--dsgn-space-2--dsgn-space-4--dsgn-surface-base--dsgn-surface-raised--dsgn-text--dsgn-text-muted- In Figma
- Table header cell · Table cell · Table example
- Import alone
dsgn.systems/components/table.css