Skip to content
Fleetline

Table

Usage

Use a table to compare records across the same columns: work orders, service intervals, parts costs. Use a list group when each row is one item with a title and a few details, and a description list for the fields of a single vehicle.

Content: column headers are nouns in sentence case with the unit in brackets ("Labour (h)", "Parts (€)"). Format numbers with the locale (Intl.NumberFormat); show "0.00", not an empty cell, when the value is zero, and "—" with .sr-only "Not recorded" when it is unknown. Sorting, selection and pagination belong to the data table.

Anatomy

  1. Scroll wrapper — .table-wrap, role="region", tabindex="0", labelled by the caption
  2. Caption — <caption>, visible (.table__caption) or .sr-only
  3. Column headers — <th scope="col"> in <thead>
  4. Row header — <th scope="row">, the identifying cell (work order number)
  5. Data cells — <td>; numeric ones get .table__num
  6. Secondary line (optional) — .table__secondary inside a cell

Examples

States marked hover and focus-visible are frozen with .is-hover and .is-focus-visible. Those classes share their rule with the real pseudo-class; never use them in product code.

Table

Rows are work orders; the first cell is a row header. Numeric columns are end-aligned with tabular numerals so decimals line up.

Open work orders
Work orderVehicleMechanicLabour (h)Parts (€)
WO-4182Van KX-219Ford Transit, 84,212 kmMarta Quintero3.5412.80
WO-4185Truck TR-077Volvo FH, 312,940 kmIdris Okafor11.02,940.00
WO-4191Van KX-224Mercedes Sprinter, 51,006 kmLena Brandt1.2568.40
WO-4193Pickup PU-012Toyota Hilux, 140,377 kmMarta Quintero0.750.00
Open work orders, depot north
Work orderVehicleMechanicLabour (h)Parts (€)
WO-4182Van KX-219Ford Transit, 84,212 kmMarta Quintero3.5412.80
WO-4185Truck TR-077Volvo FH, 312,940 kmIdris Okafor11.02,940.00
WO-4191Van KX-224Mercedes Sprinter, 51,006 kmLena Brandt1.2568.40
WO-4193Pickup PU-012Toyota Hilux, 140,377 kmMarta Quintero0.750.00
Open work orders (compact)
Work orderVehicleMechanicLabour (h)Parts (€)
WO-4182Van KX-219Ford Transit, 84,212 kmMarta Quintero3.5412.80
WO-4185Truck TR-077Volvo FH, 312,940 kmIdris Okafor11.02,940.00
WO-4191Van KX-224Mercedes Sprinter, 51,006 kmLena Brandt1.2568.40
WO-4193Pickup PU-012Toyota Hilux, 140,377 kmMarta Quintero0.750.00
Open work orders — week 41
Work orderVehicleMechanicLabour (h)Parts (€)
WO-4182Van KX-219Ford Transit, 84,212 kmMarta Quintero3.5412.80
WO-4185Truck TR-077Volvo FH, 312,940 kmIdris Okafor11.02,940.00
WO-4191Van KX-224Mercedes Sprinter, 51,006 kmLena Brandt1.2568.40
WO-4193Pickup PU-012Toyota Hilux, 140,377 kmMarta Quintero0.750.00
<div class="table-wrap" role="region" aria-labelledby="wo-caption" tabindex="0">
  <table class="table table--striped">
    <caption id="wo-caption" class="table__caption">Open work orders — week 41</caption>
    <thead>
      <tr><th scope="col">Work order</th><th scope="col">Vehicle</th><th scope="col">Mechanic</th><th scope="col" class="table__num">Labour (h)</th><th scope="col" class="table__num">Parts (€)</th></tr>
    </thead>
    <tbody>
      <tr><th scope="row">WO-4182</th><td>Van KX-219<span class="table__secondary">Ford Transit, 84,212 km</span></td><td>Marta Quintero</td><td class="table__num">3.5</td><td class="table__num">412.80</td></tr>
      <tr><th scope="row">WO-4185</th><td>Truck TR-077<span class="table__secondary">Volvo FH, 312,940 km</span></td><td>Idris Okafor</td><td class="table__num">11.0</td><td class="table__num">2,940.00</td></tr>
      <tr><th scope="row">WO-4191</th><td>Van KX-224<span class="table__secondary">Mercedes Sprinter, 51,006 km</span></td><td>Lena Brandt</td><td class="table__num">1.25</td><td class="table__num">68.40</td></tr>
      <tr><th scope="row">WO-4193</th><td>Pickup PU-012<span class="table__secondary">Toyota Hilux, 140,377 km</span></td><td>Marta Quintero</td><td class="table__num">0.75</td><td class="table__num">0.00</td></tr>
    </tbody>
  </table>
</div>

API

HookValuesPurpose
.tableblock classBase table: full width, row dividers
.table--striped | --compact | --borderedmodifier classZebra rows, tighter cells, cell borders
.table-wrapwrapper classHorizontal scroll container; add role="region" tabindex="0" aria-labelledby
.table__captionpart classVisible caption style (or use .sr-only)
.table__numpart classEnd-aligned, tabular numerals; put it on the header too
.table__secondarypart classMuted second line in a cell
[data-density="compact"]ancestor attributeSame as .table--compact

Do and don't

Header "Parts (€)", value 2,940.00 end-aligned.

Do put units in the header and align numbers on the decimal side.

Header "Parts", value €2940 start-aligned.

Don’t repeat units in every cell or start-align numbers.

<th scope="row">WO-4182</th>

Do mark the identifying cell of each row as a row header.

<div class="row"> grids pretending to be tables.

Don’t build tables from divs; screen readers lose row and column context.

Accessibility

Keyboard interaction
KeyBehavior
TabMoves focus to the scroll wrapper when the table overflows
← / →Scrolls the focused wrapper horizontally

Tokens

Custom propertyPurpose
--density-comfortable-cell-padding-y / --density-compact-cell-padding-yRow height per density
--space-3 | -4Cell inline padding
--color-border-default | -strongRow dividers, header underline
--color-bg-subtleHeader fill and stripes
--color-text-default | -mutedCell text, secondary line
--font-size-sm | -xs | -mdCell, secondary line, caption
--focus-ring-*Focus ring on the scroll wrapper