CSS Grid Layouts You Will Use on Every Project

AJ
15 min read

Grid Patterns You'll Actually Use

Let's be honest for a second. How many times have you Googled "CSS Grid template columns" this month? If you're like most frontend developers, the answer is "too many." CSS Grid is incredibly powerful, but most of us only need a handful of patterns for our day-to-day web development work. The problem is that Grid has so many features that it can feel overwhelming. You read the MDN docs, see terms like "implicit grid tracks" and "grid-template-areas," and your brain just checks out. But here's the thing: you don't need to master every single Grid property to be productive. You need the same six or seven patterns, and you need to know them well enough that you can reach for them without thinking.

In this post, I'm going to walk you through the CSS Grid layouts that I use on literally every project. Whether I'm building a dashboard in Next.js, laying out a marketing page with Tailwind CSS, or putting together a design system, these are the patterns that come up again and again. Each one includes copy-paste-ready code so you can drop them straight into your React components.

┌────────────────────┐     ┌──────────────────────┐     ┌────────────────────┐
│  Layout Problem     │────▶│  Pick a Grid Pattern  │────▶│  Copy & Paste Code │
│  (cards, sidebar,   │     │  (auto-fit, holy      │     │  (Tailwind classes  │
│   dashboard, etc.)  │     │   grail, form grid)   │     │   ready to go)     │
└────────────────────┘     └──────────────────────┘     └────────────────────┘
                                     │
                                     ▼
                           ┌──────────────────────┐
                           │  Customize for Your   │
                           │  Specific Breakpoints │
                           │  and Spacing Needs    │
                           └──────────────────────┘

1. Auto-Fit Card Grid

This is probably the most commonly needed layout in all of frontend development. You have a bunch of cards and you want them to fill the available space, wrapping automatically as the screen gets smaller. No media queries. No breakpoint math. Just cards that figure out their own arrangement. The secret sauce here is the combination of auto-fill (or auto-fit) with the minmax() function. You tell CSS Grid the minimum and maximum size for each column, and it figures out how many columns fit in the available space. When the container gets narrower, it automatically drops columns and wraps. It's honestly magical.

auto-grid.tsx

When to Use auto-fill vs Breakpoint Columns

The auto-fill approach is great when you want a truly fluid layout. Cards will fill whatever space is available, and you don't have to think about breakpoints at all. But sometimes you want more control. Maybe you specifically want two columns on tablet and three on desktop, regardless of the container width. In that case, the breakpoint approach (sm:grid-cols-2 lg:grid-cols-3) gives you that precision. In my experience, I use the breakpoint approach about 70% of the time because designers usually have a specific layout in mind for each screen size.

Handling Different Card Heights

One gotcha with card grids: if your cards have varying heights, the grid rows will stretch to fit the tallest card in each row. This is usually fine, but if it bothers you, you can use grid-auto-rows: min-content or consider a masonry layout. For most UI components in a design system, keeping cards the same height actually looks cleaner anyway.

2. Sidebar Layout

Almost every web application has a sidebar. Email clients, dashboards, admin panels, documentation sites. The sidebar layout is one of those patterns you'll build over and over in your frontend development career. The key insight with CSS Grid is that you can have a fixed-width sidebar and a flexible main content area in one line of code. No absolute positioning. No calc() hacks. Just a simple grid template that does exactly what you want.

sidebar.tsx

Making the Sidebar Collapsible

The collapsible sidebar pattern is really clean with CSS Grid and Tailwind CSS. You just toggle between two grid-template-columns values. The transition-all duration-300 handles the animation smoothly. Inside the sidebar component, you'd conditionally show icon-only navigation when collapsed and full labels when expanded. This is one of those React component patterns that every design system needs, and CSS Grid makes the layout part trivially easy.

Dealing with Sidebar Overflow

A common issue with sidebar layouts is content overflow. If your sidebar has a long navigation list, you want it to scroll independently from the main content. Add overflow-y-auto to the sidebar and h-screen sticky top-0 to keep it fixed while the main content scrolls. This gives you the classic app layout that users expect from modern web applications.

3. Holy Grail Layout

