PixelEqualHeightGrid
Grid wrapper that forces equal-height children via a 3-row subgrid (header / body / footer).
- Inherits PixelGrid props (cols, gap, surface, etc.) minus align, which rowAlign sets
- Gives each child grid-rows-[auto_1fr_auto] so footers align across the row
- Surface-aware borders and transitions
- rowAlign="top" keeps each item at its own height, at the top of its row
- Status
- stable
- Category
- layout
- Since
- v1.6.0
API
import { PixelEqualHeightGrid } from '@pxlkit/ui-kit';
| Prop | Type | Default | Description |
|---|
rowAlign | 'top' | 'stretch' | 'stretch' | stretch gives every item of a row the row's height; top keeps their own. |
surface | 'pixel' | 'linear' | — | Surface override; defaults to the nearest provider. |
cols | 1 | 2 | 3 | 4 | 5 | 6 | 12 | GridResponsiveColumns | — | Column count, or a count per breakpoint ({ base: 1, md: 3 }); ignored with autoFit / autoFill. |
rows | 1 | 2 | 3 | 4 | 5 | 6 | — | Row count. |
gap | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 | — | Gap token (stackGap) between rows and columns. |
as | keyof React.JSX.IntrinsicElements | — | Element to render. |
justify | 'start' | 'center' | 'end' | 'stretch' | — | Inline-axis alignment of the items. |
colGap | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 | — | Gap between columns; with rowGap, it replaces gap. |
rowGap | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 | — | Gap between rows; with colGap, it replaces gap. |
autoFit | boolean | — | As many columns as fit, empty tracks collapsed. |
autoFill | boolean | — | As many columns as fit, empty tracks kept. |
minColWidth | string | — | Narrowest column with autoFit / autoFill (any CSS length). |
Also takes the native attributes and event handlers of <div> (HTMLAttributes<HTMLDivElement>), except align.
ref points to <div>.
Accessibility
WCAG target: 2.1 AA
Inherits semantics from the underlying PixelGrid element (defaults to <div>). Use the as prop to render a more semantic container when appropriate.
Usage
import { cn, PixelEqualHeightGrid } from '@pxlkit/ui-kit';
function Card({ title, body, className }: { title: string; body: string; className?: string }) {
return (
<div className={cn('border border-retro-border p-4', className)}>
<h3 className="text-sm font-semibold text-retro-text">{title}</h3>
<p className="text-sm text-retro-muted">{body}</p>
<div className="mt-2 text-xs text-retro-muted">Footer</div>
</div>
);
}
export function Default() {
return (
<PixelEqualHeightGrid cols={{ base: 1, sm: 3 }} gap={4}>
<Card title="One" body="Short copy." />
<Card title="Two" body="A longer body that forces the row to grow taller than the first card." />
<Card title="Three" body="Medium length copy here." />
</PixelEqualHeightGrid>
);
}
Examples
Default
import { cn, PixelEqualHeightGrid } from '@pxlkit/ui-kit';
function Card({ title, body, className }: { title: string; body: string; className?: string }) {
return (
<div className={cn('border border-retro-border p-4', className)}>
<h3 className="text-sm font-semibold text-retro-text">{title}</h3>
<p className="text-sm text-retro-muted">{body}</p>
<div className="mt-2 text-xs text-retro-muted">Footer</div>
</div>
);
}
export function Default() {
return (
<PixelEqualHeightGrid cols={{ base: 1, sm: 3 }} gap={4}>
<Card title="One" body="Short copy." />
<Card title="Two" body="A longer body that forces the row to grow taller than the first card." />
<Card title="Three" body="Medium length copy here." />
</PixelEqualHeightGrid>
);
}
Row Align Top
import { cn, PixelEqualHeightGrid } from '@pxlkit/ui-kit';
function Card({ title, body, className }: { title: string; body: string; className?: string }) {
return (
<div className={cn('border border-retro-border p-4', className)}>
<h3 className="text-sm font-semibold text-retro-text">{title}</h3>
<p className="text-sm text-retro-muted">{body}</p>
<div className="mt-2 text-xs text-retro-muted">Footer</div>
</div>
);
}
export function RowAlignTop() {
return (
<PixelEqualHeightGrid cols={{ base: 1, sm: 3 }} gap={4} rowAlign="top">
<Card title="One" body="Short copy." />
<Card title="Two" body="A longer body that would otherwise stretch siblings." />
<Card title="Three" body="Medium length copy here." />
</PixelEqualHeightGrid>
);
}
Pixel Surface
import { cn, PixelEqualHeightGrid } from '@pxlkit/ui-kit';
function Card({ title, body, className }: { title: string; body: string; className?: string }) {
return (
<div className={cn('border border-retro-border p-4', className)}>
<h3 className="text-sm font-semibold text-retro-text">{title}</h3>
<p className="text-sm text-retro-muted">{body}</p>
<div className="mt-2 text-xs text-retro-muted">Footer</div>
</div>
);
}
export function PixelSurface() {
return (
<PixelEqualHeightGrid cols={2} gap={4} surface="pixel">
<Card title="Pixel A" body="Surface-aware grid item." />
<Card title="Pixel B" body="Renders with the pixel surface tokens applied to the grid." />
</PixelEqualHeightGrid>
);
}