Skip to main content
Light Dark System

Section

<cw-section> | CwSection
Since 1.6 experimental

A full-width band of page content with a capped, centered content width, vertical padding and an optional background.

<cw-section> is one band of a page: a heading and some content, with room above and below, a content width that stops growing on wide screens, and optionally a background color that runs the full width. Stack sections to build a page.

Get started

Install the library, add a theme, and start using components in plain HTML.

Read the guide
<cw-section surface="alt" label="Getting started">
  <cw-stack gap="small">
    <h3 class="section-flush">Get started</h3>
    <p class="section-flush">Install the library, add a theme, and start using components in plain HTML.</p>
    <div><cw-button variant="primary">Read the guide</cw-button></div>
  </cw-stack>
</cw-section>

<style>
  .section-flush {
    margin: 0;
  }
</style>
import CwButton from '@cordwainer/cw-elements/dist/react/button';
import CwSection from '@cordwainer/cw-elements/dist/react/section';
import CwStack from '@cordwainer/cw-elements/dist/react/stack';

const css = `
  .section-flush {
    margin: 0;
  }
`;

const App = () => (
  <>
    <CwSection surface="alt" label="Getting started">
      <CwStack gap="small">
        <h3 className="section-flush">Get started</h3>
        <p className="section-flush">Install the library, add a theme, and start using components in plain HTML.</p>
        <div>
          <CwButton variant="primary">Read the guide</CwButton>
        </div>
      </CwStack>
    </CwSection>

    <style>{css}</style>
  </>
);

See Page Layout for how sections, grids and stacks combine into a full page.

Examples

Width

Use width to cap how wide the content can grow: narrow (a comfortable reading measure), default or wide. The caps come from the layout tokens. full removes the cap. In every case the background spans the whole section, and the content is centered.

Narrow
Default
Wide
Full
<cw-section width="narrow" surface="alt">
  <div class="section-box">Narrow</div>
</cw-section>

<cw-section width="default" surface="alt">
  <div class="section-box">Default</div>
</cw-section>

<cw-section width="wide" surface="alt">
  <div class="section-box">Wide</div>
</cw-section>

<cw-section width="full" surface="alt">
  <div class="section-box">Full</div>
</cw-section>

<style>
  .section-box {
    padding: var(--cw-spacing-medium);
    border-radius: var(--cw-border-radius-medium);
    background: var(--cw-color-primary-100);
    color: var(--cw-color-primary-800);
    font-weight: var(--cw-font-weight-semibold);
  }
</style>
import CwSection from '@cordwainer/cw-elements/dist/react/section';

const css = `
  .section-box {
    padding: var(--cw-spacing-medium);
    border-radius: var(--cw-border-radius-medium);
    background: var(--cw-color-primary-100);
    color: var(--cw-color-primary-800);
    font-weight: var(--cw-font-weight-semibold);
  }
`;

const App = () => (
  <>
    <CwSection width="narrow" surface="alt">
      <div className="section-box">Narrow</div>
    </CwSection>

    <CwSection width="default" surface="alt">
      <div className="section-box">Default</div>
    </CwSection>

    <CwSection width="wide" surface="alt">
      <div className="section-box">Wide</div>
    </CwSection>

    <CwSection width="full" surface="alt">
      <div className="section-box">Full</div>
    </CwSection>

    <style>{css}</style>
  </>
);

Padding and Gutter

Use padding-block to set the space above and below the content, and gutter to set the space on its left and right. Both take a spacing token name, from 3x-small to 4x-large. The defaults are 2x-large and medium.

Small padding and gutter

Large padding and gutter
<cw-section padding-block="small" gutter="small" surface="alt">
  <div class="section-box">Small padding and gutter</div>
</cw-section>

<br />

<cw-section padding-block="4x-large" gutter="4x-large" surface="alt">
  <div class="section-box">Large padding and gutter</div>
</cw-section>

<style>
  .section-box {
    padding: var(--cw-spacing-medium);
    border-radius: var(--cw-border-radius-medium);
    background: var(--cw-color-primary-100);
    color: var(--cw-color-primary-800);
    font-weight: var(--cw-font-weight-semibold);
  }
</style>
import CwSection from '@cordwainer/cw-elements/dist/react/section';

const css = `
  .section-box {
    padding: var(--cw-spacing-medium);
    border-radius: var(--cw-border-radius-medium);
    background: var(--cw-color-primary-100);
    color: var(--cw-color-primary-800);
    font-weight: var(--cw-font-weight-semibold);
  }
`;