The "Holy Grail" layout has been a classic web development challenge since the early days of CSS. Header at the top, footer at the bottom, main content that stretches to fill the remaining space. For years, developers used all sorts of hacks to achieve this: negative margins, calc() with viewport units, flexbox tricks. With CSS Grid, it's literally one property. The pattern grid-rows-[auto_1fr_auto] says: first row is as tall as its content, middle row takes all remaining space, last row is as tall as its content. That's it.

holy-grail.tsx

Why min-h-screen Matters

Without min-h-screen, the grid container will only be as tall as its content. That means on pages with very little content, the footer won't stick to the bottom of the viewport. It'll be floating somewhere in the middle of the page, which looks terrible. The min-h-screen class ensures the grid is at least as tall as the viewport, pushing the footer to the bottom even on short-content pages. This is a tiny detail that makes a huge difference in how professional your Next.js application looks.

4. Dashboard Grid

Dashboards are where CSS Grid really shines. You typically have stat cards at the top, a big chart in the middle, and some tables or lists at the bottom. The different sections need different column configurations, and Grid handles this beautifully. You can mix and match column counts, span items across multiple columns, and create asymmetric layouts that would be a nightmare with Flexbox alone.

dashboard.tsx

The 7-Column Trick

Notice that weird lg:grid-cols-7 in the dashboard example? That's a trick for creating non-50/50 splits. With 7 columns, you can do a 4/3 split, which looks much more intentional than a boring 50/50. You could also use grid-cols-12 for a traditional 12-column grid system, but I find that most dashboard layouts only need 2, 3, 4, or 7 columns. Keep it simple. The 7-column trick is particularly useful in design systems where you want to give more space to primary content without making the secondary content feel cramped.

Making Dashboards Responsive

The beautiful thing about this pattern is how easily it goes responsive. On mobile, everything stacks into a single column. On tablet, you get two columns. On desktop, you get the full multi-column layout. All with just Tailwind CSS utility classes. No custom CSS, no media query objects, no separate mobile components. This is why Tailwind CSS and CSS Grid work so well together for modern web development.

Dashboard Layout Hierarchy
═══════════════════════════

┌─────────┬─────────┬─────────┬─────────┐
│  Stat 1 │  Stat 2 │  Stat 3 │  Stat 4 │   ◀── 4 equal columns
├─────────┴─────────┴─────────┴─────────┤
│              Revenue Chart             │   ◀── Full width
├──────────────────────┬────────────────┤
│    Recent Orders     │  Top Products  │   ◀── 4/3 weighted split
│    (col-span-4)      │  (col-span-3)  │
├──────────┬───────────┬────────────────┤
│  Feed    │  Alerts   │  Quick Actions │   ◀── 3 equal columns
└──────────┴───────────┴────────────────┘

Mobile: Everything stacks to 1 column
Tablet: 2 columns for stats, 1 for rest
Desktop: Full layout as shown above

5. Centered Content

Centering things in CSS has been a running joke in the web development community for years. But with Grid, it's genuinely trivial. The place-items-center utility is the shortest path to perfect centering, both horizontally and vertically. I use this for login pages, empty states, error pages, loading screens, and any other situation where you want content dead center in its container.

centered.tsx

place-items vs place-content

Quick clarification because this trips people up. place-items-center centers each item within its grid cell. place-content-center centers the entire grid content as a group. For most centering use cases, place-items-center is what you want. But if you have multiple items and want them clustered together in the center, place-content-center is your friend. Both are equally valid approaches in modern CSS layout, and both work perfectly with Tailwind CSS.

6. Form Layout

Forms are everywhere in web applications, and getting the layout right is crucial for usability. A two-column form grid with the ability to have some fields span both columns is one of the most practical CSS Grid patterns. It gives you a clean, organized layout on desktop while stacking gracefully on mobile. The key is the col-span-2 utility for fields that need the full width, like email addresses or text areas.

form-grid.tsx

Fieldset Grouping for Better Accessibility

Wrapping related form fields in fieldset elements with legend labels is not just about organization. It's an accessibility requirement. Screen readers use fieldset/legend to group related inputs and announce the group name before each field. This is a perfect example of how CSS Grid layout and HTML semantics work together to create better UI components. Your forms will look better and be more accessible at the same time.

7. Content + Aside Layout

Blog posts, documentation pages, and long-form content often need a main content area with a sticky sidebar for navigation or related content. This is different from the app sidebar layout because the sidebar content needs to be sticky as the main content scrolls. CSS Grid handles the layout, and a touch of sticky positioning handles the scroll behavior.

