Tables
Tabular clinical and administrative data. A tinted header row, a subtle divider between rows, and no rule under the header — the tint is what separates it.
| No. | Patient | NHS number | DoB | Status |
|---|---|---|---|---|
| 1 | JONES, Alis | 123 456 7890 | 06 Dec 1974 | Confirmed |
| 2 | OWEN, Rhys | 234 567 8901 | 14 Mar 1988 | In review |
| 3 | PATEL, Nia | 345 678 9012 | 02 Jul 1991 | Draft |
<div class="sr-table-wrap">
<table class="sr-table">
<thead class="sr-table__head">…</thead>
<tbody>
<tr class="sr-table__row sr-table__row--selected">…</tr>
</tbody>
</table>
</div>
Row 2 shows the selected state; hover any row to see the hover surface. Dates use
the d Mmm yyyy format, and the header uses the No. abbreviation exception.
Show clinical or administrative data in rows and columns so staff can scan, compare and act on it, patient lists, results, appointments, audit logs.
When to use
- The data is genuinely tabular, rows are comparable across a shared set of columns (patient lists, results, appointments, audit logs).
- Staff need to scan down a column, sort, or compare rows.
When not to use
- For a single record's fields (one entity, many attributes), use a description list or the summary pattern, not a table.
- For 2–5 mutually exclusive choices, use radios; for a long selectable list, use Select. See.
- For general table markup and layout guidance, follow GDS / NHS England, this page covers only Single Record specifics.
How it works
- Row states are token-bound, see the table below; never hardcode row backgrounds.
- Compact clinical density, body cells are
Body S(14/20) at 8px padding, 40px tall. This is the primary-content minimum, justified for data-dense clinical views. - Square corners, data grids are full-bleed (
radius.none). - Row actions read as interactive, icon-only actions render in
Interactive/Primary(blue), destructive inInteractive/Destructive(red). - Horizontal scroll, never page-break, wide tables scroll inside
.sr-table-wrap.
Row states
| State | Token | Light | Dark |
|---|---|---|---|
| Default | sr.color.surface.section-cards | white | blue.900 |
| Hover | sr.color.surface.subtle | blue.50 | navy.700 |
Selected (--selected) | sr.color.surface.accent | cyan.100 | blue.900 |
Row dividers use sr.color.border.subtle. A selected row must also carry a non-colour signal (e.g. a persistent selection control or a left accent border), colour is never the only indicator (WCAG 1.4.1).
Options
| Option | Use when |
|---|---|
| Default | A plain data table with column headers only. |
Selectable rows (--selected) | One row is the active/selected entity, e.g. the current patient. |
kebab-left | A row has many actions or space is tight, the menu holds them. |
icons-left | One or two frequent actions worth surfacing directly. |
row-headers | Each row names an entity the columns describe (observation × time). |
Do & don't
| Do | Don't |
|---|---|
| Use the row-state tokens above | Hardcode a hover or selected background |
Keep cells compact (Body S, 8px padding) | Pad clinical tables so loosely they need scrolling |
Give every icon-only action an aria-label naming action + subject | Rely on colour alone to mark a selected row |
Use No. for "Number" in a tight column heading | Introduce other abbreviations with full stops (write ECG, not E.C.G.) |
Show dates as d Mmm yyyy (e.g. 10 Mar 2026) | Use ambiguous all-numeric formats (06/12/21) in tables |
Accessibility
- Semantic
<table>,<thead>,<tbody>,<th scope="col">;<th scope="row">for therow-headerslayout. - The actions-column header carries a visually-hidden "Actions" label.
- Every icon-only row action must have an
aria-labelnaming the action and its subject (e.g. "Edit Jones, Alis"). Icons themselves arearia-hidden. - Row action targets are 32×32px, a documented dense-desktop exception; promote to full-size controls on touch/mobile.
- Focus uses
Border/Focus(Cyan/700, ), outside the element.
Content
- Abbreviations: avoid abbreviations and never use full stops (
ECG, notE.C.G.). Table-heading exception:No.is allowed for "Number" in a column heading where width is genuinely tight. This is the only sanctioned abbreviation-with-full-stop, and only in headings. - Dates (, adapted): use the short form
d Mmm yyyy(e.g.10 Mar 2026) in tables and anywhere else width is constrained; use the long form10 March 2026in prose and where there is room. An abbreviated or full month name (never a digit) is what resolves day/month ambiguity for clinical safety. This adapts the legacydd-Mmm-yyyyformat, which used hyphens; the ambiguity protection is unchanged. - Names:
SURNAME, First Min list/table columns. - Sentence case for all cell content and headings. Follow the DHCW terminology table.
Frameworks
| Framework | Status | Where |
|---|---|---|
| Web (HTML/CSS) | Reference baseline | packages/web/src/table/table.css, .sr-table__* classes |
| React | Current | mirrors the sr-table__* markup |
| Blazor /.NET | Current | mirrors the sr-table__* markup via the RCL |
| .NET MAUI | Planned | Native XAML, not a web view. Tokens available now; native styles in progress |
| Legacy (.NET 4.8 / Delphi) | Tokens only / best-effort | token CSS custom properties |
Sorting, filtering and pagination are planned and not yet part of the reference,
Clinical / DHCW notes
The legacy. These map onto the kebab-left layout and the selectable-row / editable patterns respectively, carried forward, re-expressed against the token system. Chronology defaults to oldest-first with sortable columns.
Related
- Select · Tags (status badges in cells) · Button (row actions)
- GDS Table · NHS England Table
Accessibility requirements
| Requirement | WCAG SC | How Single Record meets it | Test method |
|---|---|---|---|
| Semantic table structure | 1.3.1 | Real table, thead and th elements with a scope; a row-header layout adds a row-scoped header cell. | Markup review, screen reader |
| Icon-only row actions are named | 4.1.2 | Each action names the action and its subject, for example "Edit Jones, Alis". Icons are hidden from assistive technology. | Screen reader announce |
| Selected row not colour alone | 1.4.1 | Selected rows carry a non-colour signal such as a selection control or a left accent. | Greyscale review |
| Target size for dense actions | 2.5.8 | 32×32px is a documented dense-desktop exception, promoted to full size on touch and mobile. | Measure, touch device |
| Focus visible | 2.4.7 | A focus ring sits outside the action buttons so it is never clipped by the row. | Keyboard tab |