CSS Flexbox and Grid ā Complete Layout Guide
Master CSS Flexbox and CSS Grid with practical examples. Build responsive navbars, card grids, holy grail layouts, and understand when to use each.
CSS Flexbox and Grid
Before Flexbox and Grid, CSS layouts were hacked together with floats and positioning. Now these two tools handle 95% of everything you need. Learn both ā they complement each other.
Rule of thumb: Flexbox for one-dimensional layouts (row OR column). Grid for two-dimensional layouts (rows AND columns simultaneously).
CSS Flexbox
Apply display: flex to a container to turn its direct children into flex items.
The Main Axis and Cross Axis
The key mental model:
- Main axis = the direction flex items flow (
flex-direction) - Cross axis = perpendicular to main axis
.container {
display: flex;
flex-direction: row; /* default: left to right */
/* flex-direction: column; top to bottom */
/* flex-direction: row-reverse; right to left */
/* flex-direction: column-reverse; bottom to top */
}Alignment Properties
.container {
display: flex;
/* Align along MAIN axis */
justify-content: flex-start; /* default ā pack at start */
justify-content: flex-end; /* pack at end */
justify-content: center; /* center */
justify-content: space-between; /* first/last at edges, rest evenly spaced */
justify-content: space-around; /* equal space around each item */
justify-content: space-evenly; /* equal space between all items and edges */
/* Align along CROSS axis (single line) */
align-items: stretch; /* default ā fill cross axis */
align-items: flex-start; /* align to start of cross axis */
align-items: flex-end; /* align to end */
align-items: center; /* center vertically (if row direction) */
align-items: baseline; /* align text baselines */
/* Align multiple lines (only when flex-wrap: wrap) */
align-content: flex-start;
align-content: center;
align-content: space-between;
}Wrapping
.container {
flex-wrap: nowrap; /* default ā overflow if items don't fit */
flex-wrap: wrap; /* wrap to next line */
flex-wrap: wrap-reverse;
}Gap
.container {
display: flex;
gap: 16px; /* space between all items */
gap: 16px 8px; /* row-gap column-gap */
row-gap: 16px;
column-gap: 8px;
}Flex Item Properties
.item {
/* How much the item grows relative to siblings (default: 0 = don't grow) */
flex-grow: 1; /* take up remaining space */
flex-grow: 2; /* take twice as much remaining space as flex-grow:1 items */
/* How much the item shrinks (default: 1 = can shrink) */
flex-shrink: 0; /* don't shrink ā keep its width */
/* Starting size before grow/shrink */
flex-basis: 200px; /* start at 200px, then grow/shrink */
flex-basis: auto; /* use width/content size */
flex-basis: 0; /* start from nothing, then grow */
/* Shorthand: grow shrink basis */
flex: 1 1 auto; /* default */
flex: 1; /* grow:1, shrink:1, basis:0 ā most common */
flex: 0 0 200px; /* fixed 200px ā don't grow, don't shrink */
/* Override align-items for this specific item */
align-self: center;
/* Change order (default: 0) */
order: -1; /* move to beginning */
order: 1; /* move to end */
}Flexbox Patterns
Centered Content (most common CSS question)
.centered {
display: flex;
justify-content: center;
align-items: center;
/* For full-screen centering: */
min-height: 100vh;
}Navigation Bar
.nav {
display: flex;
align-items: center;
padding: 0 24px;
height: 64px;
}
.nav-logo { margin-right: auto; } /* pushes everything else to the right */
.nav-links {
display: flex;
gap: 8px;
}Equal-Width Cards
.card-row {
display: flex;
gap: 16px;
}
.card {
flex: 1; /* all cards share space equally */
}Sticky Footer
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main { flex: 1; } /* takes all available space, pushes footer down */
footer { /* natural height */ }CSS Grid
Grid divides a container into rows and columns, and you place items into cells.
Defining the Grid
.grid {
display: grid;
/* Define columns */
grid-template-columns: 200px 200px 200px; /* 3 fixed columns */
grid-template-columns: 1fr 1fr 1fr; /* 3 equal columns */
grid-template-columns: 200px 1fr; /* fixed + flexible */
grid-template-columns: repeat(3, 1fr); /* shorthand */
grid-template-columns: repeat(3, minmax(200px, 1fr)); /* min 200px, share rest */
/* Define rows */
grid-template-rows: 80px 1fr 60px; /* fixed header, flexible main, fixed footer */
grid-auto-rows: 200px; /* all implicit rows are 200px */
grid-auto-rows: minmax(150px, auto); /* min 150px, grow with content */
/* Gap */
gap: 16px;
column-gap: 16px;
row-gap: 8px;
}Responsive Grid with auto-fill
/* Auto-fill: as many columns as fit, minimum 250px each */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
/* auto-fit vs auto-fill:
auto-fill: keeps empty columns (items don't stretch to fill row)
auto-fit: collapses empty columns (items stretch to fill row) */Placing Items
/* By line number (1-based, negative counts from end) */
.item {
grid-column: 1 / 3; /* from column line 1 to 3 (spans 2 columns) */
grid-column: 1 / -1; /* full width (from line 1 to last line) */
grid-column: span 2; /* span 2 columns from current position */
grid-row: 1 / 2;
grid-row: span 2; /* span 2 rows */
}Named Template Areas
.layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 64px 1fr 60px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }Grid Patterns
Holy Grail Layout
body {
display: grid;
grid-template-columns: 240px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
min-height: 100vh;
gap: 0;
}
header { grid-area: header; }
.sidebar{ grid-area: sidebar; }
main { grid-area: content; }
aside { grid-area: aside; }
footer { grid-area: footer; }Magazine / Asymmetric Grid
.magazine {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
}
.featured {
grid-column: span 2;
grid-row: span 2;
}Image Gallery with Masonry-like Effect
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
gap: 8px;
}
.gallery-item:nth-child(3n+1) { grid-row: span 2; } /* every 3rd-1 is taller */Flexbox vs Grid ā When to Use Each
| Scenario | Use | |----------|-----| | Navigation bar (horizontal) | Flexbox | | Card row (equal widths) | Either | | Full-page layout (header/sidebar/main/footer) | Grid | | Responsive card grid | Grid (auto-fill) | | Center one element | Flexbox | | Item grows to fill remaining space | Flexbox | | Two-dimensional overlap/spanning | Grid | | Unknown number of items | Flexbox |
They work together ā use Grid for page layout, Flexbox inside components.
Complete Example: App Layout
<!-- HTML -->
<body class="layout">
<header class="header">
<a href="/" class="logo">App</a>
<nav class="nav">
<a href="/dashboard">Dashboard</a>
<a href="/courses">Courses</a>
<a href="/settings">Settings</a>
</nav>
<button class="btn">Sign In</button>
</header>
<aside class="sidebar">...</aside>
<main class="main">
<div class="cards">
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
</div>
</main>
<footer class="footer">Ā© 2026</footer>
</body>/* Page layout ā Grid */
.layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr 48px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; padding: 24px; }
.footer { grid-area: footer; }
/* Header ā Flexbox */
.header {
display: flex;
align-items: center;
padding: 0 24px;
gap: 16px;
border-bottom: 1px solid #e5e7eb;
}
.nav { display: flex; gap: 4px; }
.btn { margin-left: auto; }
/* Cards ā responsive Grid */
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
/* Card ā Flexbox for internal layout */
.card {
display: flex;
flex-direction: column;
border-radius: 12px;
overflow: hidden;
}
.card-content { flex: 1; padding: 16px; } /* grows to push footer down */
.card-footer { padding: 12px 16px; } /* stays at bottom */Key Takeaways
- Flexbox = one-dimensional,
justify-contenton main axis,align-itemson cross axis - Grid = two-dimensional,
grid-template-columns/rowsdefine structure,grid-areaplaces items gapworks in both ā prefer it over margins between itemsrepeat(auto-fill, minmax(250px, 1fr))is the magic responsive grid patternflex: 1makes an item fill remaining space ā use it for the main content area- Named template areas (
grid-template-areas) make complex layouts readable
Enjoyed this article?
Explore the Frontend Engineering learning path for more.
Found this helpful?
Leave a comment
Have a question, correction, or just found this helpful? Leave a note below.