A full-width band with vertical rhythm and an optional Container, used to lay out page content.

Last updated

Section content, centered by its inner Container.

Show code
<Section spacing="medium">
<p class="text-neutral">Section content, centered by its inner Container.</p>
</Section>

Add

npx @ava-ui/apogee add section

Pulls in Container.

Usage

---
import Section from '@/components/apogee/Section/Section.astro'
---
<Section spacing="large">
  <h2>About us</h2>
  <p>…</p>
</Section>

Anatomy

  • Content (default slot) — wrapped in a Container unless container={false}.
  • slot="background" — renders full-bleed behind the content (absolute inset-0 -z-10), for a background image/gradient/pattern that should ignore the Container’s width.

API

@composable — exposed to Content Editors in AVA. Any other attribute passes through to the root element.

Prop Type Default Description
as string 'section' Element/tag to render.
theme 'inherit' | 'light' | 'dark' 'inherit' Flips design tokens for this section and everything inside it (sets data-theme).
spacing 'none' | 'small' | 'medium' | 'large' | 'xlarge' 'large' Vertical padding.
background 'page' | 'neutral-faded' | 'primary-faded' | 'primary' | 'inverted' — Surface token for the band; solid fills also set the on-colour text.
containerWidth 'small' | 'medium' | 'large' | 'xlarge' | 'full' 'large' Width of the inner Container.
container boolean true Set false to skip the inner Container — content spans full width.
class string — Extra classes, merged last.

Variants

theme re-colors the section and its whole subtree by flipping tokens — every variant:

theme=“light”

theme=“dark”

Show code
<Section theme="light" spacing="small"><p>theme="light"</p></Section>
<Section theme="dark" spacing="small"><p>theme="dark"</p></Section>

Every background:

background=“page”

background=“neutral-faded”

background=“primary-faded”

background=“primary”

background=“inverted”

Show code
<Section background="page" spacing="none"><p class="px-4 py-3">background="page"</p></Section>
<Section background="neutral-faded" spacing="none"><p class="px-4 py-3">background="neutral-faded"</p></Section>
<Section background="primary-faded" spacing="none"><p class="px-4 py-3">background="primary-faded"</p></Section>
<Section background="primary" spacing="none"><p class="px-4 py-3">background="primary"</p></Section>
<Section background="inverted" spacing="none"><p class="px-4 py-3">background="inverted"</p></Section>

Sizes

Every spacing value:

spacing=“none”

spacing=“small”

spacing=“medium”

spacing=“large”

spacing=“xlarge”

Show code
<Section spacing="none"><p class="border border-dashed border-neutral p-2 text-sm">spacing="none"</p></Section>
<Section spacing="small"><p class="border border-dashed border-neutral p-2 text-sm">spacing="small"</p></Section>
<Section spacing="medium"><p class="border border-dashed border-neutral p-2 text-sm">spacing="medium"</p></Section>
<Section spacing="large"><p class="border border-dashed border-neutral p-2 text-sm">spacing="large"</p></Section>
<Section spacing="xlarge"><p class="border border-dashed border-neutral p-2 text-sm">spacing="xlarge"</p></Section>

Every containerWidth value:

containerWidth=“small”
containerWidth=“medium”
containerWidth=“large”
containerWidth=“xlarge”
containerWidth=“full”
Show code
<Section containerWidth="small" spacing="small"><div class="border border-dashed border-neutral p-2 text-sm">containerWidth="small"</div></Section>
<Section containerWidth="medium" spacing="small"><div class="border border-dashed border-neutral p-2 text-sm">containerWidth="medium"</div></Section>
<Section containerWidth="large" spacing="small"><div class="border border-dashed border-neutral p-2 text-sm">containerWidth="large"</div></Section>
<Section containerWidth="xlarge" spacing="small"><div class="border border-dashed border-neutral p-2 text-sm">containerWidth="xlarge"</div></Section>
<Section containerWidth="full" spacing="small"><div class="border border-dashed border-neutral p-2 text-sm">containerWidth="full"</div></Section>

States

Section is a static layout wrapper — no interactive states.

Examples

A full-bleed background behind Container-width content:

Full-bleed background

The gradient spans edge-to-edge; the heading stays inside the Container.

Show code
<Section spacing="large">
<div slot="background" class="h-full bg-gradient-to-br from-primary/20 to-transparent" />
<h2 class="text-2xl font-semibold text-neutral">Full-bleed background</h2>
<p class="text-neutral-faded">The gradient spans edge-to-edge; the heading stays inside the Container.</p>
</Section>

Skipping the Container for something that should span edge-to-edge:

<Section container={false} spacing="none">
  <img src="/hero.jpg" alt="" class="w-full" />
</Section>

Accessibility

  • as picks the rendered element — choose a real landmark (section, nav, aside, …) rather than leaving every Section a generic <section> when a page has several; give repeated landmarks of the same type an accessible name (aria-label / aria-labelledby).
  • theme only flips CSS custom properties (data-theme) — it carries no ARIA implications.
  • Native semantics otherwise — no extra ARIA needed.

Tokens

Token Used for
--background-page Section fill, only when theme isn’t inherit
--foreground-neutral Section text color, only when theme isn’t inherit

A themed Section flips the token context for its whole subtree — every component nested inside also reads its own tokens from that context; see each component’s own Tokens table.

Do / Don’t

Layout primitive — no content or misuse surface of its own; guidance lives on the components placed inside it.

Content

Layout primitive — no text of its own.