Skip to content

Grid

  • Cards, products or a gallery, in rows of equal columns
  • Tiles that should drop to fewer columns on a narrow screen

Choosing between laying out:

ComponentUse it forFor example
StackChildren in one line, down or across, with a gap between themA form’s fields, a row of buttons, tags
GridChildren in equal columns, wrapping into rowsCards, a gallery, a dashboard’s tiles
TableRecords compared across the same columnsInvoices, users, order lines
ToolbarA row of controls reached with the arrow keys, as one Tab stopA text editor’s formatting controls
One
Two
Three
Four
Five
Six
  • Free
  • Pro
  • Team
  • Enterprise
  • Education
import { Card, Grid } from '@arun-dev/ui';
const plans = ['Free', 'Pro', 'Team', 'Enterprise', 'Education'];
const tile = { padding: 'var(--space-sm)', borderRadius: 'var(--radius-md)' };
export default function GridBasics() {
return (
<Grid gap="lg" style={{ inlineSize: '100%' }}>
{/* Fixed: three equal columns at every width. */}
<Grid columns={3} gap="2xs">
{['One', 'Two', 'Three', 'Four', 'Five', 'Six'].map((label) => (
<Card key={label} style={tile}>
{label}
</Card>
))}
</Grid>
{/* Fitted: as many 6rem columns as there is room for, at most three — four would fit
here. Narrow the window and they drop to two. */}
<Grid minItemSize="6rem" columns={3} render={<ul role="list" aria-label="Plans" />}>
{plans.map((plan) => (
<Card key={plan} render={<li />} style={tile}>
{plan}
</Card>
))}
</Grid>
</Grid>
);
}

Grid is a CSS grid, in one of two modes:

PropsColumns
columnsExactly that many, at every width
minItemSizeAs many as fit at that width each, filling the row
minItemSize and columnsAs many as fit, but no more than columns: fewer as the space narrows

With minItemSize the grid is responsive with no breakpoints. A column is never wider than the grid itself, so one column still fits on a phone. A short last row keeps the same column width, rather than stretching across.

Grid props
PropTypeDefaultDescription
columnsnumber1How many equal columns. With minItemSize, the most there can be: fewer as the space narrows.
minItemSizestringThe narrowest a column may be, as a CSS length ('12rem'). The grid fits as many as there is room for.
gap'0' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl''sm'Space between rows and columns: the --space-* token of the same name.
classNamestringConcatenated with the component's own classes, never replacing them.
renderReactElementElement or component to render instead of the default. Props, className, event handlers and ref are merged onto it.
refRef<HTMLElement>Ref to the rendered element. Merged with any ref on the render element.
…restHTMLAttributesAnything else is spread onto the rendered element, so id, aria-*, data-* and event handlers all reach the DOM.
  • It renders a <div>. Use render={<ul role="list" />} for a list of cards, with each card as an <li>. A Grid drops a list’s markers itself; role="list" keeps it announced as a list in Safari.
  • gap takes a step on the spacing scale, as in Stack, for rows and columns alike.
  • The columns reach the CSS as --grid-columns and --grid-min-item-size on the element. A grid nested in another sets its own, so it never takes the outer grid’s.