# Size

How big things are: control heights, icon boxes, touch targets and the widths content may grow to.

Status: candidate. Changes with density, viewport.

## Guidelines

### Purpose

The vocabulary of widths and heights that are not distances between things: how tall a control is, how big an icon is, the smallest box a finger can hit, how wide a column of content may grow, and the widths at which a layout may change shape. Spacing says how far apart; size says how big.

### How it is structured

Primitives come in three runs. A run of small steps for controls, icons and boxes; a run of widths for columns, panels and pages; and a run of viewport widths that name the structural breakpoints. They share a group because they are all sizes, but they are read by different roles and are not interchangeable.

The semantic roles say what is being sized:

- **Control** — the height of interactive things: buttons, fields, selects.
- **Icon** — the box an icon glyph is drawn into, from the smallest inline marker to the large decorative size.
- **Target** — the tap-area floors: the minimum the accessibility guidelines allow, and a more comfortable target for primary touch actions.
- **Selection** — the box of a checkbox or radio.
- **Mark** — the size of a small fixed mark inside a component: a dot, a bar, a key.
- **Content** — the widths a column of content may grow to, from a narrow prose measure to the full page line.
- **Layout** — a page's container widths, the measure of its text, the least width of a column, and the header's height.
- **List, tooltip and table** — the most a scrolling list grows, the widest a tooltip gets, and the narrowest and widest a column of prose in a table.
- **Sidebar** — the width of the expanded sidebar, authored here because Figma has no place for it.

### Tiers

Both tiers reach CSS. Use a semantic role wherever the thing being sized has a name in the list above, because that is what lets a density change move every control together. A primitive step is for a fixed internal measurement with no role — the width of a caret, the thickness of a progress bar.

The viewport steps are primitives with no semantic layer, on purpose: a breakpoint is a structural fact about a layout, not a design intent, and a breakpoint belongs where the content needs a structural change rather than at a named device. The semantics that do sit on viewport steps are the breakpoints, documented under Breakpoints.

### Context behavior

Density changes the control heights and nothing else in this group. Compact controls are one step shorter, except the smallest, which does not shrink because it is already at the minimum target floor. Icons, targets, selection boxes and content widths are the same under both densities, and target floors in particular must never compress.

A touch screen keeps every size. Nothing is drawn bigger or further apart for a finger. Instead, a control drawn smaller than the comfortable target takes an invisible press area round it, out to the comfortable target where nothing else pressable stands closer, and halfway to its neighbour where one does, so no two areas meet. No press area is ever smaller than the minimum target. A laptop with a touch screen and a mouse keeps the mouse behaviour.

The header's height is the one size that follows the screen: it has a phone value and a desktop value, which switch at the layout breakpoint and follow the layout attribute, as the components' narrow and wide forms do.

Theme and text size do not touch size.

### Usage rules

#### Do

- Size a control by its role, never by a primitive, so that density reaches it.
- Give every interactive element at least the minimum target, and primary touch actions the comfortable target, even when the visible control is smaller. Padding or a pseudo-element can carry the difference.
- Size icons by the icon roles, and let them inherit their color from the text they sit beside.
- Cap reading text at a content width. Readability depends on line length, and the content roles are the sanctioned measures.

#### Don't

- Write a pixel width or height in component CSS. The conformance checker rejects it.
- Use a control height as a spacing value, or a spacing step as a height. The two groups look similar in value and mean different things.
- Reference a viewport step inside a component to change its own layout. A component responds to the space it is given with a container query; viewport steps are for page-level structure.
- Shrink a target below the minimum floor for any density.
- Put a viewport step's custom property in a media query. CSS cannot read a custom property in a media query's condition, so take the number from the build's TypeScript or JSON output at build time instead.
- Size a checkbox or radio box with an icon size, or an icon with a selection size. Some match in value today by coincidence, and either can change without the other.

## Tokens

### Scale

