Skip to content

Section

Hero example

Section content

When to use

Reach for <Section> whenever you're composing a marketing or content page with vertical rhythm — every major page block on the marketing site (Hero, How It Works, Pricing, Footer) is a Section. The component renders a real <section> element and applies the canonical vertical padding (configurable via tight for denser sections). bloom paints a tinted background and cascades the matching tint to nested button glows; glow cascades the tint without the backdrop.

Don't reach for Section for individual cards — that's Card. Don't use it for full-screen overlays — that's Sheet. Section is the page-level rhythm wrapper.

Do — pair every Section with a <Container> for max-width body content. Section is full-bleed; Container is constrained.
Don't — nest Section inside Section. The vertical rhythm compounds and breaks.

Anatomy

A single <section> element with:

  • One of .section (default 96px vertical padding) or .section-tight (48px).
  • Optionally .bloom-{tone} — paints a soft tinted backdrop AND sets --btn-glow so child buttons inherit the matching tint on hover.
  • Optionally .glow-{tone} — sets the --btn-glow cascade only (no backdrop).
  • position: relative so absolute children (e.g. BloomBackdrop) anchor inside.

All HTMLAttributes<HTMLElement> pass through via spread.

Props

PropTypeDefaultDescription
tightbooleanfalse
bloom"peach" | "amber" | "lavender" | "sage"
glow"blue" | "pink" | "lime"
childrenReact.ReactNode

Also accepts Omit<React.HTMLAttributes<HTMLElement>, "children">.

bloom and glow are mutually exclusive in practice — setting both works but produces a redundant tint. Pick one based on whether you want the painted background.

States

Stateless.

Density

The tight prop is the density lever — tight: true halves the vertical padding (96 → 48). The site-level density toggle has no effect.

Themes

Section content
Section content
Section content

In dark, bloom backdrops shift to their dark-theme variants. In forced-colors, bloom backdrops collapse to Canvas — the painted identity is lost but the layout is preserved.

Tokens consumed

No tokens match. No tokens match.

Bloom backdrops read --bloom-{tone}-bg (peach, amber, lavender, sage). Vertical padding reads --section-y / --section-y-tight. Button glow propagation uses --btn-glow.

Accessibility

  • Keyboard interactions. None on the Section itself. Children carry their own contracts.
  • ARIA roles and properties. Renders a semantic <section>. To make it a named region for screen readers, place an <h2> inside and set aria-labelledby on the section pointing to the heading's id.
  • Focus order. N/A on the section.
  • Screen-reader expectations. Announces as a region. Without aria-labelledby it's an unnamed region (some readers skip).
  • Reduced motion. N/A.
  • Forced colors. Bloom paints disappear. Vertical padding preserved.
  • WIG rules. <section> over <div> (semantic-element rule). bloom cascade keeps button glow consistent with the section's emotional cue (color consistency rule).

Do / Don't

Do — match bloom to the lifecycle phase or emotional cue of the section. Peach for "create" / open / welcoming. Amber for "manage" / steady. Lavender for "reflective" / settings. Sage for "complete" / verified.
Don't — render Section without a Container inside. Page-level rhythm is the Section's job; max-width is the Container's.
Do — use tight for sections that are visually paired (a hero immediately followed by a sub-hero). The 48px padding maintains the relationship.
Don't — set inline padding-block. The recipe handles vertical rhythm; consumers shouldn't override.
Do — set id for in-page anchored navigation. <Section id="how-it-works"> becomes #how-it-works reachable from the in-page TOC.
Don't — render named sections without an <h2> inside. The semantic region needs a heading to be useful to assistive tech.

Recipes

This component appears in:

  • Every marketing-site page (Hero, How It Works, Pricing, Footer).
  • Docs corpus recipe — the page-section wrapper.

Code example

import { Section, Container, DisplayHeading } from "@matter/components";

export function HowItWorks() {
  return (
    <Section bloom="peach" id="how-it-works" aria-labelledby="how-it-works-h">
      <Container>
        <DisplayHeading as="h2" size="hero" id="how-it-works-h">
          How Matter works.
        </DisplayHeading>
        {/* body */}
      </Container>
    </Section>
  );
}

Source

packages/components/src/Section

On this page