Field Guide / advanced

Fluid spacing without breakpoint sprawl

Responsive spacing should protect relationships between elements, not just grow because the viewport got wider.

Live demo

Responsive type scale playground

Open demo page

Expected behavior

Sliders update the preview immediately while measure and line height remain explicit CSS constraints.

Accessibility notes

Range controls use visible labels and the preview is regular document text, not a canvas image.

CSS used in this demo
.tool {
  display: grid;
  gap: 1.25rem;
  padding: 1.5rem;
}

form {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}

label {
  display: grid;
  gap: 0.35rem;
  font-weight: 700;
}

input {
  accent-color: #0f8b8d;
}

.preview {
  --heading: 48px;
  --leading: 1.45;
  --measure: 62ch;
  max-width: var(--measure);
  border: 2px solid #171717;
  border-radius: 8px;
  background: #ffffff;
  padding: 1.5rem;
}

.kicker {
  color: #0a6a6c;
  font-size: 0.78rem;
  font-weight: 800;
  text-transform: uppercase;
}

.preview h1 {
  margin: 0.25rem 0 1rem;
  font-size: var(--heading);
  line-height: 1.05;
}

.preview p:last-child {
  margin: 0;
  font-size: 1.1rem;
  line-height: var(--leading);
}

Spacing systems fail when every component invents its own breakpoint. The result is a page where sections grow at different widths for reasons nobody can explain.

The better approach is to define spacing relationships and let components opt into a small set of page rhythms.

Use tokens for rhythm, not decoration

:root {
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
}

A spacing scale is not valuable because it has many values. It is valuable because it limits arguments. If a card body uses --space-4 and a section uses --space-6, the relationship is visible.

Change rhythm at layout boundaries

Instead of writing custom media queries inside every component, adjust section or layout variables at the boundary.

.page-section {
  --section-space: 3rem;
  padding-block: var(--section-space);
}

@media (min-width: 48rem) {
  .page-section {
    --section-space: 5rem;
  }
}

Components inside the section can use local spacing without knowing about the viewport.

Avoid fluid values where stability matters

Fluid spacing can be useful for editorial pages, but fixed-format UI elements need stable dimensions. Toolbars, icon buttons, board cells, and dense dashboards often behave better with defined sizes and media-query steps. The goal is not to make every value fluid. The goal is to prevent layout jumps and overlap.

Test with real content

Spacing that looks good with short labels can fail with localization, long product names, or code snippets. Before calling a spacing system done, test it with:

  • A long heading.
  • A card with missing media.
  • A form label that wraps.
  • A table or code block inside the main column.

Responsive spacing is a content problem as much as a viewport problem.

References