Skip to content
Cynosurev0.5.0
SearchStorybookGitHubnpmColour mode: System. Switch to Light

Components / Structure

Grid

Lays items out in rows and columns: a fixed number of equal columns, a number per width of the grid, or as many as fit at a minimum width. Gaps and padding are space tokens.

Fixed columns

When to useLink to "When to use"

  • Galleries, dashboards and tiles: items that line up in both directions.

Use something else when:

  • items run in one direction: Stack (vertical) or Inline (horizontal, wrapping)
  • the content is data with headers: a table

UsageLink to "Usage"

tsx
Copy
import { Grid, GridItem } from "@arshad-shah/cynosure";

<Grid columns={3} gap="6">
  <GridItem span={2}><Chart /></GridItem>
  <Summary />
</Grid>
<Grid columns={{ base: 1, sm: 2, lg: 4 }}>…</Grid>
<Grid columns={2} padding="6">…</Grid>

Columns per breakpointLink to "Columns per breakpoint"

Pass columns an object to choose the column count at each width: { base: 1, sm: 2, lg: 4 } is one column in a narrow grid, two from sm and four from lg. The widths are those of the grid's own content box, not the window's, so the same grid adapts in a page, a side panel, a popup or a shadow root. It is done in CSS alone: nothing is measured by script, server-rendered markup is right on the first paint, and nothing shifts afterwards.

Columns per breakpoint, table 1
BreakpointApplies from (grid width)At a 16px root font size
base00
sm30rem480px
md45rem720px
lg60rem960px
xl75rem1200px

A breakpoint you leave out keeps the count of the one below it. The scale is exported as GRID_BREAKPOINTS. A grid that fills a Container of size sm, md, lg or xl reaches the breakpoint of the same name.

Columns per breakpoint

Responsive without breakpointsLink to "Responsive without breakpoints"

Pass minItemWidth and the grid fits as many columns of at least that width as its own width allows, wrapping the rest. Add columns to cap how many there can be. It responds to the grid's width, not the window's, so it works in side panels and popups too. A grid narrower than minItemWidth shows one column the grid's width, never overflowing.

Fits as many as the width allows

SpanningLink to "Spanning"

Wrap an item in GridItem to span columns (span={2}, or span="full" for the whole row) or rows (rowSpan). A span wider than the grid is clamped to its columns; with columns per breakpoint, to the columns in effect at the current width.

PaddingLink to "Padding"

padding pads all four sides of the grid with a space token. paddingInline (the sides) and paddingBlock (top and bottom) each win over padding for their axis, and "0" counts as a value. The padding is inside the grid's width, and breakpoints measure the room inside it.

tsx
Copy
<Grid columns={2} padding="6" paddingBlock="8">…</Grid>
Padding uses space tokens

In an app shellLink to "In an app shell"

Grid takes grow, shrink, fill, minSize and overflow as Stack does: a grid that takes what a header leaves, may be shorter than its items and scrolls them. GridItem takes overflow, for a wide item that scrolls sideways inside its column.

tsx
Copy
<Grid columns={2} grow minSize="0" overflow="auto">…</Grid>
Grows and scrolls in ashell

PropsLink to "Props"