const App = () => (
  <>
    <CwSection paddingBlock="small" gutter="small" surface="alt">
      <div className="section-box">Small padding and gutter</div>
    </CwSection>

    <br />

    <CwSection paddingBlock="4x-large" gutter="4x-large" surface="alt">
      <div className="section-box">Large padding and gutter</div>
    </CwSection>

    <style>{css}</style>
  </>
);

Flush

Add flush to drop the gutter to zero when the section is narrower than --cw-section-flush-below (40rem by default). On a phone the content and background then run edge to edge, while wider sections keep their gutter. It responds to the section’s own width, not the viewport’s, so the narrow container below shows the effect at any screen size.

Flush: no gutter at this width

Not flush: the gutter stays
<div class="section-frame" style="width: 20rem;">
  <cw-section flush surface="alt" padding-block="medium">
    <div class="section-box">Flush: no gutter at this width</div>
  </cw-section>
</div>

<br />

<div class="section-frame" style="width: 20rem;">
  <cw-section surface="alt" padding-block="medium">
    <div class="section-box">Not flush: the gutter stays</div>
  </cw-section>
</div>

<style>
  .section-box {
    padding: var(--cw-spacing-medium);
    border-radius: var(--cw-border-radius-medium);
    background: var(--cw-color-primary-100);
    color: var(--cw-color-primary-800);
    font-weight: var(--cw-font-weight-semibold);
  }

  .section-frame {
    border: 1px dashed var(--cw-color-neutral-300);
  }
</style>
import CwSection from '@cordwainer/cw-elements/dist/react/section';

const css = `
  .section-box {
    padding: var(--cw-spacing-medium);
    border-radius: var(--cw-border-radius-medium);
    background: var(--cw-color-primary-100);
    color: var(--cw-color-primary-800);
    font-weight: var(--cw-font-weight-semibold);
  }

  .section-frame {
    border: 1px dashed var(--cw-color-neutral-300);
  }
`;

const App = () => (
  <>
    <div className="section-frame" style={{ width: '20rem' }}>
      <CwSection flush surface="alt" paddingBlock="medium">
        <div className="section-box">Flush: no gutter at this width</div>
      </CwSection>
    </div>

    <br />

    <div className="section-frame" style={{ width: '20rem' }}>
      <CwSection surface="alt" paddingBlock="medium">
        <div className="section-box">Not flush: the gutter stays</div>
      </CwSection>
    </div>

    <style>{css}</style>
  </>
);

Set --cw-section-flush-below on :root to change the threshold everywhere, or on one section.

cw-section {
  --cw-section-flush-below: 30rem;
}

Surface

Use surface to choose a background and text color. default is transparent and inherits the text color, alt is a subtle neutral, primary uses the same colors as a primary button, and inverse is dark in a light theme and light in a dark theme.

Default Alt Primary Inverse
<cw-section surface="default" padding-block="medium">Default</cw-section>
<cw-section surface="alt" padding-block="medium">Alt</cw-section>
<cw-section surface="primary" padding-block="medium">Primary</cw-section>
<cw-section surface="inverse" padding-block="medium">Inverse</cw-section>
import CwSection from '@cordwainer/cw-elements/dist/react/section';

const App = () => (
  <>
    <CwSection surface="default" paddingBlock="medium">Default</CwSection>
    <CwSection surface="alt" paddingBlock="medium">Alt</CwSection>
    <CwSection surface="primary" paddingBlock="medium">Primary</CwSection>
    <CwSection surface="inverse" paddingBlock="medium">Inverse</CwSection>
  </>
);

Custom Background

Set --cw-section-background to replace the surface’s background with any CSS background color. The surface’s text color is kept, so choose a background that keeps enough contrast with it.

A custom background
<cw-section surface="inverse" style="--cw-section-background: var(--cw-color-success-700);" padding-block="medium">
  A custom background
</cw-section>
import CwSection from '@cordwainer/cw-elements/dist/react/section';

const App = () => (
  <CwSection
    surface="inverse"
    style={{ '--cw-section-background': 'var(--cw-color-success-700)' }}
    paddingBlock="medium"
  >
    A custom background
  </CwSection>
);

Label

Add a label to make the section a named region landmark, so screen reader users can list the page’s regions and jump between them. Use it for substantial sections with a clear purpose. Without a label, the section is a plain wrapper and adds no landmark, which avoids cluttering the page with unnamed regions.

Pricing

<cw-section label="Pricing" surface="alt" padding-block="medium">
  <h3 style="margin: 0;">Pricing</h3>
</cw-section>
import CwSection from '@cordwainer/cw-elements/dist/react/section';

const App = () => (
  <CwSection label="Pricing" surface="alt" paddingBlock="medium">
    <h3 style={{ margin: 0 }}>Pricing</h3>
  </CwSection>
);

