Section
<cw-section> | CwSection
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.
<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> </> );
A section is a block-level element that fills the width of whatever contains it. The background and padding always span that full width, while the content inside is capped and centered.
Leave horizontal padding to your sections. If the page container around them has its own side padding, a
section’s background stops short of the screen edge and flush can’t reach it. Give the page
container no side padding and let each section’s gutter provide it.
Sections deliberately don’t break out of their container with negative margins or viewport units, because that causes a horizontal scrollbar whenever a vertical one is present.
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.
<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> </> );
An unknown width, padding-block, gutter or
surface value falls back to the default and logs a warning to the console naming the value,
so a typo never silently changes the layout.
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.
<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.
<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.
<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.
<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.
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.