Size & spacing

Control height, surrounding space, and vertical rhythm are related decisions with separate jobs. Set the shared family once, then use component size and layout props to compose it.

Follow a control height

With an explicit 16px text base and a size ratio of 1.2:

DecisionSmallMediumLarge
Control roominess 2.5About 33.3px40px48px
Control roominess 2.75About 36.7px44px52.8px

The relationship is medium = base text size × roominess, small = medium ÷ size ratio, and large = medium × size ratio. These values describe the shared height roles. Content, borders, and component-specific constraints can still require more room.

text-size: 16px        control-roominess: 2.75
            ↘          ↙
             medium: 44px
              ↙       ↘
 small: 44 ÷ 1.2     large: 44 × 1.2

A 44px example is the result of these chosen values. Choose the proportions appropriate to your interface. Touch-target area is a separate decision and can extend beyond a compact visible control where neighboring controls allow it.

Map your decisions

Recipe keyCSS propertyWhat changes
control-roominess--ui-control-roominessMedium control height as a unitless multiple of the text base. Derives --ui-control-size and its small, medium, and large roles.
scale-contrast--ui-scale-ratioThe separation between sizes. At 1, the control sizes are equal; higher ratios separate them.
rhythm--ui-rhythmVertical Stack gaps and unitless line-height multipliers. Horizontal navigation and action-row gaps retain their own spacing.
spacing--ui-spacingGaps and padding independently of control heights and text ratios.
space-curve--ui-space-curveHow the spacing scale grows. 1 is linear; increasing toward 2 curves the intermediate steps while keeping stable endpoints.
corner-roundness--ui-radius-mdThe shared corner family for controls and surfaces.
line-weight--ui-border-widthShared border weight. Focus visibility has its own roles.

Keep height and space distinct

If buttons and fields feel too tall, change Control roominess. If content feels crowded around otherwise well-proportioned controls, change Spacing. If stacked paragraphs and groups need more vertical breathing room, change Rhythm.

{
  "schemaVersion": 1,
  "values": {
    "text-size": "16px",
    "control-roominess": "2.75",
    "scale-contrast": "1.2",
    "spacing": "1.1",
    "rhythm": "1.1"
  }
}

In component markup, use supported props such as size="sm" on a control or gap="l" on Stack. Let the theme supply the shared values behind those choices.

Preserve units

Base text-size is px-only and sets the document root. Other supported length inputs retain their CSS units, including rem, with generated guards for their documented bounds. Set the base on :root; a nested light/dark region shares that rem root.

For older recipes, replace density with spacing. Replace a length-valued control-size with numeric control-roominess by dividing the desired medium height by the original text base. For example, 40px ÷ 16px becomes 2.5.

Back to Theme decisions · Next: material and light