Skip to main content
Light Dark System

Stack

<cw-stack> | CwStack
Since 1.6 experimental

Spaces its children vertically with one consistent gap.

<cw-stack> lays its children out top to bottom, with the same space between each one. It’s the usual way to put a heading, some text and a button together, in a card or in one cell of a grid. There are no wrappers to add: each direct child is an item.

Get started

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

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

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

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

const App = () => (
  <>
    <CwStack>
      <h3 className="stack-flush">Get started</h3>
      <p className="stack-flush">Install the library, add a theme, and start using components in plain HTML.</p>
      <CwButton variant="primary">Read the guide</CwButton>
    </CwStack>

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

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

Examples

Gap

Use gap to set the space between items. It takes a spacing token name, from 3x-small to 4x-large. The default is medium.

One
Two
Three
One
Two
Three
<cw-grid columns="2" min-column-width="8rem">
  <cw-stack gap="x-small">
    <div class="stack-box">One</div>
    <div class="stack-box">Two</div>
    <div class="stack-box">Three</div>
  </cw-stack>

  <cw-stack gap="2x-large">
    <div class="stack-box">One</div>
    <div class="stack-box">Two</div>
    <div class="stack-box">Three</div>
  </cw-stack>
</cw-grid>

<style>
  .stack-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 CwGrid from '@cordwainer/cw-elements/dist/react/grid';
import CwStack from '@cordwainer/cw-elements/dist/react/stack';

const css = `
  .stack-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 = () => (
  <>
    <CwGrid columns="2" minColumnWidth="8rem">
      <CwStack gap="x-small">
        <div className="stack-box">One</div>
        <div className="stack-box">Two</div>
        <div className="stack-box">Three</div>
      </CwStack>

      <CwStack gap="2x-large">
        <div className="stack-box">One</div>
        <div className="stack-box">Two</div>
        <div className="stack-box">Three</div>
      </CwStack>
    </CwGrid>

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

Alignment

Use align to position items horizontally. The default, stretch, makes every item as wide as the stack. start, center and end size each item to its content instead.

Start
A longer item
Center
A longer item
End
A longer item
<cw-grid columns="3" min-column-width="8rem">
  <cw-stack align="start">
    <div class="stack-box">Start</div>
    <div class="stack-box">A longer item</div>
  </cw-stack>

  <cw-stack align="center">
    <div class="stack-box">Center</div>
    <div class="stack-box">A longer item</div>
  </cw-stack>

  <cw-stack align="end">
    <div class="stack-box">End</div>
    <div class="stack-box">A longer item</div>
  </cw-stack>
</cw-grid>
import CwGrid from '@cordwainer/cw-elements/dist/react/grid';
import CwStack from '@cordwainer/cw-elements/dist/react/stack';

const App = () => (
  <CwGrid columns="3" minColumnWidth="8rem">
    <CwStack align="start">
      <div className="stack-box">Start</div>
      <div className="stack-box">A longer item</div>
    </CwStack>

    <CwStack align="center">
      <div className="stack-box">Center</div>
      <div className="stack-box">A longer item</div>
    </CwStack>

    <CwStack align="end">
      <div className="stack-box">End</div>
      <div className="stack-box">A longer item</div>
    </CwStack>
  </CwGrid>
);

Stacks in a Grid

A grid of stacks is how most content rows are built: each grid cell is a stack, so every cell’s heading, text and button are spaced the same way.

Components

Accessible, themeable components built on web standards.

Browse

Tokens

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

Browse

Frameworks

Works anywhere HTML does, with generated wrappers for React.

Browse
<cw-grid columns="3" min-column-width="10rem">
  <cw-stack gap="small">
    <h4 class="stack-flush">Components</h4>
    <p class="stack-flush">Accessible, themeable components built on web standards.</p>
    <cw-button size="small">Browse</cw-button>
  </cw-stack>

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

  <cw-stack gap="small">
    <h4 class="stack-flush">Frameworks</h4>
    <p class="stack-flush">Works anywhere HTML does, with generated wrappers for React.</p>
    <cw-button size="small">Browse</cw-button>
  </cw-stack>
</cw-grid>
import CwButton from '@cordwainer/cw-elements/dist/react/button';
import CwGrid from '@cordwainer/cw-elements/dist/react/grid';
import CwStack from '@cordwainer/cw-elements/dist/react/stack';

const App = () => (
  <CwGrid columns="3" minColumnWidth="10rem">
    <CwStack gap="small">
      <h4 className="stack-flush">Components</h4>
      <p className="stack-flush">Accessible, themeable components built on web standards.</p>
      <CwButton size="small">Browse</CwButton>
    </CwStack>

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

    <CwStack gap="small">
      <h4 className="stack-flush">Frameworks</h4>
      <p className="stack-flush">Works anywhere HTML does, with generated wrappers for React.</p>
      <CwButton size="small">Browse</CwButton>
    </CwStack>
  </CwGrid>
);

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/stack/stack.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/stack/stack.js';

To import this component using a bundler:

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

To import this component as a React component:

import CwStack from '@cordwainer/cw-elements/dist/react/stack';

Slots

Name Description
(default) The stack’s items, laid out top to bottom in source order.

Learn more about using slots.

Properties

Name Description Reflects Type Default
gap The space between items, as a spacing token name. Items’ own margins are kept, and add to it. '3x-small' | '2x-small' | 'x-small' | 'small' | 'medium' | 'large' | 'x-large' | '2x-large' | '3x-large' | '4x-large' 'medium'
align How items are aligned horizontally. stretch makes every item as wide as the stack; the others size each item to its content and place it at the start, center or end. 'stretch' | 'start' | 'center' | 'end' 'stretch'
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Parts

Name Description
base The component’s base wrapper, which lays out the slotted items.

Learn more about customizing CSS parts.