CSS Flexbox and Grid — Complete Layout Guide

Photo: Bibek ghosh / Pexels
CSS layout was painful for years. Developers floated elements, cleared floats, and performed strange clearfix rituals to achieve basic layouts. Then Flexbox arrived, followed by Grid, and modern CSS layout became genuinely enjoyable.
Understanding both layout systems — and knowing when to reach for each — is one of the highest-leverage CSS skills you can develop.
Flexbox vs Grid: The Core Distinction
The single most useful mental model:
- Flexbox is for one-dimensional layouts — a row of buttons, a navigation bar, a column of items in a sidebar.
- Grid is for two-dimensional layouts — a full page layout, a card grid, a dashboard with rows and columns.
| Feature | Flexbox | Grid |
|---|---|---|
| Dimensions | 1D (row or column) | 2D (rows and columns) |
| Control source | Content drives layout | Layout drives content |
| Item sizing | Items size themselves | Layout defines slots |
| Best for | Components, UI elements | Page layouts, galleries |
| Browser support | Excellent | Excellent (IE excluded) |
| Alignment | Powerful | Powerful |
In practice you'll use both — Grid for the page structure, Flexbox for the components inside each grid area.
Flexbox
Enable Flexbox by setting display: flex on a container element. All direct children become flex items.
display: flex;
}
Flex Container Properties
flex-direction controls whether items flow in a row or column:
flex-direction: row; /* default: left to right */
flex-direction: row-reverse; /* right to left */
flex-direction: column; /* top to bottom */
flex-direction: column-reverse;/* bottom to top */
justify-content aligns items along the main axis (horizontal in a row, vertical in a column):
justify-content: flex-start; /* default: pack to start */
justify-content: flex-end; /* pack to end */
justify-content: center; /* center */
justify-content: space-between;/* gaps between items, none at edges */
justify-content: space-around; /* equal space around each item */
justify-content: space-evenly; /* equal space including edges */
align-items aligns items along the cross axis (vertical in a row):
align-items: stretch; /* default: items fill container height */
align-items: flex-start;/* align to top */
align-items: flex-end; /* align to bottom */
align-items: center; /* center vertically */
align-items: baseline; /* align text baselines */
flex-wrap controls whether items wrap to a new line when they overflow:
flex-wrap: nowrap; /* default: no wrapping */
flex-wrap: wrap; /* wrap to next line */
flex-wrap: wrap-reverse; /* wrap in reverse */
gap sets spacing between items (no more margin hacks):
gap: 16px; /* equal gap in both directions */
gap: 8px 16px; /* row-gap column-gap */
Practical Example: Navbar
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
height: 60px;
}.nav-links {
display: flex;
gap: 24px;
list-style: none;
}
<nav class="navbar">
<a href="/" class="logo">Brand</a>
<ul class="nav-links">
<li><a href="/about">About</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
Flex Item Properties
These go on the items inside a flex container.
flex-grow — how much of the remaining space an item takes:
If three items have flex-grow: 1, flex-grow: 2, flex-grow: 1, the available space splits 1:2:1.
flex-shrink — how much an item shrinks when there's not enough space:
flex-basis — the initial size before growing or shrinking:
The shorthand: flex: grow shrink basis
align-self overrides align-items for a single item:
order changes visual order without changing HTML order (useful for accessibility):
Centering with Flexbox
Centering both horizontally and vertically:
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
This is the cleanest centering solution in CSS.
CSS Grid
Grid gives you explicit control over rows and columns. Enable it with display: grid.
Defining the Grid
grid-template-columns and grid-template-rows define the grid structure:
display: grid;
grid-template-columns: 200px 1fr 200px; /* fixed | flexible | fixed */
grid-template-rows: auto;
gap: 24px;
}
The fr unit (fractional unit) distributes available space. 1fr 2fr means the second column gets twice the width of the first.
repeat() avoids repetition:
/* 3 equal columns */
grid-template-columns: repeat(3, 1fr);
/* 12-column grid */
grid-template-columns: repeat(12, 1fr);
auto-fill vs auto-fit
Both work with repeat() to create responsive grids without media queries.
/* auto-fill: creates as many columns as fit, even empty ones */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* auto-fit: collapses empty columns, items stretch to fill */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
auto-fit is usually what you want for card grids — items expand to fill the container when there aren't enough to fill a row.
/* Responsive card grid with no media queries */.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}
Placing Items
By default, Grid places items in document order, filling rows left to right. You can override this with placement properties.
Line-based placement:
grid-column: 1 / 4; /* span from line 1 to line 4 */
grid-row: 1 / 2;
}.sidebar {
grid-column: 1 / 2;
grid-row: 2 / 4;
}.main {
grid-column: 2 / 4;
grid-row: 2 / 3;
}
Named template areas — more readable for page layouts:
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 240px 1fr 1fr;
grid-template-rows: 60px 1fr 80px;
min-height: 100vh;
}.header { grid-area: header; }.sidebar { grid-area: sidebar; }.main { grid-area: main; }.footer { grid-area: footer; }
This reads almost like a wireframe.
span keyword:
grid-column: span 2; /* take 2 columns */
}
Grid Alignment
Grid has the same alignment properties as Flexbox, plus justify-items and align-items which control item alignment within their grid cell.
justify-items: stretch; /* default: fill cell width */
align-items: stretch; /* default: fill cell height */
}
/* Center all items within their cells */.grid {
justify-items: center;
align-items: center;
}
justify-content and align-content align the entire grid within the container when the grid is smaller than the container.
Common Layout Patterns
Holy Grail Layout (Header, Footer, Sidebar, Main)
display: grid;
grid-template:
"header" 60px
"sidebar main" 1fr
"footer" 80px
/ 240px 1fr;
min-height: 100vh;
}
<div class="page">
<header style="grid-area: header">...</header>
<aside style="grid-area: sidebar">...</aside>
<main style="grid-area: main">...</main>
<footer style="grid-area: footer">...</footer>
</div>
Responsive Card Grid
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
padding: 20px;
}
No media queries. Cards are at least 300px wide and expand to fill available space.
Sidebar + Content
display: grid;
grid-template-columns: 280px 1fr;
gap: 32px;
}
@media (max-width: 768px) {.layout {
grid-template-columns: 1fr;
}
}
Stack with Space Between (Flexbox)
A common pattern: stack items vertically with a button always at the bottom.
display: flex;
flex-direction: column;
height: 300px;
}.card-content {
flex: 1; /* takes remaining space */
}.card-button {
/* naturally stays at the bottom */
}
Choosing Between Them in Practice
A useful heuristic: if you're thinking in rows or columns, use Flexbox. If you're thinking in rows and columns, use Grid.
For a navigation bar — Flexbox. Items sit in a row with spacing between them.
For a product listing page — Grid. Cards need consistent rows and columns.
For a button with an icon and text — Flexbox. Icon and text sit side by side.
For a dashboard with panels — Grid. Panels occupy defined areas.
There's no penalty for using both in the same layout. A Grid defines the page structure; Flexbox handles the components inside each grid area.
Frequently Asked Questions
Q: Is Flexbox or Grid better? A: Neither — they solve different problems. Flexbox is better for one-dimensional arrangements (a row of buttons, a vertical list). Grid is better for two-dimensional layouts (a page with columns and rows). Most modern layouts use both.
Q: What does fr mean in Grid?
A: fr stands for "fractional unit." It represents a fraction of the available space in the grid container. 1fr 2fr 1fr divides space in a 1:2:1 ratio. It's like flexbox's flex-grow but for grid tracks.
Q: How do I center something with CSS Grid?
A: Use place-items: center on the grid container (shorthand for align-items: center; justify-items: center). Or use place-content: center to center the entire grid within its container.
Q: What's the difference between align-items and align-content in Flexbox?
A: align-items aligns items within a single line on the cross axis. align-content aligns multiple lines (only applies when flex-wrap is enabled and there's more than one row/column of items).
Q: How do I make a grid item span multiple columns?
A: Use grid-column: span N where N is the number of columns to span, or specify exact lines: grid-column: 1 / 4 spans from grid line 1 to grid line 4.
Q: Should I still use media queries with Grid?
A: You need fewer of them. auto-fit with minmax() handles many responsive breakpoints automatically. But explicit media queries are still useful for structural changes — like switching from a two-column layout to a single column on mobile.
Related Articles
- CSS-in-JS vs Tailwind — CSS methodology choices for modern projects
- Complete Web Dev Learning Path 2026 — Where CSS fits in your learning journey
- Best Web Dev Tools 2026 — Tools for inspecting and debugging layouts
Sources
- MDN Web Docs — Flexbox — Mozilla Developer Network
- MDN Web Docs — Grid — Mozilla Developer Network
- CSS Tricks — A Complete Guide to Flexbox — css-tricks.com
- CSS Tricks — A Complete Guide to Grid — css-tricks.com
- Can I Use — CSS Grid — Browser compatibility data
Follow new articles
Add SciHub101 to your feed reader to see new science and technology stories.
About the Author
SciHub101 is an independent science and technology publication founded and edited by Buğra Sözeri, a software engineer and app developer based in Türkiye. AI tools assist with drafting and research. Source documentation in the existing archive is uneven, and articles are being reviewed and corrected. The Editorial Team byline identifies editorial responsibility; it does not certify specialist or independent human review. Where we compare products, anything built by our own team is labelled as such — see the editorial guidelines and About page for how corrections and disclosures work.
Related Articles

React Hooks Explained — useState and useEffect
React Hooks explained from scratch: how useState and useEffect work, the dependency array, cleanup, Strict Mode, common bugs, and when not to use an effect.

Web Accessibility Guide 2026 — WCAG, ARIA, Testing Tools
Web accessibility for developers: what WCAG 2.2 AA requires, how to use semantic HTML and ARIA, keyboard support, and a testing workflow that catches bugs.

Tailwind CSS Explained — Why It Dominates Web Design 2026
Tailwind CSS for beginners: why utility-first CSS won, common patterns, integration with React/Next.js, gotchas. The CSS framework everyone uses in 2026.

Responsive Design & Mobile-First Development Guide 2026
Responsive web design guide 2026: mobile-first CSS, Flexbox, Grid, media queries, touch-friendly UI. Real code examples and checklist for every project.

HTML, CSS, JavaScript Fundamentals — Web Dev Basics
Learn the three pillars of web development. HTML structure, CSS styling, JavaScript interactivity. Interactive examples.

What Is HTMX? Hypermedia for Modern Web
HTMX explained: how this 14KB library lets you build dynamic web apps with HTML attributes instead of a JavaScript framework, plus how it actually works.