Primitive, 18 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.4` | `--smbk-size-4` | 4px |
| `size.6` | `--smbk-size-6` | 6px |
| `size.8` | `--smbk-size-8` | 8px |
| `size.12` | `--smbk-size-12` | 12px |
| `size.16` | `--smbk-size-16` | 16px |
| `size.20` | `--smbk-size-20` | 20px |
| `size.24` | `--smbk-size-24` | 24px |
| `size.28` | `--smbk-size-28` | 28px |
| `size.32` | `--smbk-size-32` | 32px |
| `size.40` | `--smbk-size-40` | 40px |
| `size.44` | `--smbk-size-44` | 44px |
| `size.48` | `--smbk-size-48` | 48px |
| `size.56` | `--smbk-size-56` | 56px |
| `size.64` | `--smbk-size-64` | 64px |
| `size.72` | `--smbk-size-72` | 72px |
| `size.80` | `--smbk-size-80` | 80px |
| `size.88` | `--smbk-size-88` | 88px |
| `size.96` | `--smbk-size-96` | 96px |

### Viewport

Primitive, 6 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.viewport.320` | `--smbk-size-viewport-320` | 320px |
| `size.viewport.640` | `--smbk-size-viewport-640` | 640px |
| `size.viewport.768` | `--smbk-size-viewport-768` | 768px |
| `size.viewport.1024` | `--smbk-size-viewport-1024` | 1024px |
| `size.viewport.1280` | `--smbk-size-viewport-1280` | 1280px |
| `size.viewport.1440` | `--smbk-size-viewport-1440` | 1440px |

### Width

Primitive, 12 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.width.240` | `--smbk-size-width-240` | 240px |
| `size.width.320` | `--smbk-size-width-320` | 320px |
| `size.width.400` | `--smbk-size-width-400` | 400px |
| `size.width.480` | `--smbk-size-width-480` | 480px |
| `size.width.640` | `--smbk-size-width-640` | 640px |
| `size.width.720` | `--smbk-size-width-720` | 720px |
| `size.width.960` | `--smbk-size-width-960` | 960px |
| `size.width.1200` | `--smbk-size-width-1200` | 1200px |
| `size.width.1280` | `--smbk-size-width-1280` | 1280px |
| `size.width.1360` | `--smbk-size-width-1360` | 1360px |
| `size.width.1440` | `--smbk-size-width-1440` | 1440px |
| `size.width.1920` | `--smbk-size-width-1920` | 1920px |

### Icon

Semantic, 6 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.icon.xs` | `--smbk-size-icon-xs` | 12px |
| `size.icon.sm` | `--smbk-size-icon-sm` | 16px |
| `size.icon.md` | `--smbk-size-icon-md` | 20px |
| `size.icon.lg` | `--smbk-size-icon-lg` | 24px |
| `size.icon.xl` | `--smbk-size-icon-xl` | 32px |
| `size.icon.2xl` | `--smbk-size-icon-2xl` | 40px |

### Selection

Semantic, 3 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.selection.sm` | `--smbk-size-selection-sm` | 16px |
| `size.selection.md` | `--smbk-size-selection-md` | 20px |
| `size.selection.lg` | `--smbk-size-selection-lg` | 24px |

### Content

Semantic, 4 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.content.sm` | `--smbk-size-content-sm` | 480px |
| `size.content.md` | `--smbk-size-content-md` | 720px |
| `size.content.lg` | `--smbk-size-content-lg` | 960px |
| `size.content.xl` | `--smbk-size-content-xl` | 1360px |

### Mark

Semantic, 4 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.mark.sm` | `--smbk-size-mark-sm` | 16px |
| `size.mark.md` | `--smbk-size-mark-md` | 20px |
| `size.mark.lg` | `--smbk-size-mark-lg` | 24px |
| `size.mark.xl` | `--smbk-size-mark-xl` | 32px |

### Modal

Semantic, 3 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.modal.sm` | `--smbk-size-modal-sm` | 400px |
| `size.modal.md` | `--smbk-size-modal-md` | 560px |
| `size.modal.lg` | `--smbk-size-modal-lg` | 800px |

### Control

