Grid
A responsive grid — autofit by default, or a fixed column count.
Last updated
Layout primitive — exempt from Do/Don’t and Content (no misuse or wording surface).
Show codeHide code
<Grid minItemWidth="10rem" gap={4}>
<div class="rounded-md border border-neutral p-4 text-sm">1</div>
<div class="rounded-md border border-neutral p-4 text-sm">2</div>
<div class="rounded-md border border-neutral p-4 text-sm">3</div>
<div class="rounded-md border border-neutral p-4 text-sm">4</div>
</Grid>Add
npx @ava-ui/apogee add grid
No Apogee dependencies.
Usage
---
import Grid from '@/components/apogee/Grid/Grid.astro'
---
<Grid>
<Card />
<Card />
<Card />
</Grid>
API
@composable — exposed to Content Editors in AVA. Any other attribute passes
through to the root <div>.
| Prop | Type | Default | Description |
|---|---|---|---|
minItemWidth |
string |
'16rem' |
Autofit mode: the smallest a column may get before the count drops. Ignored when cols is set. |
cols |
1 … 12 | 'auto', responsive |
— | Fixed column count (overrides autofit). { base: 1, md: 3 } for breakpoints. |
gap |
0 … 6 | 8 | 10 | 12 | 16, responsive |
6 |
Gap size (Tailwind gap-* scale). |
colGap / rowGap |
0 | 1 | 2 | 3 | 4 | 6 | 8 | 10 | 12 |
— | Gap on one axis. |
align |
'start' | 'center' | 'end' | 'stretch' |
— | Vertical alignment of items in their cells. |
justify |
'start' | 'center' | 'end' | 'stretch' |
— | Horizontal alignment of items in their cells. |
as |
string |
'div' |
Tag to render. |
class |
string |
— | Extra classes, merged last. |
GridItem
Spans columns or rows; colSpan and rowSpan accept per-breakpoint objects.
| Prop | Type | Default | Description |
|---|---|---|---|
colSpan |
1 … 12 | 'full', responsive |
— | Columns to span. |
rowSpan |
1 … 6, responsive |
— | Rows to span. |
colStart |
1 … 13 |
— | Column line to start at. |
rowStart |
1 … 7 |
— | Row line to start at. |
as |
string |
'div' |
Tag to render. |
Show codeHide code
<Grid cols={{ base: 1, md: 3 }} gap={4}>
<GridItem colSpan={{ base: 'full', md: 2 }}>Main</GridItem>
<GridItem>Aside</GridItem>
<GridItem colSpan="full">Footer</GridItem>
</Grid>Variants
Autofit (default) — columns reflow to the grid’s width, no breakpoints:
Show codeHide code
<Grid minItemWidth="8rem">
<div class="rounded-md border border-neutral p-4 text-sm">A</div>
<div class="rounded-md border border-neutral p-4 text-sm">B</div>
<div class="rounded-md border border-neutral p-4 text-sm">C</div>
<div class="rounded-md border border-neutral p-4 text-sm">D</div>
<div class="rounded-md border border-neutral p-4 text-sm">E</div>
</Grid>Fixed columns (cols overrides autofit):
Show codeHide code
<Grid cols={3}>
<div class="rounded-md border border-neutral p-4 text-sm">1</div>
<div class="rounded-md border border-neutral p-4 text-sm">2</div>
<div class="rounded-md border border-neutral p-4 text-sm">3</div>
</Grid>Every gap value (two columns, so the gap is easy to compare):
Show codeHide code
<div class="flex w-full flex-col gap-6">
<Grid cols={2} gap={0}>
<div class="rounded-md border border-neutral p-3 text-xs">gap=0</div>
<div class="rounded-md border border-neutral p-3 text-xs">gap=0</div>
</Grid>
<Grid cols={2} gap={2}>
<div class="rounded-md border border-neutral p-3 text-xs">gap=2</div>
<div class="rounded-md border border-neutral p-3 text-xs">gap=2</div>
</Grid>
<Grid cols={2} gap={4}>
<div class="rounded-md border border-neutral p-3 text-xs">gap=4</div>
<div class="rounded-md border border-neutral p-3 text-xs">gap=4</div>
</Grid>
<Grid cols={2} gap={6}>
<div class="rounded-md border border-neutral p-3 text-xs">gap=6</div>
<div class="rounded-md border border-neutral p-3 text-xs">gap=6</div>
</Grid>
<Grid cols={2} gap={8}>
<div class="rounded-md border border-neutral p-3 text-xs">gap=8</div>
<div class="rounded-md border border-neutral p-3 text-xs">gap=8</div>
</Grid>
<Grid cols={2} gap={10}>
<div class="rounded-md border border-neutral p-3 text-xs">gap=10</div>
<div class="rounded-md border border-neutral p-3 text-xs">gap=10</div>
</Grid>
</div>Alignment
align places items vertically in their cells; stretch fills the cell height.
align=“start”
align=“center”
align=“end”
align=“stretch”
Show codeHide code
<p class="text-sm text-neutral-faded">align="start"</p>
<Grid cols={3} gap={2} align="start" class="h-20 rounded-md border border-dashed border-neutral p-2"><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">A</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">B</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">C</div></Grid>
<p class="text-sm text-neutral-faded">align="center"</p>
<Grid cols={3} gap={2} align="center" class="h-20 rounded-md border border-dashed border-neutral p-2"><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">A</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">B</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">C</div></Grid>
<p class="text-sm text-neutral-faded">align="end"</p>
<Grid cols={3} gap={2} align="end" class="h-20 rounded-md border border-dashed border-neutral p-2"><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">A</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">B</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">C</div></Grid>
<p class="text-sm text-neutral-faded">align="stretch"</p>
<Grid cols={3} gap={2} align="stretch" class="h-20 rounded-md border border-dashed border-neutral p-2"><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">A</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">B</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">C</div></Grid>justify places items horizontally in their cells; stretch fills the cell width.
justify=“start”
justify=“center”
justify=“end”
justify=“stretch”
Show codeHide code
<p class="text-sm text-neutral-faded">justify="start"</p>
<Grid cols={3} gap={2} justify="start" class="h-20 rounded-md border border-dashed border-neutral p-2"><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">A</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">B</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">C</div></Grid>
<p class="text-sm text-neutral-faded">justify="center"</p>
<Grid cols={3} gap={2} justify="center" class="h-20 rounded-md border border-dashed border-neutral p-2"><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">A</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">B</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">C</div></Grid>
<p class="text-sm text-neutral-faded">justify="end"</p>
<Grid cols={3} gap={2} justify="end" class="h-20 rounded-md border border-dashed border-neutral p-2"><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">A</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">B</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">C</div></Grid>
<p class="text-sm text-neutral-faded">justify="stretch"</p>
<Grid cols={3} gap={2} justify="stretch" class="h-20 rounded-md border border-dashed border-neutral p-2"><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">A</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">B</div><div class="rounded-sm bg-primary-faded px-2 py-1 text-sm text-primary">C</div></Grid>Accessibility
Native semantics, no extra ARIA needed. A <div class="grid"> carries no
implicit role — if the children form a meaningful list, use a list element
(ul/ol) inside or around it as appropriate.
Tokens
No CSS custom properties. Column width comes from an inline grid-template-columns
(computed from minItemWidth or cols); gap comes from Tailwind’s built-in
gap-* spacing scale, not a bespoke token.