// preview in
saved for every page

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.

Pattern CSS gridServer componentSource ↗
minimal · light · #3fa34d
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.

Done

Brand refresh

Logo, colors and type.

On track

Partner portal

Sign-up, contracts and payouts in one place.

minChildWidth
align

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.

minimal · light · #3fa34d
Revenue$48,92012%vs. September
Orders1,2844%vs. September
Average ticket$38.102%vs. September
  • 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.

Order#A-20931Placed on10/28/2026PaymentVisa ending in 4242DeliveryExpress, 2 business days

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.

Revenue$48,920
Orders1,284
Average ticket$38.10

Storage by team

Design42 GB of 100 GB
x
Engineering71 GB of 100 GB
x

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.

Revenue$48,92012%vs. September
Orders1,2844%vs. September
Average ticket$38.102%vs. September

Storage by team

Design42 GB of 100 GB
x
Engineering71 GB of 100 GB
x
Marketing18 GB of 100 GB
x

Projects

Mobile app 3.0

At risk

Billing migration

On track

Help center

Done
Sales dashboardGrid · Stat · Card · Meter · Badge

Shipping address

Express, 2 business days

Address formCard · Grid · Field · Input · Button

Starter

$0/month

For one person.3 projects
Most popular

Team

$24/month

Shared projects, roles and a common library of components and tokens.Unlimited projects

Business

$49/month

SSO and audit log.SSO and audit log
Pricing plansGrid · Card · Badge · Button

Guidelines

Starter

For one person.

Team

Shared projects, roles and a common library of components and tokens.

DoCards in a row share one height.

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.

Don’tCards that end at different heights.

align="start" leaves a ragged bottom edge, and the eye has to hunt for each button.

DoPair fields that belong together.

The card number takes the row; expiry and CVC sit side by side because people fill them in together.

Don’tTwo columns just to fill the space.

Unrelated fields side by side make people zigzag, and the order they read is not the order they type.

Props

PropTypeDefaultDescription
as"div" | "section" | "ul" | "form" | …"div"Element to render, for the right semantics (e.g. as="ul").
columnsstring | number—A number of equal columns, or any grid-template-columns value.
minChildWidthstring—Responsive alternative to columns: as many columns as fit, each at least this wide.
gapnumber0Space between rows and columns, in multiples of --cml-space: gap={4} = 1rem.
alignCSS align-items"stretch"Vertical alignment of items in their row (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

data-slot"grid"

Tokens it reads

This component only

--cml-grid-align--cml-grid-columns--cml-grid-gap--cml-space
/* 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 renders no interactive element. Tab moves through its children in DOM order, row by row.
Was this page helpful? · Edit this page on GitHub