Semantic, 4 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.control.xs` | `--smbk-size-control-xs` | 24px |
| `size.control.sm` | `--smbk-size-control-sm` | comfortable: 32px · compact: 28px (changes with density) |
| `size.control.md` | `--smbk-size-control-md` | comfortable: 40px · compact: 32px (changes with density) |
| `size.control.lg` | `--smbk-size-control-lg` | comfortable: 48px · compact: 40px (changes with density) |

### Column

Semantic, 3 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.column.min.sm` | `--smbk-size-column-min-sm` | 240px |
| `size.column.min.md` | `--smbk-size-column-min-md` | 320px |
| `size.column.min.lg` | `--smbk-size-column-min-lg` | 400px |

### Layout

Semantic, 12 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.layout.container.md` | `--smbk-size-layout-container-md` | 720px |
| `size.layout.container.default` | `--smbk-size-layout-container-default` | 1360px |
| `size.layout.container.3xl` | `--smbk-size-layout-container-3xl` | 1360px |
| `size.layout.container.xs` | `--smbk-size-layout-container-xs` | 480px |
| `size.layout.container.sm` | `--smbk-size-layout-container-sm` | 640px |
| `size.layout.container.lg` | `--smbk-size-layout-container-lg` | 960px |
| `size.layout.container.xl` | `--smbk-size-layout-container-xl` | 1200px |
| `size.layout.container.2xl` | `--smbk-size-layout-container-2xl` | 1280px |
| `size.layout.container.4xl` | `--smbk-size-layout-container-4xl` | 1440px |
| `size.layout.container.5xl` | `--smbk-size-layout-container-5xl` | 1920px |
| `size.layout.measure.body` | `--smbk-size-layout-measure-body` | 640px |
| `size.layout.measure.heading` | `--smbk-size-layout-measure-heading` | 720px |

### Other size tokens

Semantic, 28 tokens.

| Token | CSS | Value |
|---|---|---|
| `size.target.min` | `--smbk-size-target-min` | 24px |
| `size.target.comfortable` | `--smbk-size-target-comfortable` | 44px |
| `size.list.max-height` | `--smbk-size-list-max-height` | 320px |
| `size.tooltip.max-width` | `--smbk-size-tooltip-max-width` | 240px |
| `size.table.prose-min` | `--smbk-size-table-prose-min` | 240px |
| `size.table.prose-max` | `--smbk-size-table-prose-max` | 480px |
| `size.sidebar.width` | `--smbk-size-sidebar-width` | 280px |
| `size.drawer.width` | `--smbk-size-drawer-width` | 384px |
| `size.dropdown.width` | `--smbk-size-dropdown-width` | 240px |
| `size.dropdown.max-width` | `--smbk-size-dropdown-max-width` | 320px |
| `size.command-palette.width` | `--smbk-size-command-palette-width` | 640px |
| `size.search.width` | `--smbk-size-search-width` | 320px |
| `size.preview.narrow` | `--smbk-size-preview-narrow` | 360px |
| `size.table-of-contents.width` | `--smbk-size-table-of-contents-width` | 240px |
| `size.popover.width` | `--smbk-size-popover-width` | 320px |
| `size.field.control.width` | `--smbk-size-field-control-width` | 200px |
| `size.button-note.width` | `--smbk-size-button-note-width` | 240px |
| `size.date-picker.date-min-width` | `--smbk-size-date-picker-date-min-width` | 168px |
| `size.date-picker.time-width` | `--smbk-size-date-picker-time-width` | 144px |
| `size.filter-bar.sort-width` | `--smbk-size-filter-bar-sort-width` | 240px |
| `size.toolbar.field-width` | `--smbk-size-toolbar-field-width` | 200px |
| `size.chart.plot-height` | `--smbk-size-chart-plot-height` | 196px |
| `size.chart.donut` | `--smbk-size-chart-donut` | 140px |
| `size.progress-ring.md` | `--smbk-size-progress-ring-md` | 72px |
| `size.progress-ring.sm` | `--smbk-size-progress-ring-sm` | 36px |
| `size.color-area.width` | `--smbk-size-color-area-width` | 224px |
| `size.color-picker.width` | `--smbk-size-color-picker-width` | 256px |
| `size.header.height` | `--smbk-size-header-height` | phone: 56px · desktop: 80px (changes with layout) |
