Grid
Lays its children out in rows and columns that line up. Use it for dashboards, card lists, galleries and forms with fields side by side; for one direction only, use a Stack.
Website redesign
New home and pricing pages.
Mobile app 3.0
Offline mode and a new checkout, reviewed with the payments team before beta.
Help center
Move 140 articles.
Billing migration
From the old gateway to the new one, by 12/15/2026.
Brand refresh
Logo, colors and type.
Partner portal
Sign-up, contracts and payouts in one place.
Installation
Set up Camaleo once (Installation), then import it. It has no state, so it renders on the server.
import { Grid } from "@camaleo/react";Anatomy
One grid element with data-slot="grid". Its children are the cells; any child can span with gridColumn, like the card here that takes the whole row.
Examples
Every example is a real file you can copy. They all wear the skin, mode and brand from the bar above. Make the window narrower to see them reflow.
- On track
Website redesign
New home and pricing pages.
- At risk
Mobile app 3.0
Offline mode and a new checkout, reviewed with the payments team before beta.
- Done
Help center
Move 140 articles.
- On track
Billing migration
From the old gateway to the new one, by 12/15/2026.
Cards that fit the width
minChildWidth fits as many columns as there is room for, each at least that wide. No breakpoints: four cards in a row on a desktop, one on a phone.
Any column template
Pass a string to columns for anything CSS grid accepts. "auto 1fr" sizes the labels to the longest one and gives the values the rest.
Storage by team
An item across the row
There is no span prop: set gridColumn on the child. "1 / -1" takes the whole row however many columns fit, so it never breaks the layout.
Two columns, one on phones
Pair short fields side by side and give long ones the whole row. With minChildWidth, the form falls back to a single column on narrow screens.
Starter
For one person.
Team
Shared projects, roles and a common library of components and tokens.
Business
SSO and audit log.
Equal heights
Switch it off. The default align="stretch" makes every card in a row as tall as the tallest, so their buttons line up.
Morro do Pai Inácio Fumaça waterfall Poço Azul Lençóis at dusk Vale do Pati trail Pratinha cave
Gallery as a list
Render as="ul" so screen readers announce "6 items". Keep the DOM in the order people see, and avoid order or dense packing that would shuffle it.
In context
These are whole pieces of UI you can copy, in the skin you picked.
Storage by team
Projects
Mobile app 3.0
At riskBilling migration
On trackHelp center
DoneShipping address
Express, 2 business days
Starter
$0/month
Team
$24/month
Business
$49/month
Guidelines
Starter
For one person.
Team
Shared projects, roles and a common library of components and tokens.
With the default stretch and the action at the bottom, the buttons line up and the row reads as a set.
Starter
For one person.
Team
Shared projects, roles and a common library of components and tokens.
align="start" leaves a ragged bottom edge, and the eye has to hunt for each button.
The card number takes the row; expiry and CVC sit side by side because people fill them in together.
Unrelated fields side by side make people zigzag, and the order they read is not the order they type.
Props
as="ul").grid-template-columns value.columns: as many columns as fit, each at least this wide.--cml-space: gap={4} = 1rem.align-items).as takes the same tags as Box. When both are set, minChildWidth wins over columns. Children place themselves with gridColumn and gridRow.
Styling hooks
Each prop becomes a custom property on the element. Leave a prop out and your stylesheet can set its property instead.
Attributes
Tokens it reads
This component only
/* a sidebar layout from 48rem up, one column below */
@media (min-width: 48rem) {
.account[data-slot="grid"] {
--cml-grid-columns: 16rem minmax(0, 1fr);
}
}Accessibility
- Grid is layout, not a data grid: it has no grid role and no arrow-key navigation. For data people compare across rows, use a Table.
- Keep the visual order equal to the DOM order. order, grid-auto-flow: dense and explicit placement can move cells without moving focus or what screen readers read.
- Render a collection of cards or photos as="ul" so its size is announced, and name it with aria-label when there is no visible heading.
- Don't rely on position to carry meaning ("the card on the right"): with minChildWidth, the right column drops below on a phone.