How big things are: control heights, icon boxes, touch targets and the widths content may grow to.
Size scale
44px66px88px1212px1616px2020px2424px2828px3232px4040px4444px4848px5656px6464px7272px8080px8888px9696px
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
103 tokens in 12 groups. Open a group to see its tokens. The button beside a CSS name copies it, ready to paste; open a row for what the token is for and which components read it.
Scale
| Token | Value | Picture | CSS |
|---|---|---|---|
4 | 4px | --smbk-size-4 | |
Raw size step, 4 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
6 | 6px | --smbk-size-6 | |
8 | 8px | --smbk-size-8 | |
Raw size step, 8 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
12 | 12px | --smbk-size-12 | |
Raw size step, 12 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
16 | 16px | --smbk-size-16 | |
Raw size step, 16 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
20 | 20px | --smbk-size-20 | |
Raw size step, 20 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
24 | 24px | --smbk-size-24 | |
Raw size step, 24 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
28 | 28px | --smbk-size-28 | |
Raw size step, 28 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
32 | 32px | --smbk-size-32 | |
40 | 40px | --smbk-size-40 | |
Raw size step, 40 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
44 | 44px | --smbk-size-44 | |
Raw size step, 44 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
48 | 48px | --smbk-size-48 | |
Raw size step, 48 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
56 | 56px | --smbk-size-56 | |
64 | 64px | --smbk-size-64 | |
72 | 72px | --smbk-size-72 | |
Raw size step, 72 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
80 | 80px | --smbk-size-80 | |
88 | 88px | --smbk-size-88 | |
Raw size step, 88 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
96 | 96px | --smbk-size-96 | |
Raw size step, 96 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here.
| |||
Viewport
| Token | Value | Picture | CSS |
|---|---|---|---|
320 | 320px | --smbk-size-viewport-320 | |
Raw screen width, 320 px: the breakpoints point here.
| |||
640 | 640px | --smbk-size-viewport-640 | |
Raw screen width, 640 px: the breakpoints point here.
| |||
768 | 768px | --smbk-size-viewport-768 | |
Raw screen width, 768 px: the breakpoints point here.
| |||
1024 | 1024px | --smbk-size-viewport-1024 | |
Raw screen width, 1024 px: the breakpoints point here.
| |||
1280 | 1280px | --smbk-size-viewport-1280 | |
Raw screen width, 1280 px: the breakpoints point here.
| |||
1440 | 1440px | --smbk-size-viewport-1440 | |
Raw screen width, 1440 px: the breakpoints point here.
| |||
Width
| Token | Value | Picture | CSS |
|---|---|---|---|
240 | 240px | --smbk-size-width-240 | |
A fixed width of 240 px: a narrow column, a list’s greatest height. Semantic sizes point here.
| |||
320 | 320px | --smbk-size-width-320 | |
A fixed width of 320 px: a narrow column, a list’s greatest height. Semantic sizes point here.
| |||
400 | 400px | --smbk-size-width-400 | |
A fixed width of 400 px: a narrow column, a list’s greatest height. Semantic sizes point here.
| |||
480 | 480px | --smbk-size-width-480 | |
A fixed width of 480 px. size/content points here.
| |||
640 | 640px | --smbk-size-width-640 | |
A fixed width of 640 px. Raw step: use a semantic size.
| |||
720 | 720px | --smbk-size-width-720 | |
A fixed width of 720 px. size/content points here.
| |||
960 | 960px | --smbk-size-width-960 | |
A fixed width of 960 px. size/content points here.
| |||
1200 | 1200px | --smbk-size-width-1200 | |
A fixed width of 1200 px. Raw step: use a semantic size.
| |||
1280 | 1280px | --smbk-size-width-1280 | |
| |||
1360 | 1360px | --smbk-size-width-1360 | |
A fixed width of 1360 px. size/content points here.
| |||
1440 | 1440px | --smbk-size-width-1440 | |
| |||
1920 | 1920px | --smbk-size-width-1920 | |
| |||
Icon
| Token | Value | Picture | CSS |
|---|---|---|---|
xs | 12px | --smbk-size-icon-xs | |
Icon box, extra small.
| |||
sm | 16px | --smbk-size-icon-sm | |
Icon box, small.
| |||
md | 20px | --smbk-size-icon-md | |
Icon box, medium.
| |||
lg | 24px | --smbk-size-icon-lg | |
Icon box, large.
| |||
xl | 32px | --smbk-size-icon-xl | |
2xl | 40px | --smbk-size-icon-2xl | |
Icon box, 2× large.
| |||
Selection
| Token | Value | Picture | CSS |
|---|---|---|---|
sm | 16px | --smbk-size-selection-sm | |
md | 20px | --smbk-size-selection-md | |
Checkbox and radio box, medium.
| |||
lg | 24px | --smbk-size-selection-lg | |
Content
| Token | Value | Picture | CSS |
|---|---|---|---|
sm | 480px | --smbk-size-content-sm | |
md | 720px | --smbk-size-content-md | |
Widest a content column may grow, medium.
| |||
lg | 960px | --smbk-size-content-lg | |
Widest a content column may grow, large.
| |||
xl | 1360px | --smbk-size-content-xl | |
Widest a content column may grow, extra large.
| |||
Mark
| Token | Value | Picture | CSS |
|---|---|---|---|
sm | 16px | --smbk-size-mark-sm | |
md | 20px | --smbk-size-mark-md | |
lg | 24px | --smbk-size-mark-lg | |
xl | 32px | --smbk-size-mark-xl | |
Modal
| Token | Value | Picture | CSS |
|---|---|---|---|
sm | 400px | --smbk-size-modal-sm | |
| |||
md | 560px | --smbk-size-modal-md | |
| |||
lg | 800px | --smbk-size-modal-lg | |
| |||
Control
| Token | Comfortable | Compact | Picture | CSS |
|---|---|---|---|---|
xs | 24px | 24px | --smbk-size-control-xs | |
Height of the extra-small control: 24 in both densities, the smallest target allowed. Dashboard recipe: use compact density; 40 for the page’s one main action and for forms; 32 for toolbars and filters, the size used most; 28 for actions inside table rows and cards. On phones switch to comfortable density, or give small controls an invisible 44 px tap area (size/target/comfortable).
| ||||
sm | 32px | 28px | --smbk-size-control-sm | |
Height of a small control: 32 comfortable, 28 compact. Dashboard recipe: use compact density; 40 for the page’s one main action and for forms; 32 for toolbars and filters, the size used most; 28 for actions inside table rows and cards. On phones switch to comfortable density, or give small controls an invisible 44 px tap area (size/target/comfortable).
| ||||
md | 40px | 32px | --smbk-size-control-md | |
Height of a medium control, where controls insert by default: 40 comfortable, 32 compact. Dashboard recipe: use compact density; 40 for the page’s one main action and for forms; 32 for toolbars and filters, the size used most; 28 for actions inside table rows and cards. On phones switch to comfortable density, or give small controls an invisible 44 px tap area (size/target/comfortable).
| ||||
lg | 48px | 40px | --smbk-size-control-lg | |
Height of a large control: 48 comfortable, 40 compact. A page may use it for its main call to action; apps use md. Dashboard recipe: use compact density; 40 for the page’s one main action and for forms; 32 for toolbars and filters, the size used most; 28 for actions inside table rows and cards. On phones switch to comfortable density, or give small controls an invisible 44 px tap area (size/target/comfortable).
| ||||
Column
| Token | Value | Picture | CSS |
|---|---|---|---|
sm | 240px | --smbk-size-column-min-sm | |
The narrowest grid column, small: 240. Each value points to a density token, so compact density still applies.
| |||
md | 320px | --smbk-size-column-min-md | |
The narrowest grid column, medium: 320. Each value points to a density token, so compact density still applies.
| |||
lg | 400px | --smbk-size-column-min-lg | |
The narrowest grid column, large: 400. Each value points to a density token, so compact density still applies.
| |||
Layout
| Token | Value | Picture | CSS |
|---|---|---|---|
| Container10 | |||
md | 720px | --smbk-size-layout-container-md | |
Page container max width, 720 px.
| |||
default | 1360px | --smbk-size-layout-container-default | |
3xl | 1360px | --smbk-size-layout-container-3xl | |
Page container max width, 1360 px.
| |||
xs | 480px | --smbk-size-layout-container-xs | |
Page container max width, 480 px.
| |||
sm | 640px | --smbk-size-layout-container-sm | |
Page container max width, 640 px.
| |||
lg | 960px | --smbk-size-layout-container-lg | |
Page container max width, 960 px.
| |||
xl | 1200px | --smbk-size-layout-container-xl | |
Page container max width, 1200 px.
| |||
2xl | 1280px | --smbk-size-layout-container-2xl | |
Page container max width, 1280 px.
| |||
4xl | 1440px | --smbk-size-layout-container-4xl | |
Page container max width, 1440 px.
| |||
5xl | 1920px | --smbk-size-layout-container-5xl | |
Page container max width, 1920 px.
| |||
| Measure2 | |||
body | 640px | --smbk-size-layout-measure-body | |
Longest a line of running text may be: about 70 to 80 characters of Body MD. Paragraphs stop here even inside a wider container.
| |||
heading | 720px | --smbk-size-layout-measure-heading | |
Longest a heading or a lede may run before it wraps, so a big title does not stretch across the whole page.
| |||
Other size tokens
| Token | Phone | Desktop | Picture | CSS |
|---|---|---|---|---|
| Target2 | ||||
min | 24px | 24px | --smbk-size-target-min | |
Smallest tap area allowed (24, WCAG 2.2).
| ||||
comfortable | 44px | 44px | --smbk-size-target-comfortable | |
Comfortable touch target (44).
| ||||
| List1 | ||||
max-height | 320px | 320px | --smbk-size-list-max-height | |
| Tooltip1 | ||||
max-width | 240px | 240px | --smbk-size-tooltip-max-width | |
Placeholder:. The widest a tooltip bubble grows before its text wraps. Points at size/width/240 for now.
| ||||
| Table2 | ||||
prose-min | 240px | 240px | --smbk-size-table-prose-min | |
Placeholder:. The narrowest a prose column gets in a table before it wraps.
| ||||
prose-max | 480px | 480px | --smbk-size-table-prose-max | |
Placeholder:. The widest a prose column grows in a table, so lines stay readable.
| ||||
| Sidebar1 | ||||
width | 280px | 280px | --smbk-size-sidebar-width | |
| Drawer1 | ||||
width | 384px | 384px | --smbk-size-drawer-width | |
Width of a drawer from the left or right edge. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Dropdown2 | ||||
width | 240px | 240px | --smbk-size-dropdown-width | |
Least width of the dropdown menu panel, which grows from it to fit its longest item on one line. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
max-width | 320px | 320px | --smbk-size-dropdown-max-width | |
Greatest width of the dropdown menu panel: past it a long item's words wrap inside the panel. Not in Figma, which draws the panel at one width.
| ||||
| Command palette1 | ||||
width | 640px | 640px | --smbk-size-command-palette-width | |
Width of the command palette. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Search1 | ||||
width | 320px | 320px | --smbk-size-search-width | |
Width of the search field in the wide app bar. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Preview1 | ||||
narrow | 360px | 360px | --smbk-size-preview-narrow | |
Width of Figma's phone frames, used for the narrow previews of components that reflow. Not a viewport step; the steps in the size foundation are the layout breakpoints.
| ||||
| Table of contents1 | ||||
width | 240px | 240px | --smbk-size-table-of-contents-width | |
Width of the table of contents card. A fixed frame width in Figma with no variable behind it.
| ||||
| Popover1 | ||||
width | 320px | 320px | --smbk-size-popover-width | |
Width of the popover panel. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Field1 | ||||
control.width | 200px | 200px | --smbk-size-field-control-width | |
Width of the control in a side-by-side field, the label taking the rest of the row. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Button note1 | ||||
width | 240px | 240px | --smbk-size-button-note-width | |
Width of the note beside, under or at the end of a button: beside it, the note stays there while this much room is left after the button and moves under it otherwise. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Date picker2 | ||||
date-min-width | 168px | 168px | --smbk-size-date-picker-date-min-width | |
Least width of the date field beside the time field in a date and time picker; with less room the time field moves under it. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
time-width | 144px | 144px | --smbk-size-date-picker-time-width | |
Width of the time field beside the date field in a date and time picker. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Filter bar1 | ||||
sort-width | 240px | 240px | --smbk-size-filter-bar-sort-width | |
Width of the sort list in a wide filter bar, beside the search field and the filters button. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Toolbar1 | ||||
field-width | 200px | 200px | --smbk-size-toolbar-field-width | |
Width of a field in a toolbar: the list that picks what the bar acts on, a search field, a time range. A fixed frame width in Figma (the Picker, the Filter tools' search) with no variable behind it; it should become one.
| ||||
| Chart2 | ||||
plot-height | 196px | 196px | --smbk-size-chart-plot-height | |
Height of a line or bar chart's plot, the grid lines and the marks between its value labels. A fixed frame height in Figma with no variable behind it; it should become one.
| ||||
donut | 140px | 140px | --smbk-size-chart-donut | |
Width and height of a donut chart's ring. A fixed frame size in Figma with no variable behind it; it should become one.
| ||||
| Progress ring2 | ||||
md | 72px | 72px | --smbk-size-progress-ring-md | |
| ||||
sm | 36px | 36px | --smbk-size-progress-ring-sm | |
| ||||
| Color area1 | ||||
width | 224px | 224px | --smbk-size-color-area-width | |
Greatest width of the color area, which is square and fills the width it is given up to this. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Color picker1 | ||||
width | 256px | 256px | --smbk-size-color-picker-width | |
Width of the color picker panel. A fixed frame width in Figma with no variable behind it; it should become one.
| ||||
| Header1 | ||||
height | 56px | 80px | --smbk-size-header-height | |
The sticky header’s height, for scroll padding so a focused item is never hidden under it: 56 on a phone, 80 on a desktop. Each value points to a density token, so compact density still applies.
| ||||