Lays children out in a column or row with a consistent gap — the default way to space a group of elements.

Last updated

One
Two
Three
Show code
<Stack gap={4}>
<div class="rounded-md bg-neutral-faded p-3">One</div>
<div class="rounded-md bg-neutral-faded p-3">Two</div>
<div class="rounded-md bg-neutral-faded p-3">Three</div>
</Stack>

Add

npx @ava-ui/apogee add stack

No Apogee component dependencies.

Usage

---
import Stack from '@/components/apogee/Stack/Stack.astro'
---
<Stack gap={2}>
  <p>First</p>
  <p>Second</p>
</Stack>

API

@composable — exposed to Content Editors in AVA. Any other attribute passes through onto the rendered tag.

Prop Type Default Description
as string 'div' Element/tag to render.
direction 'column' | 'row' | 'column-reverse' | 'row-reverse', responsive 'column' Stack axis.
gap 0 … 6 | 8 | 10 | 12 | 16, responsive 4 Gap between children (Tailwind’s numeric spacing scale).
align 'start' | 'center' | 'end' | 'stretch' | 'baseline', responsive — Cross-axis alignment (items-*).
justify 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly', responsive — Main-axis distribution (justify-*).
wrap boolean, responsive — Allows children to wrap (flex-wrap).
class string — Extra classes, merged last.

Responsive values

Every layout prop accepts a value or an object keyed by breakpoint (T | { base?, sm?, md?, lg?, xl? }, mobile first, Tailwind’s sm 640px, md 768px, lg 1024px, xl 1280px). Resize the window to see the direction flip:

One
Two
Three
Show code
<Stack direction={{ base: 'column', md: 'row' }} gap={{ base: 2, md: 6 }} align={{ md: 'center' }}>
<div>One</div><div>Two</div><div>Three</div>
</Stack>

Variants

Direction

A
B
A
B
Show code
<Stack direction="row" gap={2}>
<div class="rounded-md bg-neutral-faded p-3">A</div>
<div class="rounded-md bg-neutral-faded p-3">B</div>
</Stack>
<Stack direction="column" gap={2}>
<div class="rounded-md bg-neutral-faded p-3">A</div>
<div class="rounded-md bg-neutral-faded p-3">B</div>
</Stack>

Gap

Every value on the scale:

gap=0
gap=1
gap=2
gap=3
gap=4
gap=5
gap=6
gap=8
gap=10
gap=12
Show code
<Stack gap={2}>
<Stack direction="row" gap={0} align="center"><span class="w-12 text-xs">gap=0</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={1} align="center"><span class="w-12 text-xs">gap=1</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={2} align="center"><span class="w-12 text-xs">gap=2</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={3} align="center"><span class="w-12 text-xs">gap=3</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={4} align="center"><span class="w-12 text-xs">gap=4</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={5} align="center"><span class="w-12 text-xs">gap=5</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={6} align="center"><span class="w-12 text-xs">gap=6</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={8} align="center"><span class="w-12 text-xs">gap=8</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={10} align="center"><span class="w-12 text-xs">gap=10</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
<Stack direction="row" gap={12} align="center"><span class="w-12 text-xs">gap=12</span><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div><div class="size-4 rounded bg-primary"></div></Stack>
</Stack>

Align

start
center
end
stretch
Show code
<Stack direction="row" align="start" gap={2} class="h-16 bg-neutral-faded">
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">start</div>
</Stack>
<Stack direction="row" align="center" gap={2} class="h-16 bg-neutral-faded">
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">center</div>
</Stack>
<Stack direction="row" align="end" gap={2} class="h-16 bg-neutral-faded">
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">end</div>
</Stack>
<Stack direction="row" align="stretch" gap={2} class="h-16 bg-neutral-faded">
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">stretch</div>
</Stack>

Justify

start
center
end
A
B
Show code
<Stack direction="row" justify="start" gap={2} class="w-full bg-neutral-faded p-2">
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">start</div>
</Stack>
<Stack direction="row" justify="center" gap={2} class="w-full bg-neutral-faded p-2">
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">center</div>
</Stack>
<Stack direction="row" justify="end" gap={2} class="w-full bg-neutral-faded p-2">
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">end</div>
</Stack>
<Stack direction="row" justify="between" gap={2} class="w-full bg-neutral-faded p-2">
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">A</div>
<div class="rounded-md bg-primary p-2 text-xs text-on-primary">B</div>
</Stack>

Wrap

One
Two
Three
Four
Show code
<Stack direction="row" gap={2} wrap class="w-48">
<div class="rounded-md bg-neutral-faded p-3">One</div>
<div class="rounded-md bg-neutral-faded p-3">Two</div>
<div class="rounded-md bg-neutral-faded p-3">Three</div>
<div class="rounded-md bg-neutral-faded p-3">Four</div>
</Stack>

States

Not applicable — Stack is a static layout primitive with no interactive states.

Examples

Polymorphic tag for correct semantics:

<Stack as="ul" gap={1}>
  <li>First</li>
  <li>Second</li>
  <li>Third</li>
</Stack>

Nested Stacks — a vertical form with a right-aligned button row:

<Stack gap={4}>
  <input class="rounded-md border border-neutral px-3 py-2" placeholder="Email" />
  <Stack direction="row" gap={2} justify="end">
    <button class="rounded-md border border-neutral px-3 py-2 text-sm">Cancel</button>
    <button class="rounded-md bg-primary px-3 py-2 text-sm text-on-primary">Save</button>
  </Stack>
</Stack>

Accessibility

Native semantics, no extra ARIA needed. Stack renders a plain container (<div> by default, or your chosen as tag) with no interactive behavior of its own — pick an as value with the right semantics for your content (ul, nav, section, …); Stack adds none.

Tokens

Stack reads no Apogee design tokens directly — gap maps to Tailwind’s built-in numeric spacing scale (gap-0…gap-12), not a themeable custom property.

Do / Don’t

Layout primitive — no content or misuse surface beyond picking the right props; the usual Do/Don’t guidance doesn’t apply.

Content

Not applicable — Stack renders no text of its own.