Sections with a Grid of Stacks

Sections, grids and stacks are designed to nest: a section sets the band and its width, a grid lays out the columns, and each cell is a stack.

Features

Components

Accessible, themeable components built on web standards.

Tokens

Color, spacing and typography tokens you can override per theme.

Frameworks

Works anywhere HTML does, with generated wrappers for React.

<cw-section surface="alt" label="Features">
  <cw-stack gap="large">
    <h3 class="section-flush">Features</h3>
    <cw-grid columns="3" min-column-width="10rem">
      <cw-stack gap="small">
        <h4 class="section-flush">Components</h4>
        <p class="section-flush">Accessible, themeable components built on web standards.</p>
      </cw-stack>

      <cw-stack gap="small">
        <h4 class="section-flush">Tokens</h4>
        <p class="section-flush">Color, spacing and typography tokens you can override per theme.</p>
      </cw-stack>

      <cw-stack gap="small">
        <h4 class="section-flush">Frameworks</h4>
        <p class="section-flush">Works anywhere HTML does, with generated wrappers for React.</p>
      </cw-stack>
    </cw-grid>
  </cw-stack>
</cw-section>

<style>
  .section-flush {
    margin: 0;
  }
</style>
import CwGrid from '@cordwainer/cw-elements/dist/react/grid';
import CwSection from '@cordwainer/cw-elements/dist/react/section';
import CwStack from '@cordwainer/cw-elements/dist/react/stack';

const css = `
  .section-flush {
    margin: 0;
  }
`;

const App = () => (
  <>
    <CwSection surface="alt" label="Features">
      <CwStack gap="large">
        <h3 className="section-flush">Features</h3>
        <CwGrid columns="3" minColumnWidth="10rem">
          <CwStack gap="small">
            <h4 className="section-flush">Components</h4>
            <p className="section-flush">Accessible, themeable components built on web standards.</p>
          </CwStack>

          <CwStack gap="small">
            <h4 className="section-flush">Tokens</h4>
            <p className="section-flush">Color, spacing and typography tokens you can override per theme.</p>
          </CwStack>

          <CwStack gap="small">
            <h4 className="section-flush">Frameworks</h4>
            <p className="section-flush">Works anywhere HTML does, with generated wrappers for React.</p>
          </CwStack>
        </CwGrid>
      </CwStack>
    </CwSection>

    <style>{css}</style>
  </>
);

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Script Import Bundler React

To import this component from the CDN using a script tag:

<script type="module" src="https://cdn.jsdelivr.net/npm/@cordwainer/cw-elements@1.6.0/cdn/components/section/section.js"></script>

To import this component from the CDN using a JavaScript import:

import 'https://cdn.jsdelivr.net/npm/@cordwainer/cw-elements@1.6.0/cdn/components/section/section.js';

To import this component using a bundler:

import '@cordwainer/cw-elements/dist/components/section/section.js';

To import this component as a React component:

import CwSection from '@cordwainer/cw-elements/dist/react/section';

Slots

Name Description
(default) The section’s content.

Learn more about using slots.

Properties

Name Description Reflects Type Default
width How wide the content can grow before it stops and centers, as a layout width token name (narrow, default or wide). full has no cap. The background always spans the whole section. 'narrow' | 'default' | 'wide' | 'full' 'default'
paddingBlock
padding-block
The space above and below the content, as a spacing token name. '3x-small' | '2x-small' | 'x-small' | 'small' | 'medium' | 'large' | 'x-large' | '2x-large' | '3x-large' | '4x-large' '2x-large'
gutter The space on the left and right of the content, as a spacing token name. '3x-small' | '2x-small' | 'x-small' | 'small' | 'medium' | 'large' | 'x-large' | '2x-large' | '3x-large' | '4x-large' 'medium'
flush Removes the gutter when the section is narrower than --cw-section-flush-below, so content and background run edge to edge on phones. boolean false
surface The background and text color. default is transparent, alt is a subtle neutral, primary matches a primary button and inverse is dark in a light theme and light in a dark theme. 'default' | 'alt' | 'primary' | 'inverse' 'default'
label A name for the section. When set, the section is a region landmark that assistive technology can list and jump to. Without one, the section is a plain wrapper and adds no landmark. string | undefined -
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Custom Properties

Name Description Default
--cw-section-background Overrides the background of the chosen surface. Any CSS background color.
--cw-section-flush-below With flush, the side gutter is removed when the section is narrower than this. Set it on :root to change it everywhere, or on one section. 40rem

Learn more about customizing CSS custom properties.

Parts

Name Description
base The component’s base wrapper, which draws the background and padding and spans the section’s full width.

Learn more about customizing CSS parts.