content-aside.tsx

Grid vs Flexbox: When to Use Which

This is the question that every frontend developer asks at some point, and the answer is simpler than you think. It's not about which one is "better." They solve different problems, and the best React component patterns use both. Here's my mental model after years of building UI components with both.

The Decision Framework

  • Grid: When you need rows AND columns. Dashboards, page layouts, card grids, form layouts.
  • Flexbox: When you need one direction. Nav bars, button groups, centering, inline elements.
  • Both: Grid for the page layout, Flexbox inside individual components. This is the most common pattern.
  • Flexbox wrap: When items can be different sizes. Tag lists, chip groups, toolbar buttons.
  • Grid auto-fill: When items should be the same size. Card grids, image galleries, product listings.

A Real-World Example: Navigation Bar

Consider a typical navigation bar. You have a logo on the left, nav links in the middle, and user actions on the right. You might think Grid is the answer because you have three distinct areas. But Flexbox is actually better here because the middle section has a variable number of items that need to be evenly spaced. Flexbox's justify-between handles this perfectly. On the other hand, the page layout that contains that nav bar is a Grid job. The nav goes in the header row, the content goes in the main row, and the footer goes at the bottom. It's Grid and Flexbox working together.

Advanced Grid Techniques

Once you're comfortable with the basic patterns, here are some advanced techniques that can save you a lot of time in your web development projects.

Subgrid for Aligned Content

Subgrid lets child elements align with the parent grid's tracks. This is incredibly useful for card grids where you want the title, description, and action button of each card to align across the row, regardless of content length. Browser support is now excellent. If you're building a design system with React and Tailwind CSS, subgrid is a game changer for consistent card layouts.

Named Grid Areas

For complex layouts, named grid areas can make your code much more readable. Instead of counting column spans, you give each area a name and draw the layout visually with strings. While Tailwind CSS doesn't have built-in utilities for this, you can use arbitrary values or add them to your Tailwind config. This is especially helpful for layouts that change dramatically between mobile and desktop breakpoints.

Container Queries and Grid

Container queries are changing how we think about responsive design in modern CSS. Instead of responding to the viewport width, components can respond to their own container's width. This pairs beautifully with CSS Grid. Imagine a card component that switches from horizontal to vertical layout based on how much space it has in the grid, regardless of the screen size. Tailwind CSS now supports container queries, and they're a perfect complement to Grid-based layouts.

Common Pitfalls and How to Avoid Them

The Overflow Problem

Grid items with long text or wide images can overflow their grid cells, breaking the layout. Always add min-w-0 to grid items that contain text content. Without it, the minimum width of a grid item defaults to auto, which means it can push the grid wider than intended. This is probably the most common CSS Grid bug in React applications, and the fix is always the same: add min-w-0 or overflow-hidden.

Gap Inconsistency

Use a consistent gap scale across your entire design system. If your card grid uses gap-6, your dashboard grid should probably use the same. Mixing gap-2, gap-4, and gap-8 randomly makes the UI feel unpolished. Pick two or three gap values and stick with them. Your Tailwind CSS config can enforce this with a custom spacing scale.

Pro Tip: Debug with Borders

When a Grid layout isn't behaving as expected, add border border-red-500 to each grid item temporarily. This makes the grid structure visible and helps you see exactly where items are being placed. Chrome DevTools also has a grid overlay tool that shows grid lines, but sometimes a quick border is faster for debugging during frontend development.

The Short Version

  • auto-fill + minmax = responsive cards without breakpoints
  • grid-cols-[fixed_1fr] = sidebar layout
  • grid-rows-[auto_1fr_auto] = header/content/footer
  • place-items-center = center anything
  • col-span-2 = full-width fields in a form grid
  • Grid for 2D layouts, Flexbox for 1D layouts, both together for real apps
  • Always add min-w-0 to grid items with text content
  • Use a consistent gap scale across your design system
  • Container queries + Grid = the future of responsive UI components

CSS Grid has fundamentally changed how we build layouts for the web. The patterns in this post cover the vast majority of what you'll need for real-world frontend development with React, Next.js, and Tailwind CSS. Bookmark this page, steal the code snippets, and stop Googling CSS Grid template columns. You've got this.

Related Articles

Your Product
Deserves a better ui