Section

.section is one declaration — padding-block: var(--space-section) — where the token is clamp(2.5rem, 1.4rem + 5.5vw, 6rem). It is the vertical counterpart of the page gutter: breathing room between the major parts of a page that grows with the viewport instead of stepping at breakpoints.

When to use it

Use it on the outermost band of each part of a page — usually a <section> or <header> element, with a .container inside it. The section owns the vertical rhythm and any background; the container owns the width.

Two bands. Resize the window and the padding follows.

First section

Second section

<div class="stack stack-0"> <section class="section" style="background:var(--surface-2)"> <div class="container"><h3>First section</h3></div> </section> <section class="section"> <div class="container"><h3>Second section</h3></div> </section> </div>
<div class="stack stack-0">
  <section class="section" style="background:var(--surface-2)">
    <div class="container"><h3>First section</h3></div>
  </section>
  <section class="section">
    <div class="container"><h3>Second section</h3></div>
  </section>
</div>

Why a clamp

clamp(2.5rem, 1.4rem + 5.5vw, 6rem) reads as: never less than 2.5rem, never more than 6rem, and in between it grows with the viewport at 5.5% of its width.

The alternative is a media query that jumps from 2.5rem to 6rem at some width. The clamp is better for a reason that is easy to miss: there is no width at which the page suddenly changes shape. Drag a browser window across a breakpoint and a stepped layout visibly lurches; a clamped one slides. It also means there is no width that was never designed for, because every width gets a value on the same line.

The same reasoning produces --space-gutter: clamp(1rem, .55rem + 2.2vw, 2rem). Between them, the two clamps are the whole of Deck's page-level spacing, and neither involves a breakpoint.

Padding, not margin

.section uses padding-block. That choice does two things that a margin would not:

  • Two adjacent sections do not collapse. Vertical margins merge into the larger of the two, so two sections with 6rem margins would be 6rem apart rather than 12rem. With padding, each section keeps its own space and the total is what it looks like.
  • A background covers the space. Padding is inside the box, so a section with a background colour has the breathing room within the colour. With a margin the band would be tight against its content and the space would be page-coloured — which is almost never the intent.

This is the same argument the stack page makes about gap versus margin, arriving at a different property for a different job. Deck's position is not that margins are wrong; it is that the container should own the spacing.

Not for spacing inside a component

At the top of its range .section is 6rem of padding, top and bottom. Inside a card that is close to two inches of nothing. For spacing within a component, use .stack and its steps — the largest, .stack-8, is 2rem.

The rule of thumb: if the element has a background that reaches the edge of the screen, .section is probably right. If it does not, .stack probably is.

Classes

One class, one declaration, no variants — so there is no component root and no completeness check on this page.

Classes, generated from the stylesheet source
Class Layer What it does Source
.section deck.layout Vertical page rhythm: a block of --space-section, which is a clamp that grows with the viewport. For spacing inside a component reach for .stack instead. 04-layout.css:161

Tokens

Design tokens this component reads
Token Live Declared value
--space-section clamp(2.5rem, 1.4rem + 5.5vw, 6rem)
--space-gutter clamp(1rem, .55rem + 2.2vw, 2rem)
--space-8 2rem

Accessibility

  • The class is not the element. .section supplies padding and nothing else — no role, no landmark. Put it on a real <section> with a heading, or on <header>/<footer>, if the division should exist for a screen reader as well as for the eye.
  • A <section> without an accessible name is not a landmark. Bare, it is exposed as a generic region or not at all. Give it a heading and aria-labelledby, or accept that it is visual grouping only.
  • Space is not a separator. 6rem between two blocks tells a sighted reader they are different things and tells a screen-reader user nothing. Headings are what carry that.
  • It scales with the reader's font size. The clamp's floor and ceiling are in rem, so at 200% zoom the padding grows too and the page keeps its proportions rather than becoming text crammed between fixed gaps.
  • The vw term does not respond to zoom in the same way — vw is a fraction of the viewport, so zooming in makes the middle term smaller in rem terms. The rem floor is what stops that mattering.

Right to left

padding-block is the block axis, which is unaffected by text direction. Nothing to do, and nothing that could go wrong.

Reduced motion

Nothing animates. The clamp resizes with the viewport, which is layout rather than motion, so prefers-reduced-motion has no bearing on it.

Printing

src/99-print.css replaces the padding with padding-block: 0 0 8mm: no space at the top, 8mm at the bottom. On screen the top padding separates a section from the one above it; on paper a section can start at the top of a page, and 6rem of white there would be a wasted third of a sheet. Keeping the bottom space preserves the separation without the waste.

Overriding it

/* One section, no layer needed */
<section class="section" style="--space-section:3rem">

@layer app.pages {
  /* Change the page rhythm everywhere */
  :root { --space-section: clamp(2rem, 1rem + 4vw, 4.5rem); }

  /* A section that only pads the bottom */
  .section-tail { padding-block: 0 var(--space-section); }
}

Overriding --space-section on :root is the intended way to change a page's vertical rhythm, and it moves every section together. Setting padding-block on .section instead works but leaves the token pointing at a value nothing uses.

When not to use it

  • Not inside a card, a modal or a panel. Its padding is page-scale. Use .stack, or the component's own padded region — .card-body already has one.
  • Not for the space between two paragraphs. That is a .stack step, or .prose if the content is rendered Markdown.
  • Not on the same element as .container. It works, but then the background is capped at the container's width and stops short of the screen edges. Section outside, container inside.
  • Not stacked with a .stack-8 as well. Two spacing systems on the same axis is how a page ends up with gaps nobody chose. Pick the one that matches the scale you are working at.
  • Not as a replacement for a heading. If the reader needs to know a new topic has started, write one. The padding is the visual echo of the structure, not the structure.