CSS Grid Cheatsheet

All CSS Grid container and item properties with values, descriptions, and copy-ready examples. Filter by category or search any property.

Showing 68 of 68 entries — click any card to copy the example

Grid vs Flexbox: When to Use Each

The most practical way to decide: Flexbox is one-dimensional, Grid is two-dimensional. If you are arranging items along a single row or a single column and want them to flow and distribute space among themselves, Flexbox is the right choice. If you need to place items on a defined grid — controlling both rows and columns — Grid is the right tool.

A real-world example: a navigation bar (items in a row with space between them) is a Flexbox job. The overall page layout (header, sidebar, main content, footer) is a Grid job. A card grid where cards should align across both rows and columns is Grid. The content inside each card — an icon, a title, and a description stacked vertically — is Flexbox. Most production UIs use both in the same component tree.

One more distinction: Flexbox is content-driven — the items determine how space is divided. Grid is layout-driven — you define the structure first, then place items into it. With Grid, items do not influence each other's size across tracks unless you explicitly use subgrid.

The fr Unit and minmax()

The fr unit distributes available space after all fixed-size tracks and gaps are accounted for. This makes it safer than percentages, which can cause overflow when combined with gaps. For example, grid-template-columns: 1fr 2fr 1fr gives you a 25% / 50% / 25% split that automatically adjusts — no manual percentage math needed.

minmax(min, max) defines a size range for a track. The track is at least min and at most max. The most powerful combination in responsive design is repeat(auto-fill, minmax(280px, 1fr)) — columns are at least 280px wide, share remaining space equally, and the browser decides how many fit in each row. The result: a fully responsive grid with no media queries.

Note: you cannot use fr as the minimum value in minmax() — use minmax(0, 1fr) instead of 1fr when you need tracks that can shrink below their content size.

Named Grid Areas

grid-template-areas lets you define a visual ASCII map of your layout using names. Each quoted string is a row, each word is a cell, and a dot (.) is an empty cell. This makes complex layouts readable at a glance — you can see the page structure right in your CSS.

Once the areas are defined, assign items with grid-area: name on each child element. The browser automatically handles the line numbers — you never need to count column/row lines manually.

Named areas are also ideal for responsive redesigns. To change from a two-column desktop layout to a single-column mobile layout, just redefine grid-template-columns and grid-template-areas inside a media query. The named area assignments on items stay the same — only the container definition changes.

Frequently Asked Questions

When should I use CSS Grid instead of Flexbox?

Use CSS Grid when you need to control layout in two dimensions — rows and columns simultaneously. Grid is ideal for page-level layouts, card grids with aligned rows and columns, and any design where placement of items needs to reference both axes. Use Flexbox for one-dimensional layouts — a navigation bar, a row of buttons, a vertical stack — where items flow along a single axis and the content determines spacing. In practice, many components use both: Grid for the outer page structure, Flexbox for aligning content within each grid item.

What does the fr unit mean in CSS Grid?

fr stands for fraction — it represents a fraction of the available space in the grid container after fixed-size tracks and gaps have been allocated. For example, grid-template-columns: 1fr 2fr 1fr creates three columns where the middle column is twice as wide as the others. They divide the remaining space in a 1:2:1 ratio. Unlike percentages, fr units automatically account for gaps and don't cause overflow. When combined with minmax(), as in repeat(auto-fill, minmax(200px, 1fr)), you get columns that are at least 200px but grow proportionally when extra space is available.

What is the difference between auto-fill and auto-fit in repeat()?

Both auto-fill and auto-fit create as many tracks as will fit in the container. The difference appears when there are fewer items than the grid has capacity for. With auto-fill, empty tracks are still created and retain their size, which can leave visible gaps. With auto-fit, empty tracks collapse to zero width, so the remaining items stretch to fill the available space. For responsive card grids, auto-fit is usually preferable because a small number of cards will expand to fill the row rather than cluster on one side.

How do I use grid-template-areas for layouts?

Define the layout visually in the container using grid-template-areas with quoted strings — each string is a row, each word is a cell name, and dots (.) represent empty cells. Then assign items to areas using grid-area: name on each child. For example: grid-template-areas: 'header header' 'sidebar main' 'footer footer' creates a two-column layout with a full-width header and footer. The named areas must form a rectangle — you cannot create L-shapes or other non-rectangular named regions. This approach makes layouts highly readable and easy to redesign with media queries by redefining the template-areas string.

How do I make a fully responsive grid without media queries?

The combination of repeat(auto-fill, minmax(min-size, 1fr)) creates a fully responsive grid that adjusts column count automatically as the container resizes. Set min-size to the minimum useful width for your cards (e.g., 280px). As the container narrows, columns wrap to fewer per row. As it widens, more columns fit. Pair this with grid-auto-rows: minmax(min-row-height, auto) to give rows a minimum height while allowing them to grow. This approach requires zero media queries and works across all viewport sizes.