P-01 · Primitives · Primitives
All elements · Box on the Primitives page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve Box
Approving as
The layout host: every rectangle in the app. Absorbs the two thirds of inline styles that are pure layout. A Box has no color of its own.
| Axis | Values |
|---|---|
data-display |
flex · inline-flex · grid · inline · none |
data-direction |
row · column · row-reverse |
data-gap · data-p · data-px · data-py |
0 · 1 · 2 · 3 · 4 · 6 · 8 (token scale) |
data-align · data-justify |
start · center · end · stretch · baseline / start · center · end · between · around |
data-wrap · data-flex · data-w · data-h ·
data-overflow · data-position · data-cols
|
wrap / 1 · auto · none / full / hidden · auto / relative · absolute · sticky / 2 · 3 · 4 · auto |
Guidance
When to use
- Lay out a row of controls, such as a record header with a title, a spacer and its actions.
- Stack fields, sections or panels in a column with a token gap.
- Build a simple grid of tiles with
data-display="grid"anddata-cols. - Replace inline
stylethat only sets display, gap, padding, alignment or overflow.
When to consider something else
- When the region needs a background, border, radius or elevation, use Surface; Box has no color of its own. See Surface.
-
When the region must scroll and show edge shadows, use ScrollArea instead of
data-overflowon a Box. See ScrollArea. - When the content is a self-contained summary of one record, use Card. See Card.
- When the layout is a full app frame with nav, header and panes, use the Shell composite. See App shell.
Usability
-
Use the token scale for
data-gapand padding so spacing stays consistent across panes. -
Use
data-flex="1"on an empty Box as a spacer to push trailing actions to the end. -
Let rows wrap with
data-wrap="wrap"when a toolbar of actions can run out of width. -
Choose the HTML element for meaning (
section,header,ul) and addqf-boxfor layout.
-
Don't use
data-direction="row-reverse"to change the order users see; it breaks the match between visual and reading order. - Don't nest Boxes only to add padding when one Box with
data-pwill do. -
Don't use
data-overflow="hidden"on regions that hold focusable content or text that can grow.
Accessibility
Keyboard
No keyboard interaction of its own.
Roles and names
-
Box adds no role. It takes the semantics of the element it is applied to, so pick
div,section,nav,uland so on for meaning. -
When a Box is a landmark or a named region, give it an accessible name with
aria-labeloraria-labelledby.
Focus
- Box is not focusable. Focus order follows DOM order, so keep DOM order the same as the visual order (2.4.3).
Other requirements
- Box is layout only and has no keyboard behavior of its own.
-
Reading and focus order must not depend on
row-reverse,data-positionor grid placement that reorders content visually (1.3.2, 2.4.3). -
Lengths are
rem, so layouts scale with the root size. Check that rows wrap rather than force horizontal scrolling at 320 CSS px (1.4.10). -
Avoid
data-overflow="hidden"where text spacing or zoom can clip content (1.4.12, 1.4.4).
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (2 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- box --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
No recorded changes yet.