Grid
CSS grid container with column and gap utilities using design tokens.
import { ... } from '@corndev/ui' HTML
No JavaScript required — these classes are the whole component.
<div class="corn-grid" data-cols data-gap="md" style="--corn-grid-cols: 3">
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>
<!-- Uneven spans, and a column as wide as its contents beside one taking the rest. -->
<div class="corn-grid" data-gap="md">
<div class="corn-grid-col" data-span="4">Location</div>
<div class="corn-grid-col" data-span="8">Name</div>
<div class="corn-grid-col" data-span="content"><select aria-label="Type"><option>string</option></select></div>
<div class="corn-grid-col" data-span="auto">Format</div>
</div>
Classes
| Class |
|---|
.corn-grid |
.corn-grid-col |
Attributes
| On | Attribute | Values |
|---|---|---|
.corn-grid | data-cols | present or absent |
.corn-grid | data-gap | xs|sm|md|lg|xl |
.corn-grid | data-row-gap | xs|sm|md|lg|xl |
.corn-grid | data-col-gap | xs|sm|md|lg|xl |
.corn-grid-col | data-span | 1|2|3|4|5|6|7|8|9|10|11|12|content|auto |
CSS variables
| Variable | Default | Description |
|---|---|---|
--corn-grid-cols | 12 | Column count when data-cols is set |
Vanilla JS
Optional. createGrid only adds and removes the classes and attributes above, so the HTML is equivalent. Reach for it when you need to change options at runtime.
import { createGrid } from '@corndev/ui';
import '@corndev/ui/theme';
const el = document.querySelector('#target');
const instance = createGrid(el, { /* options */ });
Options
| Option | Type | Default | Description |
|---|---|---|---|
cols | number|null | 12 | Equal columns, written to the --corn-grid-cols custom property. Pass null for no column template, so you can set grid-template-columns or grid-template-areas yourself. |
gap | 'xs'|'sm'|'md'|'lg'|'xl'|null | 'md' | Uniform gap between cells. |
rowGap | 'xs'|'sm'|'md'|'lg'|'xl' | undefined | Row gap only; overrides the uniform gap. |
colGap | 'xs'|'sm'|'md'|'lg'|'xl' | undefined | Column gap only; overrides the uniform gap. |
React
Grid, GridCol — from @corndev/ui-react.
The props are the same as the options above, plus className.
<Grid.Col> props
A cell that says how much of the row it takes.
| Prop | Type | Default | Description |
|---|---|---|---|
span | number|'content'|'auto' | 12 | How much of the row to take. |
children | React.ReactNode | undefined | |
className | string | undefined | |
style | React.CSSProperties | undefined |
Basic usage
Apply .corn-grid to any container to make it a CSS grid. Use data-cols with the --corn-grid-cols custom property to define equal-width columns.
import '@corndev/ui/theme';
<div class="corn-grid" data-cols data-gap="md" style="--corn-grid-cols: 3">
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>
Column count
Set --corn-grid-cols inline to control how many equal columns the grid has.
<!-- 2 columns -->
<div class="corn-grid" data-cols style="--corn-grid-cols: 2">...</div>
<!-- 4 columns -->
<div class="corn-grid" data-cols style="--corn-grid-cols: 4">...</div>
<!-- 12-column layout grid -->
<div class="corn-grid" data-cols style="--corn-grid-cols: 12">...</div>
Without --corn-grid-cols, use native grid-template-columns inline or in your own stylesheet for non-uniform layouts. From the controller or the React component, that is cols: null:
createGrid(el, { cols: null, gap: 'md' });
<Grid cols={null} gap="md" style={{ gridTemplateAreas: '"nav main"' }}>…</Grid>
An invalid count — zero, negative, fractional — falls back to the stylesheet’s default of 12 rather than emitting repeat(0, …), which would void grid-template-columns entirely and collapse the layout to a single column.
Gap sizes
<div class="corn-grid" data-cols data-gap="xs" style="--corn-grid-cols: 2">...</div>
<div class="corn-grid" data-cols data-gap="sm" style="--corn-grid-cols: 2">...</div>
<div class="corn-grid" data-cols data-gap="md" style="--corn-grid-cols: 2">...</div>
<div class="corn-grid" data-cols data-gap="lg" style="--corn-grid-cols: 2">...</div>
<div class="corn-grid" data-cols data-gap="xl" style="--corn-grid-cols: 2">...</div>
Row and column gap overrides
Override just the row or column gap independently.
<!-- Large row gap, small column gap -->
<div
class="corn-grid" data-cols data-row-gap="lg" data-col-gap="sm"
style="--corn-grid-cols: 3"
>
...
</div>
Uneven columns
Grid.Col says how much of the row a child takes. A form row is rarely an even
split — a parameter’s location beside its name, a type beside its format, then a
full-width row beneath:
<Grid>
<Grid.Col span={4}><Select aria-label="In" … /></Grid.Col>
<Grid.Col span={8}><Input aria-label="Name" /></Grid.Col>
<Grid.Col span={12}><Textarea aria-label="Description" autosize /></Grid.Col>
</Grid>
A number spans that many of cols (12 by default), and the gaps are accounted for,
so 6 + 6 and 4 + 8 fill the row exactly.
content and auto
<Grid>
<Grid.Col span="content"><Select aria-label="Type" … /></Grid.Col>
<Grid.Col span="auto"><Input aria-label="Format" /></Grid.Col>
</Grid>
content is as wide as what is inside it — a small select sitting snugly beside a
field instead of taking half the row. auto takes whatever the row has left.
Neither can be expressed with fixed tracks, so a grid holding columns lays out as a
wrapping flex row; a child that is not a column still renders, at its own width.
On a narrow screen — below 640px — every column takes the full row, so a desktop split never survives onto a phone.
Without React it is the class and an attribute:
<div class="corn-grid" data-gap="md">
<div class="corn-grid-col" data-span="4">…</div>
<div class="corn-grid-col" data-span="8">…</div>
</div>