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.
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"
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.
| Breakpoint | Applies from (grid width) | At a 16px root font size |
|---|---|---|
base | 0 | 0 |
sm | 30rem | 480px |
md | 45rem | 720px |
lg | 60rem | 960px |
xl | 75rem | 1200px |
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.
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.
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.
<Grid columns={2} padding="6" paddingBlock="8">…</Grid>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.
<Grid columns={2} grow minSize="0" overflow="auto">…</Grid>PropsLink to "Props"
| Prop | What it does | Type | Default |
|---|---|---|---|
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 | GridColumns | 1 |
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. | Space | none |
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. | boolean | true |
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"andGridItem 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 forGridItems 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).
RelatedLink to "Related"
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.