The distances inside and between things, from a control's padding to the rhythm between sections of a page.
Spacing scale
Guidelines
Purpose
The vocabulary of distances: padding inside things, gaps between things, and the rhythm between sections of a page. It is dense at the small end, where a few pixels change how a control feels, and coarser at the large end, where the eye reads rhythm rather than measurement.
How it is structured
The primitive scale is a run of steps named by their size. The steps sit close together at the small end and grow further apart toward the large end. Nothing about a step says what it is for; it is a length and nothing else.
The semantic layer names the kind of distance, which is the thing that changes with density:
- Inset — padding inside a thing: a button, a card, a field.
- Stack — the gap between things arranged vertically.
- Inline — the gap between things arranged horizontally.
- Section — the vertical rhythm between sections of a page.
- Gutter — the breathing room at a section's inline edges.
- Layout — the spacing of a page's sections: their padding, the gap under a section's heading, the gaps between blocks and the gap of a grid.
- Text — the gap between texts: paragraph to paragraph, a heading to its text, a caption under its title, one list item to the next. Text is not trimmed, so these are set for the full line box.
- Link underline — the gap between a link's words and the line under them. It is the same in every density, because the line belongs to the words and not to the layout.
Each kind has its own run of sizes, and the runs are not the same length. Inline distances stop earlier than stack distances because things side by side never need the breathing room that stacked sections do. Component spacing is named by role, so that a density change can move a coherent set of decisions rather than every number at once.
The gutter is a section's own breathing room at its sides, not a page gutter. How close a page's content sits to the screen's edge is not part of the system: each site chooses its own page gutter.
Tiers
Both tiers reach CSS. A component's fixed internal distance — the gap between an icon and its label inside a button, the padding of a chip — may use a primitive step directly, because that distance does not change with theme, density or viewport, and forcing a named role onto every one of them would make a semantic layer of single-use entries with no meaning.
The semantic roles are mandatory for any distance that does change with context. If a distance ought to be tighter under compact density, it must be a semantic role, because a primitive has one value and nothing can re-point it.
Context behavior
Density changes the semantic roles and nothing else. Under compact density each role steps down one or more primitive steps. The smallest inset does not shrink, because it cannot become smaller and still be an inset; the largest section rhythm shrinks the most.
Density is chosen once by the person building a project and set as an attribute on the page element. It is never a reader-facing control and never follows the viewport. A Table is the one part of a page that can differ: it can take compact on its own in a comfortable page.
The layout and text roles are the one part of spacing that follows the screen: each has a phone value and a desktop value, which switch at the layout breakpoint, as the components' narrow and wide forms do, and either can be forced on any part of a page with the layout attribute. Each value is itself one of the roles above, so it still follows density.
Theme and text size do not touch spacing.
Usage rules
Do
- Use a spacing token for every padding, margin, gap and structural offset. The conformance checker rejects a bare length in those properties.
- Use the semantic role that names the kind of distance — inset for padding, stack for vertical gaps, inline for horizontal gaps, section for page rhythm — whenever the distance should follow density.
- Use a primitive step for a fixed internal distance that should look the same under both densities.
- Compose with
calc()from existing steps when a distance genuinely falls between them, rather than writing the result as a number.
Don't
- Write a pixel or rem length in component CSS or in a site built on the system. The conformance checker rejects it.
- Create a mobile-suffixed or dark-suffixed spacing token. Context changes a value, never a name.
- Use a section rhythm inside a component. Section distances are the page's; a component that needs that much space is probably a section.
- Use a viewport media query to change a spacing value. If a distance should change with available width, use a container query, and reach for it only when the semantic roles cannot express the need.
Tokens
65 tokens in 9 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 |
|---|---|---|---|
0 | 0px | --smbk-space-0 | |
2 | 2px | --smbk-space-2 | |
Raw space step, 2 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
4 | 4px | --smbk-space-4 | |
6 | 6px | --smbk-space-6 | |
Raw space step, 6 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
8 | 8px | --smbk-space-8 | |
Raw space step, 8 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
12 | 12px | --smbk-space-12 | |
Raw space step, 12 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
16 | 16px | --smbk-space-16 | |
Raw space step, 16 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
20 | 20px | --smbk-space-20 | |
Raw space step, 20 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
24 | 24px | --smbk-space-24 | |
Raw space step, 24 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
32 | 32px | --smbk-space-32 | |
Raw space step, 32 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
40 | 40px | --smbk-space-40 | |
Raw space step, 40 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
48 | 48px | --smbk-space-48 | |
Raw space step, 48 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
56 | 56px | --smbk-space-56 | |
Raw space step, 56 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
64 | 64px | --smbk-space-64 | |
Raw space step, 64 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
72 | 72px | --smbk-space-72 | |
Raw space step, 72 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
96 | 96px | --smbk-space-96 | |
Raw space step, 96 px. Only for fixed distances inside a component; spacing that follows density uses space/inset, stack or inline.
| |||
128 | 128px | --smbk-space-128 | |
128 px of space. Raw step: use a semantic space.
| |||
Inset
| Token | Comfortable | Compact | Picture | CSS |
|---|---|---|---|---|
2xs | 2px | 2px | --smbk-space-inset-2xs | |
Padding inside a component, smallest.
| ||||
xs | 4px | 4px | --smbk-space-inset-xs | |
Padding inside a component, extra small.
| ||||
sm | 6px | 4px | --smbk-space-inset-sm | |
md | 8px | 6px | --smbk-space-inset-md | |
Padding inside a component, medium.
| ||||
lg | 12px | 8px | --smbk-space-inset-lg | |
Padding inside a component, large.
| ||||
xl | 16px | 12px | --smbk-space-inset-xl | |
Padding inside a component, extra large.
| ||||
2xl | 24px | 16px | --smbk-space-inset-2xl | |
Padding inside a component, 2× large.
| ||||
3xl | 32px | 24px | --smbk-space-inset-3xl | |
Padding inside a component, 3× large.
| ||||
Stack
| Token | Comfortable | Compact | Picture | CSS |
|---|---|---|---|---|
xs | 4px | 4px | --smbk-space-stack-xs | |
Gap between things stacked one above another, extra small.
| ||||
sm | 8px | 6px | --smbk-space-stack-sm | |
Gap between things stacked one above another, small.
| ||||
md | 12px | 8px | --smbk-space-stack-md | |
Gap between things stacked one above another, medium.
| ||||
lg | 16px | 12px | --smbk-space-stack-lg | |
Gap between things stacked one above another, large.
| ||||
xl | 24px | 16px | --smbk-space-stack-xl | |
Gap between things stacked one above another, extra large.
| ||||
2xl | 32px | 24px | --smbk-space-stack-2xl | |
Gap between things stacked one above another, 2× large.
| ||||
3xl | 40px | 32px | --smbk-space-stack-3xl | |
Gap between things stacked one above another, 3× large.
| ||||
4xl | 48px | 40px | --smbk-space-stack-4xl | |
Gap between things stacked one above another, 4× large.
| ||||
5xl | 56px | 48px | --smbk-space-stack-5xl | |
Gap between things stacked one above another, 5× large.
| ||||
Inline
Gutter
| Token | Comfortable | Compact | Picture | CSS |
|---|---|---|---|---|
xs | 8px | 4px | --smbk-space-gutter-xs | |
sm | 12px | 8px | --smbk-space-gutter-sm | |
A section’s outer side padding on a desktop (space/layout/gutter points here). The page itself has no gutter: each section carries its own.
| ||||
Section
| Token | Comfortable | Compact | Picture | CSS |
|---|---|---|---|---|
sm | 48px | 32px | --smbk-space-section-sm | |
Rhythm of page sections, small.
| ||||
md | 64px | 48px | --smbk-space-section-md | |
Rhythm of page sections, medium.
| ||||
lg | 96px | 64px | --smbk-space-section-lg | |
Rhythm of page sections, large.
| ||||
xl | 128px | 96px | --smbk-space-section-xl | |
Rhythm of page sections, the largest: the space above and below a hero or a landing section. Compact density shrinks it.
| ||||
Layout
| Token | Phone | Desktop | Comfortable | Compact | Picture | CSS |
|---|---|---|---|---|---|---|
gutter | comfortable: 8px · compact: 4px | comfortable: 12px · compact: 8px | undefined | undefined | --smbk-space-layout-gutter | |
A section’s outer side padding: the strip of page between the screen edge and the section’s band. There is no page gutter: the page frame has no padding, and every section, the header and the footer carry this on their own sides. 8 on a phone, 12 on a desktop (comfortable). Each value points to a density token, so compact density still applies.
| ||||||
section.xs | comfortable: 16px · compact: 12px | comfortable: 24px · compact: 16px | undefined | undefined | --smbk-space-layout-section-xs | |
Space above and below a page section, xs. Phones get less: 16 | 24 (phone | desktop).
| ||||||
section.sm | comfortable: 32px · compact: 24px | comfortable: 48px · compact: 32px | undefined | undefined | --smbk-space-layout-section-sm | |
Space above and below a page section, sm. Phones get less: 32 | 48 (phone | desktop).
| ||||||
section.md | comfortable: 64px · compact: 48px | comfortable: 96px · compact: 64px | undefined | undefined | --smbk-space-layout-section-md | |
Space above and below a page section, md. Phones get less: 64 | 96 (phone | desktop).
| ||||||
section.lg | comfortable: 64px · compact: 48px | comfortable: 128px · compact: 96px | undefined | undefined | --smbk-space-layout-section-lg | |
Space above and below a page section, lg. Phones get less: 64 | 128 (phone | desktop).
| ||||||
inset | comfortable: 16px · compact: 12px | comfortable: 32px · compact: 24px | undefined | undefined | --smbk-space-layout-inset | |
The sides inside a section’s band, from its edge to its content: 16 on a phone, 32 on a desktop (comfortable). It comes on top of space/layout/gutter, which sits outside the band. Each value points to a density token, so compact density still applies.
| ||||||
heading | comfortable: 40px · compact: 32px | comfortable: 56px · compact: 48px | undefined | undefined | --smbk-space-layout-heading | |
From a section heading to its content: 40 on a phone, 56 on a desktop (comfortable). Each value points to a density token, so compact density still applies.
| ||||||
gap.md | undefined | undefined | 32px | 24px | --smbk-space-layout-gap-md | |
Between blocks and grid items: 32 (comfortable). Each value points to a density token, so compact density still applies.
| ||||||
gap.lg | comfortable: 32px · compact: 24px | comfortable: 48px · compact: 40px | undefined | undefined | --smbk-space-layout-gap-lg | |
Beside a split: 32 on a phone, 48 on a desktop (comfortable). Each value points to a density token, so compact density still applies.
| ||||||
panel | comfortable: 24px · compact: 16px | comfortable: 48px · compact: 40px | undefined | undefined | --smbk-space-layout-panel | |
Padding inside a raised panel that holds a section: a hero card, a feature block, a call-to-action box. Smaller on phones.
| ||||||
grid.gap | comfortable: 16px · compact: 12px | comfortable: 24px · compact: 16px | undefined | undefined | --smbk-space-layout-grid-gap | |
The space between the columns of the page grid, and between cards laid out on it.
| ||||||
Text
| Token | Phone | Desktop | Comfortable | Compact | Picture | CSS |
|---|---|---|---|---|---|---|
heading | comfortable: 12px · compact: 8px | comfortable: 16px · compact: 12px | undefined | undefined | --smbk-space-text-heading | |
A heading to its first paragraph or list: 12 on phones, 16 on wide screens.
| ||||||
caption | 4px | 8px | undefined | undefined | --smbk-space-text-caption | |
A title to the small grey line under it: 4 on phones, 8 on wide screens.
| ||||||
section | comfortable: 24px · compact: 16px | comfortable: 32px · compact: 24px | undefined | undefined | --smbk-space-text-section | |
The end of one block of text to the next heading: 24 on phones, 32 on wide screens.
| ||||||
paragraph | undefined | undefined | 16px | 12px | --smbk-space-text-paragraph | |
Between two paragraphs (16). Text is not trimmed, so each line’s own leading adds to it.
| ||||||
list | undefined | undefined | 8px | 6px | --smbk-space-text-list | |
Between the items of a list (8).
| ||||||
label | 0px | 0px | 0px | 0px | --smbk-space-text-label | |
Between a label or title and the line of supporting text right under it, inside a component. None: untrimmed line height already spaces the two lines.
| ||||||
Other spacing tokens
| Token | Value | Picture | CSS |
|---|---|---|---|
link-underline | 4px | --smbk-space-link-underline | |
Gap between a link's words and the line under them. Figma sets a text's underline as a plain number with no variable behind it.
| |||