Styles live in scss/components/_table.scss. PimentCSS styles semantic <table> markup; on narrow screens, pair it with a scroll container or an alternate list layout.
Responsive strategy (phone / tablet)
Recommended patterns
- Row tables (many columns), wrap with
.table-scrollso overflow stays inside a labeled region. Users swipe horizontally; the page does not. - Long text, add
.table__text--wrapon cells that may wrap; keep sort labels and numbers innowrap(default) when alignment matters. - Very small screens, consider a card/list view (same data, no horizontal scroll) for critical flows such as checkout or profile.
- Column metrics, use
.table__columnwhen each column is a vertical stack (dashboards), not a classic data grid.
Row table + mobile cards
From min-width: 48rem you see the full table inside .table-scroll (checkbox, Name, Role, Status). Below that breakpoint, the same dataset is shown as cards (doc pattern) so nothing is crushed. Click a row to toggle selection (data-table-live); hover and selected row styles are documented in Row states.
| Name | Role | Status | |
|---|---|---|---|
| Alex Martin | Product designer | Active | |
| Samira Chen | Engineer | Active | |
| Jordan Lee | Content strategist | Paused |
On phone and tablet, scroll inside the shaded region. The page itself does not scroll sideways.
<div class="table-scroll" role="region" tabindex="0" aria-label="Team members">
<table class="table">
<caption class="sr-only">…</caption>
<thead>…</thead>
<tbody>…</tbody>
</table>
</div>
Cell content primitives
Small pieces that can appear inside a cell: text, icon, checkbox, status dot, and so on. Place them in <td class="table__cell">, usually wrapped in .table__item when you need icon and label on one line (left-aligned). The live table above already combines several of them (checkbox + heading + status).
Not a WYSIWYG toolbar
Documentation only: one row per primitive, with the markup you would put in a real cell.
Atomic pieces you combine inside a <td class="table__cell">. Not a toolbar or a standalone menu.
| Type | Markup in a cell |
|---|---|
| Copy | Body text |
| Heading | Column title |
| Icon & copy | Sortable column |
| Checkbox | |
| Copy underline | Link action |
| Status | Active |
<td class="table__cell table__cell--border-bottom"><span class="table__item">
<i class="ph ph-arrows-down-up table__icon" style="font-size:20px" aria-hidden="true"></i>
<span class="table__text table__text--heading">Name</span>
</span></td>
Row states
Hover uses tr:hover or .table__row--hover. Selection uses .table__row--selected with aria-selected="true" on interactive rows.
| State | Example |
|---|---|
| Default | Normal row |
| Hover | table__row--hover or tr:hover |
| Selected | table__row--selected |
Column layout
.table__column stacks cells vertically for KPI-style columns, not a horizontal grid.
JavaScript
data-table-live on the <table> enables click-to-select rows. .table-scroll[data-table-scroll-hint] adds a focus hint for keyboard users. Call wireAllTables() after load.
import { wireAllTables } from './table-behavior';
document.addEventListener('DOMContentLoaded', () => wireAllTables());
// Row table: .table-scroll[aria-label] + .table[data-table-live] + tbody tr[data-table-select-row]
// Header checkbox toggles all rows; row checkbox and row click stay in sync
Class reference
| Class | Description |
|---|---|
.table | Semantic table (collapse borders, 100% width in scroll region) |
.table-scroll | Horizontal scroll region for row layouts on narrow viewports |
.table__cell | Cell padding and background |
.table__cell--heading | Header cell surface |
.table__cell--border-bottom | Bottom border between rows |
.table__cell--border-full | Full grid borders |
.table__row--hover | Hover row background |
.table__row--selected | Selected row (action surface) |
.table__text--wrap | Allow wrapping inside scroll regions |
.table__column | Vertical stack of cells (column layout) |
.pdoc-table-cards | Doc-only mobile card list pattern |
Customize (Sass)
-
Table spacing
Override cell padding and compact checkbox size in cells.@use "pimentcss-design-system" with ( $table-cell-padding-x: 1rem, $table-cell-padding-y: 0.75rem, $table-icon-size: 1.25rem ); -
Rebuild CSS
Run after editing _table.scss.npm run build:css
Accessibility (RGAA / WCAG)
Tables on small screens
- Captions, use
<caption class="sr-only">or visible caption; associate headers withscope="col"/scope="row". - Scroll region,
.table-scrollneedsrole="region",tabindex="0", andaria-labeldescribing the dataset. - Selection, for clickable rows use
aria-selectedand a clear focus style; prefer checkboxes when multi-select. - Do not rely on hover alone, provide text labels and visible status dots with text.
- Mobile alternative, when cards replace the table, keep the same heading order and expose all column values in the card body.