Every prop of Grid
PropWhat it doesTypeDefault
columns
Number of equal columns, or a number per width of the grid itself: { base: 1, sm: 2, lg: 4 }. A breakpoint that is left out keeps the count of the one below it. With minItemWidth it is the most columns there can be. A string is a CSS track list for columns of different widths at every width ("2fr 1fr", "16rem 1fr"); for unequal columns that change with the width, use equal columns per breakpoint and GridItem span per breakpoint. Default 1.string | number | GridColumns1
minItemWidth
Any CSS length. Columns are at least this wide: as many fit as the width allows, then items wrap.string
gap
Space token between items.Space
rowGap
Space token between rows. Default: gap.Space`gap`
align
Block-axis alignment of items in their row. Default: stretch to the row's height."start" | "end" | "center" | "stretch"
as
Neutral layout element to render (never an interactive one). Use ul or ol with GridItem as="li"."div" | "section" | "aside" | "ul" | "ol" | "nav" | "header" | "footer"
className
Added to the root element, for layout.string
style
Layout only.CSSProperties
children
The items: any elements, or GridItem for ones that span columns or rows.ReactNode
data-testid
Set on the root element, for tests.string
padding
Space token of padding on all four sides of the box. Default: none.Spacenone
paddingInline
Space token of padding at the inline start and end (left and right in English). Wins over padding.Space
paddingBlock
Space token of padding at the block start and end (top and bottom in English). Wins over padding.Space
hideBelow
Hidden while the window is narrower than this breakpoint (md: below 45rem)."sm" | "md" | "lg" | "xl"
hideAbove
Hidden from this breakpoint upwards (md: 45rem and wider)."sm" | "md" | "lg" | "xl"
grow
Take the free space along the parent's row or column (flex-grow: 1), pushing the boxes after it to the end.boolean
shrink
false keeps the box at its own size when the parent's row or column runs out of room. Default true.booleantrue
fill
As wide and as tall as the parent's content box (100% both ways).boolean
minSize
"0" lets the box be smaller than its content, so a child can scroll instead of overflowing the page. A flex or grid child is otherwise at least as tall (and wide) as what it holds. Default: the CSS automatic minimum."0"the CSS automatic minimum
overflow
What happens to content that does not fit: hidden clips it, auto scrolls it, visible lets it overflow (the default). A box that scrolls content with nothing focusable in it should be a ScrollArea with a label, so keyboard users can scroll it.BoxOverflow

Generated from the type definitions in @arshad-shah/cynosure 0.5.0.

Behaviour and accessibilityLink to "Behaviour and accessibility"

  • Semantics: Grid is layout only; it adds no role. Render a list with as="ul" and GridItem as="li": bullets and indentation are removed, the list semantics stay.
  • Reading order: visual order follows source order, so keyboard and screen reader order match what is seen.
  • Direction: columns run with the text direction.
  • Nesting: a nested Grid has its own columns and padding and never inherits its parent's.
  • Columns per breakpoint: such a grid is a size container (container-type: inline-size), so its width must come from its parent. That is the case in normal block layout and in stretched flex or grid cells; in a shrink-to-fit place (an inline-flex box, a float) give it a width. Spans are clamped for GridItems that are direct children. The breakpoints are in rem, so they follow the page's root font size.

ThemingLink to "Theming"

Grid has no tokens of its own: gaps and padding are the global space tokens (--cy-space-*). The breakpoint widths are fixed (CSS container queries cannot read custom properties).

Stack · Inline · Container · Card

These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.

Getting started
Theming
Icons
Accessibility
Code editors and highlighters
Using Cynosure without React
Build-tool adapters
Components
Accordion
AppShell
AspectRatio
Breadcrumbs
Calendar
Card
Container
Disclosure
Divider
DocumentViewport
Grid
Inline
PageHeader
PanZoomCanvas
ScrollArea
SideNav
SortableList
SplitPane
Stack
StatusBar
Tabs
TitleBar
Toolbar
Tree
VirtualList
ZoomControls
Announcer
Avatar
Badge
CodeBlock
DescriptionList
EmptyState
ErrorBoundary
Field
Heading
IconTile
Image
Kbd
List
LoadingDots
Notice
ProgressBar
Prose
Skeleton
Stat
Steps
Table
Text
Button
Checkbox
Checklist
ColorField
ColorSwatches
Combobox
CompareSlider
CopyButton
DateField
FileDrop
IconButton
KeyValueEditor
Link
NumberField
Pagination
PathField
RadioGroup
SearchField
SegmentedControl
Select
SelectionFrame
SignaturePad
Slider
Switch
TagInput
TextArea
TextField
ThemeToggle
TimeField
ButtonBase
ChoiceBase
DialogBase
FileInputBase
HiddenValue
Icon
InputBase
LinkBase
LiveRegion
TextAreaBase
ChatMessage
Choice
DataGrid
DeviceFrame
HighlightedText
HotkeyField
ListRow
OptionList
OverlayFrame
QRCode
RowActions
Section
SiteFooter
SiteHeader
SkipLink
SortButton
VisuallyHidden
CommandPalette
ContextMenu
Dialog
FloatingToolbar
HoverCard
Menu
Menubar
Popover
ProgressOverlay
Sheet
Toast
Tooltip
Changelog