Columns of cards, side by side on a wide screen in a frame that scrolls sideways, and stacked on a phone.
Website, preview
- Check the new color ladder against the contrast pairs.
Docs, preview
- One line per change, in plain words.
Shop, preview
Options
The board has no choices: it is drawn one way.
Examples
Usage
Columns side by side; when they run past the frame, it scrolls sideways and the keyboard can reach it.
Website
- Check the new color ladder against the contrast pairs.
Docs
- One line per change, in plain words.
Shop
Mobile
In a narrow space the columns stack at full width and nothing scrolls sideways.
Website, mobile
- Check the new color ladder against the contrast pairs.
Docs, mobile
- One line per change, in plain words.
Shop, mobile
Mobile, groups that fold
On a phone the finished and failed groups fold under their headings, closed at first, so the work still to do comes first; each group's label is a heading in the page's outline.
Website, groups that fold
Waiting on you
1- Check the new color ladder against the contrast pairs.
Shop, groups that fold
In progress
1Failed
1
- The export file was empty.
Guidelines
Purpose
Shows work in lanes: one column per project, person or stage, each with its cards. On a wide screen the lanes sit side by side, so the reader can compare them; on a phone they stack, one under another.
When to use
- For a few lanes of comparable work that a reader scans side by side.
- For a dashboard of projects, each with its items grouped by where they stand.
When not to use
- For one lane. Use a board column alone.
- For many items with many details each. Use a table.
Usage rules
Do
- Keep to a few columns, each named.
- Put the column that needs the reader first, first.
Don't
- Hide columns on a phone; they stack instead.
- Nest a board in a board column.
To do
Plan the next sprint
Give each column a name of its own, so a screen reader user knows which lane they are in.
Column 1
Plan the next sprint
Untitled lanes, told apart only by where they sit, are lost the moment the board stacks on a phone.
Anatomy
- The block, a frame that scrolls sideways when its columns run past it.
- The columns part, the row of board columns, the large inline gap apart.
- The scroll hint part, a thin bar along the frame's foot that shows there is more sideways and how much is in view. It shows where the browser's own scrollbar takes no room, such as on a phone or a trackpad, and wherever the system's scrollbar is drawn over the frame; it fades while that bar shows, in the same strip.
Behavior
On a wide screen the columns sit side by side at the large column width. When they need more room than the frame has, the frame scrolls sideways inside itself, so the page never does. In a narrow space the columns stack at full width, the large stack gap apart, and nothing scrolls sideways. Put data-layout="narrow" or "wide" on an element around the board to choose either form.
Moving cards between columns by dragging is not part of the board.
Accessibility
What it does for you
- While the columns run past the frame, the frame is a region named by the board's label and a stop for the Tab key, so the arrow keys can scroll it sideways. It shows the focus ring inside its edge. When everything fits, it is neither.
- The columns are read in the order they come in the page, left to right on a wide screen and top to bottom on a phone.
- Each column is a region of its own, named by its title.
What you must do
- Give the board an
aria-labelthat says what it shows, such as "Agents by project".
How to test
- On a wide screen with columns past the frame, Tab to the frame: the focus ring shows inside its edge, and the arrow keys scroll it sideways.
- With a screen reader, the frame and each column are found as regions by their names, and the columns are read in page order.
- With text at 200% and the page 320 pixels wide, the columns stack and nothing scrolls sideways.
- In a forced-color mode, the focus ring on the frame stays visible.
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the frame while the columns run past it, then into the columns. |
| Left ArroworRight Arrow | Scrolls the frame sideways while it has focus. |
Source
The files the board is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.
Stylesheet
/* smbk-board — Board. Figma "Board" 7118:1603 (Platform: Desktop, Mobile; the layout switch here).
* Columns of cards side by side on a wide screen, the large inline gap apart, in a frame that scrolls
* sideways when they run past it; in a narrow space they stack, one under another at full width, the
* large stack gap apart, and nothing scrolls sideways. Where the browser hides its own scrollbar until the
* frame scrolls (a phone, a trackpad), a thin bar along the frame's foot shows that there is more
* sideways, drawn with the table's track and thumb. */
.smbk-board {
box-sizing: border-box;
position: relative;
display: block;
width: 100%;
overflow-x: auto;
/* The system's scrollbar: thin, in the subtle border color, on a clear track. */
scrollbar-width: thin;
scrollbar-color: var(--smbk-color-border-subtle) transparent;
}
/* A frame that scrolls is a region the keyboard reaches: its ring is drawn inside its edge, which clips. */
.smbk-board:focus-visible {
outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
outline-offset: calc(-1 * var(--smbk-focus-ring-width));
}
.smbk-board__columns {
display: flex;
align-items: flex-start;
gap: var(--smbk-space-inline-lg);
width: max-content;
min-width: 100%;
}
/* ---- the scroll hint (the shared script marks the frame `data-scroll-hint`) ---- */
.smbk-board__scroll-hint {
display: none;
}
.smbk-board[data-scroll-hint] .smbk-board__scroll-hint {
position: sticky;
left: 0;
display: block;
padding: var(--smbk-space-inset-xs) var(--smbk-space-inset-sm);
pointer-events: none;
}
/* While the system's scrollbar shows over the frame (scrollbar.ts), in the same strip, the hint's bar fades out of
its way (its fade is the table's). */
.smbk-board[data-scroll-hint]:has(> .smbk-scrollbar[data-shown]) .smbk-table__scroll-track {
opacity: 0;
}
/* ---- the narrow form: the columns stack and the frame no longer scrolls sideways ---- */
@container style(--smbk-layout: narrow) {
.smbk-board {
overflow-x: visible;
}
.smbk-board__columns {
flex-direction: column;
align-items: stretch;
gap: var(--smbk-space-stack-lg);
width: auto;
}
.smbk-board__scroll-hint {
display: none;
}
}Tokens it reads
| Token and CSS | Value | Preview | Foundation |
|---|---|---|---|
| color.border.subtle--smbk-color-border-subtle | light: #c4cdd8dark: #2d3237changes with theme | Color | |
| focus.ring.width--smbk-focus-ring-width | 2px | Focus | |
| color.border.focus--smbk-color-border-focus | light: #cc0d0ddark: #f34336changes with theme | Color | |
| space.inline.lg--smbk-space-inline-lg | comfortable: 12pxcompact: 8pxchanges with density | Spacing | |
| space.inset.xs--smbk-space-inset-xs | 4px | Spacing | |
| space.inset.sm--smbk-space-inset-sm | comfortable: 6pxcompact: 4pxchanges with density | Spacing | |
| space.stack.lg--smbk-space-stack-lg | comfortable: 16pxcompact: 12pxchanges with density | Spacing |
Manifest
{
"name": "board",
"block": "smbk-board",
"summary": "Columns of cards, side by side on a wide screen in a frame that scrolls sideways, and stacked on a phone.",
"adapt": "css",
"axes": {},
"flags": {},
"parts": [
"columns",
"scroll-hint"
],
"figmaNodeId": "7118:1603"
}