Grid
Oat provides two grid systems: a classic 12-column row/col grid and a modern container-query auto-responsive grid. Both are fully responsive out of the box.
Grid tokens
| Token | Default | Purpose |
|---|---|---|
--grid-cols | 12 | Number of columns |
--grid-gap | 1.5rem | Column / row gap |
--container-max | 1280px | Max width of .container |
--container-pad | clamp(0.75rem, 4vw, 2rem) | Inline padding of container |
Container
Centers content and constrains max-width. Fluid padding shrinks on small screens.
<div class="container">...</div>12-column grid (.row / .col-*)
Equal columns
<div class="row">
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
</div>Mixed widths
<div class="row">
<div class="col-3">col-3</div>
<div class="col-6">col-6</div>
<div class="col-3">col-3</div>
</div>
<div class="row">
<div class="col-2">col-2</div>
<div class="col-8">col-8</div>
<div class="col-2">col-2</div>
</div>All column sizes
<div class="row"><div class="col-12">col-12</div></div>
<div class="row"><div class="col-11">col-11</div><div class="col-1">1</div></div>
<div class="row"><div class="col-10">col-10</div><div class="col-2">2</div></div>
<div class="row"><div class="col-9">col-9</div><div class="col-3">3</div></div>
<div class="row"><div class="col-8">col-8</div><div class="col-4">4</div></div>
<div class="row"><div class="col-7">col-7</div><div class="col-5">5</div></div>
<div class="row"><div class="col-6">col-6</div><div class="col-6">6</div></div>Offsets & alignment
<div class="row">
<div class="col-4 offset-2">col-4 offset-2</div>
<div class="col-4">col-4</div>
</div>
<div class="row">
<div class="col-3">col-3</div>
<div class="col-4 col-end">col-4 col-end</div>
</div>| Class | Effect |
|---|---|
.offset-1 to .offset-6 | Push column to start at column N+1 |
.col-end | Align column to the right edge of the row |
Responsive behavior
The .row grid automatically adapts at different breakpoints:
| Screen | Columns | Gap | Offsets |
|---|---|---|---|
| < 640px (mobile) | 1 (stacked) | 1rem | Ignored |
| 640–767px (small) | 4 | 1rem | Ignored |
| ≥ 768px | 12 (full) | 1.5rem | Active |
Resize your browser to see columns stack on mobile.
Responsive column classes
Override column spans at specific breakpoints using prefixed classes:
| Prefix | Breakpoint | Classes |
|---|---|---|
sm: | 640px+ | .sm:col-1 through .sm:col-12 |
md: | 768px+ | .md:col-1 through .md:col-12 |
lg: | 1024px+ | .lg:col-1 through .lg:col-12 |
xl: | 1280px+ | .xl:col-1 through .xl:col-12 |
Live: responsive column spans
Resize your browser to see these items reflow: full → half → quarter.
<!-- Full → Half → Quarter -->
<div class="row">
<div class="col-12 sm:col-6 lg:col-3">Item 1</div>
<div class="col-12 sm:col-6 lg:col-3">Item 2</div>
<div class="col-12 sm:col-6 lg:col-3">Item 3</div>
<div class="col-12 sm:col-6 lg:col-3">Item 4</div>
</div>Live: mixed responsive layout
Sidebar + content: stacked on mobile → 4+8 on medium → 3+9 on large.
<!-- Stacked → 4+8 → 3+9 -->
<div class="row">
<div class="col-12 md:col-4 lg:col-3">Sidebar</div>
<div class="col-12 md:col-8 lg:col-9">Main Content</div>
</div>Container-query grid (.grid)
The .grid class uses container queries instead of media queries. It responds to its own container width — perfect inside cards, sidebars, or any nested layout.
| Container width | Columns |
|---|---|
| < 640px | 1 (stacked) |
| 640–1023px | 2 |
| ≥ 1024px | Uses --grid-cols (12 by default) |
Live: .grid in full width
<div class="grid">
<div class="col-4">col-4</div>
<div class="col-8">col-8</div>
</div>Live: .grid inside a narrow container
The grid below is constrained to 500px — it uses 2 columns because of container queries.
500px container
<!-- .grid inside a narrow 500px container -->
<div style="max-width: 500px;">
<div class="grid">
<div>Item A</div>
<div>Item B</div>
<div>Item C</div>
<div>Item D</div>
</div>
</div>.grid vs .row — comparison
Both grids below are inside a 600px container. .row uses media queries (viewport), while .grid uses container queries.
.row (media-query — responds to viewport)
.grid (container-query — responds to 600px box)
<!-- .row responds to VIEWPORT width -->
<div class="row">
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
</div>
<!-- .grid responds to CONTAINER width -->
<div class="grid">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>Auto-fit grid (.grid-auto)
Equal-width columns that wrap automatically based on available space. Minimum column width is 16rem (256px).
<div class="grid-auto">
<div>Card 1</div>
<div>Card 2</div>
<div>Card 3</div>
<div>Card 4</div>
</div>Column count overrides
Use .cols-2, .cols-3, or .cols-4 with .grid to set a fixed column count:
cols-2
<div class="grid cols-2">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>cols-3
<div class="grid cols-3">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
<div>Six</div>
</div>cols-4
<div class="grid cols-4">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>| Class | Columns at 1024px+ | At 640–1023px | < 640px |
|---|---|---|---|
.cols-2 | 2 | 2 | 1 |
.cols-3 | 3 | 2 | 1 |
.cols-4 | 4 | 2 | 1 |
Nested grids
Grids can be nested inside columns for complex layouts.
<div class="row">
<div class="col-8">
<!-- Nested row inside a column -->
<div class="row">
<div class="col-6">Nested col-6</div>
<div class="col-6">Nested col-6</div>
</div>
</div>
<div class="col-4">col-4</div>
</div>Quick reference
| Class | What it does |
|---|---|
.container | Centered max-width wrapper with fluid padding |
.row | 12-column CSS grid (media-query responsive) |
.col-1 – .col-12 | Column span width |
.offset-1 – .offset-6 | Column start offset |
.col-end | Snap column to right edge |
.grid | Container-query auto-responsive grid |
.grid-auto | Auto-fit equal columns (min 16rem) |
.cols-2 / .cols-3 / .cols-4 | Fixed column count for .grid |
.sm:col-* / .md:col-* / .lg:col-* / .xl:col-* | Responsive column overrides |