Tailwind CSS Handbook v4.3

Grid

Two-dimensional layout with Tailwind — template columns and rows, spanning, auto-placement, named areas, and responsive grids that need no breakpoints.

CSS Grid lays out content in rows and columns at the same time. Use it for page shells, card galleries, dashboards and forms — anywhere items need to line up in both directions.

Overview#

Loading preview…

Defining tracks#

Columns#

UtilityCSS
grid-cols-1 … grid-cols-12repeat(N, minmax(0, 1fr))
grid-cols-nonenone
grid-cols-subgridsubgrid
grid-cols-[200px_1fr]Arbitrary track list

Rows#

UtilityCSS
grid-rows-1 … grid-rows-12repeat(N, minmax(0, 1fr))
grid-rows-[auto_1fr_auto]Arbitrary track list
auto-rows-min / auto-rows-max / auto-rows-frSize implicitly created rows
auto-cols-*Same for implicit columns

Flow#

UtilityBehaviour
grid-flow-rowDefault — fill row by row
grid-flow-colFill column by column
grid-flow-denseBackfill holes left by spanning items

Placing items#

UtilityCSS
col-span-2Span two columns
col-span-fullSpan every column
col-start-2 / col-end-4Explicit lines
row-span-2, row-start-*, row-end-*Row equivalents
col-auto / row-autoAutomatic placement
Loading preview…

Gaps and alignment#

UtilityPurpose
gap-4 / gap-x-4 / gap-y-2Space between tracks
justify-items-*Align items horizontally within their cell
items-*Align items vertically within their cell
place-items-centerBoth at once
justify-content-* / content-*Align the whole grid inside the container
justify-self-* / self-*Override for one item

Common patterns#

Responsive card grid#

HTML
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">…</div>

Auto-fitting grid — no breakpoints at all#

Loading preview…

Columns are at least 12rem wide and share the remainder. The layout adapts continuously instead of jumping at breakpoints.

Application shell#

HTML
<div class="grid min-h-screen grid-rows-[auto_1fr_auto] lg:grid-cols-[16rem_1fr] lg:grid-rows-[auto_1fr]">
  <header class="lg:col-span-2 border-b border-gray-200 px-6 py-4">Header</header>
  <aside class="hidden border-r border-gray-200 p-4 lg:block">Sidebar</aside>
  <main class="p-6">Content</main>
  <footer class="border-t border-gray-200 px-6 py-4 lg:col-span-2">Footer</footer>
</div>

grid-rows-[auto_1fr_auto] is the canonical sticky-footer grid: header and footer size to content, the middle row takes the rest.

Form layout#

Loading preview…

sm:col-span-2 is how you make one field full-width in a two-column form.

Named areas#

Tailwind has no grid-areas utilities, so use an arbitrary property:

HTML
<div class="grid gap-4 [grid-template-areas:'header_header''sidebar_main'] grid-cols-[12rem_1fr]">
  <header class="[grid-area:header]">…</header>
  <aside class="[grid-area:sidebar]">…</aside>
  <main class="[grid-area:main]">…</main>
</div>

Underscores stand in for spaces inside arbitrary values.

Subgrid#

Align nested content to the outer grid's tracks:

HTML
<div class="grid grid-cols-3 gap-4">
  <div class="col-span-3 grid grid-cols-subgrid gap-4">
    <div class="col-start-2">Aligned to the parent's second column</div>
  </div>
</div>

Overlapping elements#

Place two items in the same cell to layer them without absolute positioning:

HTML
<div class="grid">
  <img class="col-start-1 row-start-1 h-48 w-full object-cover" src="…" alt="">
  <div class="col-start-1 row-start-1 bg-gradient-to-t from-black/60 to-transparent"></div>
</div>

Grid vs Flexbox#

QuestionAnswer
Do rows and columns need to align?Grid
Is it a single row or column of things?Flexbox
Should item size be driven by content?Flexbox
Should item size be driven by the layout?Grid
Do you need to overlap items?Grid
Is the number of items unknown and variable?Either — auto-fit grid or flex-wrap

They compose: a grid cell is very often a flex container.

Common mistakes#

  • gap on the item instead of the container. gap-* belongs on the element with grid.
  • Forgetting grid. grid-cols-3 alone does nothing without display: grid.
  • Using grid-cols-* when auto-fit would do. Four breakpoint variants often replace one arbitrary track list.
  • Fixed grid-rows-* with variable content. Explicit row counts clip or stretch awkwardly; prefer auto-rows-*.
  • Expecting col-span-2 to work in a one-column grid. It clamps to the available tracks.
  • Nesting a grid where a flex row would do. Grid inside grid inside grid gets hard to reason about quickly.