CSS Grid and Flexbox are the two most powerful layout systems in modern CSS, and they're often presented as competitors. In reality, they're complementary tools designed for different problems. Grid excels at two-dimensional layouts where you need to control both rows and columns simultaneously, while Flexbox shines for one-dimensional layouts — distributing space along a single axis. This guide provides a detailed comparison with practical, copy-paste examples for real-world layout challenges.
The Core Difference: 1D vs 2D
The single most important distinction is dimensionality:
- Flexbox is one-dimensional. It lays out items along a single axis — either a row or a column. Items can wrap to the next line, but each line is laid out independently.
- CSS Grid is two-dimensional. It controls both rows and columns at the same time, allowing you to place items precisely within a defined grid structure.
This means Flexbox is ideal when your layout flows in one direction (a navbar, a toolbar, a card's internal structure), while Grid is the right choice when you need to align items across both axes (a page layout, a dashboard, a photo gallery).
Flexbox Fundamentals
Flexbox distributes space among items in a container along the main axis (horizontal by default) and controls alignment on the cross axis (vertical by default).
.flex-container {
display: flex;
flex-direction: row; /* main axis: horizontal */
justify-content: center; /* align along main axis */
align-items: center; /* align along cross axis */
gap: 1rem; /* spacing between items */
flex-wrap: wrap; /* allow items to wrap */
}
.flex-item {
flex: 1 1 200px;
/* flex-grow: 1 — item can grow to fill space */
/* flex-shrink: 1 — item can shrink if needed */
/* flex-basis: 200px — ideal starting width */
}
Key Flexbox Properties
justify-content— distributes items along the main axis:flex-start,flex-end,center,space-between,space-around,space-evenly.align-items— aligns items along the cross axis:stretch,flex-start,flex-end,center,baseline.flex-wrap— controls whether items wrap to new lines or stay on one line.gap— adds consistent spacing between items without margin hacks.order— changes the visual order of an item without changing the DOM.
CSS Grid Fundamentals
Grid lets you define a complete layout structure up front with explicit rows and columns, then place items into that structure.
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-rows: auto 1fr auto; /* header, content, footer */
gap: 1.5rem;
min-height: 100vh;
}
/* Place items explicitly */
.header { grid-column: 1 / -1; } /* span all columns */
.sidebar { grid-column: 1; }
.main { grid-column: 2 / -1; }
.footer { grid-column: 1 / -1; }
Key Grid Properties
grid-template-columns/grid-template-rows— define the track sizes of the grid.frunit — represents a fraction of the available space.1fr 2frcreates two columns where the second is twice as wide.repeat()— shorthand for repeating track definitions:repeat(4, 1fr)creates 4 equal columns.grid-column/grid-row— place items by line number.1 / -1means "from the first line to the last".grid-template-areas— name regions of the grid for intuitive placement (shown in recipes below).minmax()— set minimum and maximum sizes for tracks:minmax(250px, 1fr).
Side-by-Side Comparison
/* Flexbox centering */
.center-flex {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* Grid centering — even simpler */
.center-grid {
display: grid;
place-items: center;
min-height: 100vh;
}
For simple centering, Grid's place-items: center is more concise. But for layouts where items need to distribute along a single axis, Flexbox's justify-content options provide more granular control.
Alignment Comparison
Both Grid and Flexbox share alignment properties, but they behave differently:
- In Flexbox,
justify-contentworks along the main axis (horizontal by default) andalign-itemsalong the cross axis. - In Grid,
justify-itemsandalign-itemswork on items within their cells, whilejustify-contentandalign-contentdistribute the tracks within the container. - Grid adds
place-itemsandplace-contentas shorthand for setting both axes at once.
Nesting Grid & Flexbox
The most effective layouts combine both systems. Use Grid for the overall page structure and Flexbox for component-level layouts within grid cells.
/* Page layout with Grid */
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr 50px;
min-height: 100vh;
}
/* Navbar inside a grid cell uses Flexbox */
.navbar {
grid-column: 1 / -1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 2rem;
}
/* Card inside main content uses Flexbox */
.card {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 1.5rem;
}
Responsive Patterns
Responsive Card Grid with Grid
One of Grid's most powerful features is auto-fit / auto-fill with minmax(), which creates responsive grids without media queries.
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
padding: 2rem;
}
/*
* auto-fill: creates as many 280px+ columns as fit
* minmax(280px, 1fr): each column is at least 280px,
* grows equally to fill remaining space
*
* Result: 1 column on mobile, 2 on tablet, 3-4 on desktop
* NO media queries needed!
*/
Responsive Navigation with Flexbox
.navbar {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
gap: 1rem;
}
.navbar-brand {
flex: 0 0 auto; /* don't grow or shrink */
}
.navbar-links {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
}
/* On small screens, links take full width */
@media (max-width: 640px) {
.navbar-links {
flex-basis: 100%;
flex-direction: column;
gap: 0.5rem;
}
}
Real-World Layout Recipes
Recipe 1: Holy Grail Layout
The classic holy grail layout — header, footer, main content with two sidebars — is trivial with CSS Grid and grid-template-areas.
.holy-grail {
display: grid;
grid-template-areas:
"header header header"
"left main right"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 1rem;
}
.header { grid-area: header; background: #1a1a2e; }
.left { grid-area: left; background: #16213e; }
.main { grid-area: main; background: #0f3460; }
.right { grid-area: right; background: #16213e; }
.footer { grid-area: footer; background: #1a1a2e; }
/* Collapse sidebars on mobile */
@media (max-width: 768px) {
.holy-grail {
grid-template-areas:
"header"
"main"
"left"
"right"
"footer";
grid-template-columns: 1fr;
}
}
Recipe 2: Responsive Card Grid
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 2rem;
}
/* Each card uses Flexbox for internal layout */
.card {
display: flex;
flex-direction: column;
border-radius: 12px;
overflow: hidden;
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.card-body {
flex: 1; /* grows to fill available space */
padding: 1.5rem;
}
.card-footer {
padding: 1rem 1.5rem;
margin-top: auto; /* pushes footer to bottom */
border-top: 1px solid #eee;
}
Notice the powerful combination: Grid handles the overall responsive grid layout (equal-height cards across rows), while Flexbox handles each card's internal structure (pushing the footer to the bottom regardless of content length).
Recipe 3: Sidebar Layout
.sidebar-layout {
display: grid;
grid-template-columns: 280px 1fr;
min-height: 100vh;
}
.sidebar {
position: sticky;
top: 0;
height: 100vh;
overflow-y: auto;
padding: 2rem;
background: #f8f9fa;
border-right: 1px solid #dee2e6;
}
.sidebar-nav {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.content {
padding: 2rem 3rem;
overflow-y: auto;
}
/* Stack on mobile */
@media (max-width: 768px) {
.sidebar-layout {
grid-template-columns: 1fr;
}
.sidebar {
position: static;
height: auto;
border-right: none;
border-bottom: 1px solid #dee2e6;
}
}
Recipe 4: Navbar with Logo, Links & Actions
.navbar {
display: flex;
align-items: center;
padding: 0 2rem;
height: 60px;
background: #1a1a2e;
color: white;
}
.navbar-brand {
flex: 0 0 auto;
font-weight: 700;
font-size: 1.25rem;
margin-right: 2rem;
}
.navbar-links {
display: flex;
gap: 1.5rem;
flex: 1; /* takes remaining space, pushing actions right */
}
.navbar-links a {
color: rgba(255, 255, 255, 0.8);
text-decoration: none;
transition: color 0.2s;
}
.navbar-links a:hover {
color: white;
}
.navbar-actions {
display: flex;
gap: 0.75rem;
flex: 0 0 auto;
}
This pattern uses Flexbox's flex: 1 on the links section to create a natural gap between the navigation links and the action buttons on the right — no margin-left: auto hack needed.
When to Use Which: Decision Guide
Use this quick decision framework when choosing between Grid and Flexbox:
- Use Flexbox when:
- You're laying out items in a single row or column.
- Content size should determine the layout (content-first).
- You need to distribute space among items of varying sizes.
- Examples: navbars, toolbars, form rows, card internals, centering a single element.
- Use Grid when:
- You need to control layout in two dimensions simultaneously.
- The layout structure should be defined in advance (layout-first).
- You want items to align across both rows and columns.
- Examples: page layouts, dashboards, image galleries, data tables, any design that needs a "grid".
- Use both when:
- The page structure uses Grid, and individual components within grid cells use Flexbox.
- This is the most common pattern in production applications.
Common Mistakes to Avoid
- Using Grid for everything — a simple row of buttons doesn't need Grid. Flexbox is simpler and more appropriate.
- Using Flexbox for page layouts — while possible, it requires more workarounds than Grid for two-dimensional structures.
- Forgetting
gap— both Grid and Flexbox support thegapproperty. Stop using margin hacks. - Not testing with varying content — layouts break when content length varies. Test with short, long, and missing content.
- Ignoring
min-width: 0— flex and grid items have an implicitmin-width: autothat prevents them from shrinking below their content size. Addmin-width: 0to allow text truncation or overflow handling.
Conclusion
CSS Grid and Flexbox aren't competing technologies — they're partners. Grid handles the macro layout (the overall page structure), while Flexbox handles the micro layout (component internals). The best modern CSS uses both liberally, choosing the right tool for each specific layout challenge. Master both, and you'll be able to build any layout design throws at you — cleanly, responsively, and without hacks.
Optimise Your Stylesheets
Use Pan Tool's CSS tools to minify your production stylesheets or beautify minified CSS for debugging and review.