CSS Grid
CSS Grid is a layout system for two dimensions: rows and columns at the same time. You define a grid of tracks on a container, and place items into cells or across areas, with precise alignment in both directions. Page layouts (header, sidebar, main, footer), image galleries, dashboards, pricing tables, and forms with aligned labels are all natural Grid territory.
Grid pairs with Flexbox. Flexbox excels at distributing items along one axis inside components, while Grid defines the overall structure. With repeat(), minmax(), auto-fit, and named areas, many responsive layouts need few or no media queries.
TL;DR
display: gridcreates a grid container; define tracks withgrid-template-columnsandgrid-template-rows.- The
frunit distributes free space;minmax(min, max)sets flexible track bounds. repeat(auto-fit, minmax(240px, 1fr))builds responsive card grids without media queries.- Place items by line numbers (
grid-column: 1 / -1) or named areas (grid-template-areas). - Items not explicitly placed flow into the implicit grid (
grid-auto-rows,grid-auto-flow). subgridlets nested elements align to the parent grid's tracks, which is great for aligned card contents.
Quick Example
A classic application layout with named areas that restructures on small screens:
Core Concepts
Grid Terminology
- Lines: the dividing lines of the grid, numbered from 1 (and from −1 counting from the end).
- Tracks: rows or columns between two lines.
- Cells: the intersection of a row and a column track.
- Areas: rectangular groups of cells, optionally named.
- Gutters: the gaps between tracks (
gap,row-gap,column-gap).
Defining Tracks
frshares leftover space after fixed and content-sized tracks are resolved.minmax(a, b)keeps a track betweenaandb.minmax(0, 1fr)prevents wide content from blowing out a column, since1fralone has an implicitautominimum.min-content,max-content, andfit-content(300px)size tracks by their content.
auto-fit vs auto-fill
With repeat(auto-fill | auto-fit, minmax(240px, 1fr)), the browser creates as many columns as fit:
auto-fillkeeps empty tracks when there are few items, so items stay at their minimum-ish size.auto-fitcollapses empty tracks, so items stretch to fill the row.
Wrap the minimum in min(240px, 100%) so a single column never overflows a narrow screen.
Placing Items
Lines can also be named (grid-template-columns: [full-start] 1fr [content-start] minmax(0, 60rem) [content-end] 1fr [full-end]), which enables "breakout" layouts where most content sits in a readable column while images span full width.
Named Areas
grid-template-areas draws the layout as ASCII art. Each string is a row, each word a cell, and . is an empty cell. Items opt in with grid-area: name. Redefining the template in a media or container query rearranges the whole layout without touching the HTML.
The Implicit Grid
Items beyond the explicit tracks create implicit tracks, sized by grid-auto-rows and grid-auto-columns. grid-auto-flow controls placement direction (row by default, or column), and dense backfills holes. That's useful for masonry-like galleries, though it changes visual order.
Alignment
Grid supports alignment on both axes, for the whole grid inside the container and for items inside their cells:
place-items: center on a grid container is the shortest way to center content.
Subgrid
grid-template-columns: subgrid (or rows) makes a nested grid use its parent's tracks. For example, cards in a row can align their titles, bodies, and footers across cards even when content lengths differ, which was previously impossible without fixed heights. It's supported in all modern browsers.
Best Practices
Use Grid for Structure, Flexbox for Components
Define page and section structure with Grid, then lay out component internals (toolbars, button rows, media objects) with Flexbox.
Guard Against Overflow With minmax(0, 1fr)
Long words, code blocks, or wide tables can force 1fr tracks wider than intended. minmax(0, 1fr) tracks, plus min-width: 0 on items, keep layouts contained.
Keep Source Order Logical
Grid lets you place items anywhere visually, but keyboard focus and screen readers follow DOM order. Keep the DOM in a sensible reading order and use placement for presentation. See accessibility.
Let Intrinsic Sizing Do the Work
auto-fit/minmax() patterns and content-based track sizes often eliminate breakpoints entirely. Combine them with container queries for truly component-driven responsiveness. See responsive design.
Common Mistakes
Grid Blowout From Long Content
Confusing auto-fill and auto-fit
With few items, auto-fill leaves empty columns and items stay narrow, while auto-fit stretches them. Choose based on whether items should grow to fill the row.
Recreating 12-Column Frameworks Everywhere
Wrapping everything in repeat(12, 1fr) with span classes reintroduces framework rigidity. Define tracks that match each layout's actual structure.
FAQ
When should I use Grid instead of Flexbox?
Use Grid when you need alignment in both rows and columns, or when the layout defines the structure and content fills it: page layouts, galleries, dashboards, forms. Use Flexbox when items flow in one direction and their size should drive spacing: navbars, toolbars, tag lists.
What does the fr unit mean?
A fraction of the remaining free space in the grid container, after fixed-size and content-sized tracks are accounted for. 1fr 2fr gives the second column twice the leftover space of the first.
How do I make a responsive grid without media queries?
grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)) automatically creates as many columns as fit, each at least 250px wide, collapsing to one column on narrow screens.
Is CSS masonry layout supported?
A native masonry layout for Grid (grid-template-rows: masonry, and alternative proposals) has been under specification and experimentation in browsers. Until it's broadly available, use grid-auto-flow: dense approximations, CSS columns, or a small JavaScript library.
Related Topics
- CSS — The styling language overview
- CSS Flexbox — One-dimensional layout
- CSS Container Queries — Layouts that respond to their container
- Responsive Design — Adapting to screen sizes
- Design Systems — Layout primitives in component libraries
- Accessibility — Source order and visual order