Grid
A multi-column grid. Children fill columns left-to-right and wrap to new rows. Grid rows are atomic — a row will not split across pages.
Use grid for uniform card layouts. For tabular data with column headers, use table instead.
Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
cols |
integer | 1 | Number of columns (1–12) |
col-width |
token/pt | — | Minimum column width: the grid fits as many columns as the width allows, at least one, and stretches them to fill the row (overrides cols) |
gap |
token/pt | — | Gap between cells |
width |
token/pt | — | Constrain total width |
padding |
spacing | — | Inner padding |
background |
color | — | Background color |
border |
string | — | Border |
radius |
token/pt | — | Corner radius |
font |
string | inherit | Font name |
font-size |
token/pt | inherit | Font size |
data-source |
string | — | Dot-path to array — repeats children per item |
Three-column layout
Section titled “Three-column layout”<grid cols="3" gap="m"> <frame padding="m" border="xs #e0e0e0" radius="s"> <stack gap="4pt"> <text font-size="s">Feature A</text> <text font-size="xs" color="#666666">Short description.</text> </stack> </frame> <frame padding="m" border="xs #e0e0e0" radius="s"> <stack gap="4pt"> <text font-size="s">Feature B</text> <text font-size="xs" color="#666666">Short description.</text> </stack> </frame> <frame padding="m" border="xs #e0e0e0" radius="s"> <stack gap="4pt"> <text font-size="s">Feature C</text> <text font-size="xs" color="#666666">Short description.</text> </stack> </frame></grid>L.grid({ cols: '3', gap: 'm' }, [ L.frame({ padding: 'm', border: 'xs #e0e0e0', radius: 's' }, [ L.stack({ gap: '4pt' }, [ L.text({ fontSize: 's' }, ['Feature A']), L.text({ fontSize: 'xs', color: '#666666' }, ['Short description.']), ]), ]), L.frame({ padding: 'm', border: 'xs #e0e0e0', radius: 's' }, [ L.stack({ gap: '4pt' }, [ L.text({ fontSize: 's' }, ['Feature B']), L.text({ fontSize: 'xs', color: '#666666' }, ['Short description.']), ]), ]), L.frame({ padding: 'm', border: 'xs #e0e0e0', radius: 's' }, [ L.stack({ gap: '4pt' }, [ L.text({ fontSize: 's' }, ['Feature C']), L.text({ fontSize: 'xs', color: '#666666' }, ['Short description.']), ]), ]),])L.grid(GridAttr(cols='3', gap='m'), [ L.frame(FrameAttr(padding='m', border='xs #e0e0e0', radius='s'), [ L.stack(StackAttr(gap='4pt'), [ L.text(TextAttr(font_size='s'), ['Feature A']), L.text(TextAttr(font_size='xs', color='#666666'), ['Short description.']) ]) ]), L.frame(FrameAttr(padding='m', border='xs #e0e0e0', radius='s'), [ L.stack(StackAttr(gap='4pt'), [ L.text(TextAttr(font_size='s'), ['Feature B']), L.text(TextAttr(font_size='xs', color='#666666'), ['Short description.']) ]) ]), L.frame(FrameAttr(padding='m', border='xs #e0e0e0', radius='s'), [ L.stack(StackAttr(gap='4pt'), [ L.text(TextAttr(font_size='s'), ['Feature C']), L.text(TextAttr(font_size='xs', color='#666666'), ['Short description.']) ]) ])])L::grid(new GridAttr(cols: '3', gap: 'm'), [ L::frame(new FrameAttr(padding: 'm', border: 'xs #e0e0e0', radius: 's'), [ L::stack(new StackAttr(gap: '4pt'), [ L::text(new TextAttr(fontSize: 's'), ['Feature A']), L::text(new TextAttr(fontSize: 'xs', color: '#666666'), ['Short description.']), ]), ]), L::frame(new FrameAttr(padding: 'm', border: 'xs #e0e0e0', radius: 's'), [ L::stack(new StackAttr(gap: '4pt'), [ L::text(new TextAttr(fontSize: 's'), ['Feature B']), L::text(new TextAttr(fontSize: 'xs', color: '#666666'), ['Short description.']), ]), ]), L::frame(new FrameAttr(padding: 'm', border: 'xs #e0e0e0', radius: 's'), [ L::stack(new StackAttr(gap: '4pt'), [ L::text(new TextAttr(fontSize: 's'), ['Feature C']), L::text(new TextAttr(fontSize: 'xs', color: '#666666'), ['Short description.']), ]), ]),])L.Grid(new() { Cols = "3", Gap = "m" }, [ L.Frame(new() { Padding = "m", Border = "xs #e0e0e0", Radius = "s" }, [ L.Stack(new() { Gap = "4pt" }, [ L.Text(new() { FontSize = "s" }, ["Feature A"]), L.Text(new() { FontSize = "xs", Color = "#666666" }, ["Short description."]), ]), ]), L.Frame(new() { Padding = "m", Border = "xs #e0e0e0", Radius = "s" }, [ L.Stack(new() { Gap = "4pt" }, [ L.Text(new() { FontSize = "s" }, ["Feature B"]), L.Text(new() { FontSize = "xs", Color = "#666666" }, ["Short description."]), ]), ]), L.Frame(new() { Padding = "m", Border = "xs #e0e0e0", Radius = "s" }, [ L.Stack(new() { Gap = "4pt" }, [ L.Text(new() { FontSize = "s" }, ["Feature C"]), L.Text(new() { FontSize = "xs", Color = "#666666" }, ["Short description."]), ]), ]),])Data-driven grid
Section titled “Data-driven grid”<grid cols="2" gap="m" data-source="products"> <frame padding="m" border="xs #e0e0e0" radius="s"> <stack gap="4pt"> <text font-size="s" data-value="name">Product name</text> <text font-size="xs" color="#666666" data-value="price">$0.00</text> </stack> </frame></grid>