Density Tokens and Target Size in Data Grids
Permalink to "Density Tokens and Target Size in Data Grids"Data grids need density options: analysts want 40 rows on screen, occasional users want room to breathe. Density is usually implemented by shrinking everything — padding, fonts, icons, checkboxes — until targets fall below what users with limited dexterity can hit, and rows clip text when users increase spacing. Design tokens let you define density precisely, separating what can shrink (visual padding) from what must not (hit areas, text size, spacing tolerance).
This guide belongs to design system tokens & component contracts.
Spec reference
Permalink to "Spec reference"- SC 2.5.8 Target Size (Minimum) (AA) — 24×24 CSS pixel targets or sufficient spacing.
- SC 1.4.12 Text Spacing (AA) — rows must not clip text with increased spacing.
- SC 1.4.4 Resize Text (AA) and SC 1.4.10 Reflow (AA) — density must work with zoom.
- SC 2.5.5 Target Size (Enhanced) (AAA) — 44×44, a good goal for comfortable or touch densities.
When to use — and when not to
Permalink to "When to use — and when not to"Use density tokens for any component with repeated rows and controls: grids, lists, tree views, menus. Offer two or three densities; more adds testing burden without benefit.
Do not define compact density by scaling fonts below the body size, or by reducing hit areas below 24 px. The misapplication: --row-height: 24px; --checkbox-size: 14px for “compact”, with height (not min-height) on rows.
Annotated code example
Permalink to "Annotated code example"{
"density": {
"standard": { "rowMinHeight": "40px", "cellPaddingBlock": "8px", "cellPaddingInline": "12px", "iconSize": "20px", "targetMin": "24px" },
"comfortable": { "rowMinHeight": "48px", "cellPaddingBlock": "12px", "cellPaddingInline": "16px", "iconSize": "20px", "targetMin": "32px" },
"compact": { "rowMinHeight": "32px", "cellPaddingBlock": "4px", "cellPaddingInline": "8px", "iconSize": "16px", "targetMin": "24px" }
}
}
.grid { --row-min: var(--density-row-min-height); --pad-b: var(--density-cell-padding-block); --target: var(--density-target-min); }
.grid td, .grid th { min-block-size: var(--row-min); padding-block: var(--pad-b); line-height: 1.5; } /* min, not fixed (SC 1.4.12) */
.grid .cell-control { /* every interactive control in a cell */
min-inline-size: var(--target); min-block-size: var(--target); /* hit area (SC 2.5.8) */
display: inline-grid; place-items: center;
}
.grid .cell-control > svg { inline-size: var(--density-icon-size); block-size: var(--density-icon-size); }
Keyboard & AT behaviour
Permalink to "Keyboard & AT behaviour"Density does not change semantics, but it affects focus visibility and readability:
| Density | Focus ring room | Text size | Notes |
|---|---|---|---|
| Comfortable | Ample | Body | Best for touch and low vision |
| Standard | Enough for 2–3 px outline | Body | Default |
| Compact | Inset outline needed | Body | Use inset focus rings; test contrast |
Integration context
Permalink to "Integration context"User-facing density controls are covered in segmented controls for view density. Testing is covered in testing target size 2.5.8 in dense grids and text spacing override testing for 1.4.12. Focus in compact rows relates to designing focus indicators for dense grids.
Gotchas
Permalink to "Gotchas"Virtualization and row heights. Virtualizers that need fixed row heights conflict with min-height rows. Use dynamic measurement or reserve enough height for two lines at 1.5 line height.
Icons scaling with density. Icons can shrink visually; hit areas must not.
Third-party grids. Map your tokens onto library variables (AG Grid theme params, MUI density) and verify the library respects min heights.
Worked example
Permalink to "Worked example"A design system’s compact density set rows to 28 px fixed and checkboxes to 14 px. Target-size tests flagged hundreds of controls, and text spacing tests clipped every second row. The team rewrote density tokens with a targetMin that never drops below 24 px, switched rows to minimum heights, and kept fonts at body size. Compact rows grew to 32 px; analysts still fit 30+ rows on screen, and the grid passed both tests in every density.
Common mistakes
Permalink to "Common mistakes"- Fixed row heights that clip under text spacing.
- Shrinking fonts in compact density.
- Margins mistaken for hit areas.
- Untested densities added “for power users”.
Adoption checklist
Permalink to "Adoption checklist"- Define density tokens with explicit
targetMinvalues. - Replace fixed heights with minimum heights across grid styles.
- Wrap interactive cell controls in hit-area containers sized from tokens.
- Add target-size and text-spacing tests per density to CI.
- Make standard density the default and persist user choices.
- Map tokens onto third-party grid theme parameters.
Worked numbers for a compact row
Permalink to "Worked numbers for a compact row"A compact row with a 16-pixel checkbox illustrates the arithmetic. The visual checkbox stays 16 pixels; its label wrapper is 24×24, centred in the cell. With 4 pixels of vertical padding and a 1.5 line height at a 14-pixel font, text needs 21 pixels, so the row’s minimum height of 32 pixels leaves room for the 24-pixel target with 4 pixels above and below. Under text spacing overrides the line grows to about 21 pixels plus letter and word spacing, still within 32; if a cell wraps to two lines, the row simply grows to fit.
Testing checklist
Permalink to "Testing checklist"Design system notes
Permalink to "Design system notes"Publish density tokens with the WCAG checks they were verified against, and include a density switcher in component documentation so reviewers see every density.
FAQ
Permalink to "FAQ"Can compact density be accessible?
Yes, if hit areas stay at 24 px and rows grow with content.
Should font size change with density?
Avoid shrinking below body size. Density should change spacing, not readability.
What default density should grids use?
Standard. Offer compact as an option for users who choose it.
How do I implement larger hit areas without changing visuals?
Wrap controls in elements sized to the target minimum, or use pseudo-elements to extend clickable areas.
Does density affect 1.4.10 reflow?
Indirectly: comfortable densities need more width; ensure tables still reflow or scroll appropriately at 400%.
Should touch devices default to comfortable?
Often yes; detect coarse pointers with media queries and let users override.
How many densities should we offer?
Two or three. Each must be tested.
How do density tokens interact with zoom?
Tokens in CSS pixels scale with browser zoom; that is expected. Ensure layouts reflow at 400% rather than overflowing.
Can density be adjusted per column?
Avoid it; mixed row heights confuse virtualization and readers. Adjust column widths instead.
Related
Permalink to "Related"- Segmented controls for view density — the user control
- Testing target size in dense grids — verification
- Focus ring tokens across themes — focus in every density