Grid In Depth: Auto-Fit, Spanning, Template Areas and Subgrid

Intermediate
13 min

Grid In Depth: Auto-Fit, Spanning, Template Areas and Subgrid

The first grid lesson covered grid-cols-*, gap-* and basic spanning. This lesson covers the techniques that make grid the right tool for page shells and dashboards: responsive tracks with auto-fit, explicit placement, dense packing, named template areas and subgrid. After finishing it you will be able to build any two-dimensional layout you can sketch.

Auto-fit and minmax

grid-cols-3 always produces three columns. For a grid that adds and removes columns with available width, use an arbitrary template:

html
<div class="grid grid-cols-[repeat(auto-fit,minmax(16rem,1fr))] gap-6"> <div>Card</div> <div>Card</div> <div>Card</div> </div>

Each column is at least 16rem and stretches to share leftover space: one column on a phone, five or six on a wide monitor, with no breakpoints. auto-fill behaves the same but keeps empty tracks. Spaces inside arbitrary values are written as underscores, for example grid-cols-[200px_1fr_200px].

Explicit placement and spanning

Items normally flow into the next free cell; placement utilities override that:

html
<div class="grid grid-cols-6 gap-4"> <div class="col-span-4">Spans four columns</div> <div class="col-span-2">Spans two</div> <div class="col-start-2 col-end-6">Starts at line 2, ends at line 6</div> <div class="col-span-full">Full width</div> <div class="row-span-2">Two rows tall</div> </div>

Line numbers count from 1 on the left and negative numbers count from the right, so col-start-1 col-end-[-1] equals col-span-full. All placement utilities accept breakpoints (col-span-full md:col-span-2), and col-start-auto resets placement at a breakpoint.

Dense packing and implicit rows

When items have different spans, auto-placement can leave holes. grid-flow-row-dense backfills those gaps with later items that fit — ideal for galleries where order is not critical. Rows you did not define explicitly are implicit and sized with auto-rows-*:

html
<div class="grid auto-rows-[minmax(8rem,auto)] grid-cols-3 gap-4 grid-flow-row-dense"> <div class="col-span-2">Wide</div> <div class="row-span-2">Tall</div> <div>Small</div> </div>

auto-rows-fr equalises implicit rows, auto-rows-min sizes them to content, and grid-flow-col with auto-cols-* flips the axis for horizontal scrollers.

Named template areas

For page shells, named regions read better than line numbers. Tailwind has no dedicated utility, so use arbitrary properties:

html
<div class="grid min-h-dvh gap-4 [grid-template-areas:'header'_'main'_'sidebar'_'footer'] md:[grid-template-areas:'header_header'_'sidebar_main'_'footer_footer'] md:grid-cols-[16rem_1fr] md:grid-rows-[auto_1fr_auto]"> <header class="[grid-area:header]">Header</header> <aside class="[grid-area:sidebar]">Sidebar</aside> <main class="[grid-area:main]">Main</main> <footer class="[grid-area:footer]">Footer</footer> </div>

Each quoted string is one row; underscores stand in for spaces between column names. Mobile stacks everything in one column, md: switches to two — and the HTML order never changes.

Subgrid

Cards with a title, description and button end up with misaligned buttons because descriptions differ in length. Subgrid lets a child adopt the parent's row tracks:

html
<div class="grid grid-cols-3 gap-6"> <article class="row-span-3 grid grid-rows-subgrid gap-2 rounded-xl border p-4"> <h3 class="font-semibold">Title</h3> <p class="text-sm text-gray-600">Short description.</p> <button class="self-end">Buy</button> </article> <!-- more articles with the same classes --> </div>

Each card spans three parent rows and passes those tracks to its children, so titles, descriptions and buttons line up across the row. grid-cols-subgrid does the same horizontally.

Common mistakes

  • Using auto-fill and wondering why the last row has empty columns; auto-fit collapses them.
  • Forgetting row-span-<n> on a grid-rows-subgrid item; without it there are no rows to inherit.
  • Mixing up col-end-4 (grid line 4) with a span of four columns.
Quick Quiz
Question 1 of 2

Which template creates as many 16rem-minimum columns as fit and collapses empty tracks?

Key Takeaways

  • repeat(auto-fit, minmax(min, 1fr)) in an arbitrary template builds responsive grids without breakpoints.
  • col-span-*, col-start-* and col-end-* place items by span or by grid line; negative lines count from the end.
  • grid-flow-row-dense backfills holes and auto-rows-* sizes implicit rows.
  • Arbitrary properties [grid-template-areas:…] and [grid-area:name] give readable, reorderable page shells.
  • grid-rows-subgrid with row-span-* aligns card internals across a row.

Next lesson: Positioning, Z-Index and Sticky Elements — take elements out of the flow with absolute, fixed and sticky, and manage stacking order.

Grid In Depth: Auto-Fit, Spanning, Template Areas and Subgrid - Tailwind CSS | CodeYourCraft | CodeYourCraft