CSS Grid and Flexbox: Mastering Modern Layouts
CSS Grid and Flexbox: Mastering Modern Layouts
CSS Grid and Flexbox are the two most powerful layout tools in modern CSS. Understanding when and how to use each will transform your web development workflow.
Flexbox: One-Dimensional Layouts
Flexbox is designed for one-dimensional layouts - either a row or a column.
Basic Flexbox
.container {
display: flex;
gap: 1rem;
}
/* Direction */
.container {
flex-direction: row; /* default */
flex-direction: column;
flex-direction: row-reverse;
flex-direction: column-reverse;
}
/* Alignment on main axis */
.container {
justify-content: flex-start; /* default */
justify-content: flex-end;
justify-content: center;
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;
}
/* Alignment on cross axis */
.container {
align-items: stretch; /* default */
align-items: flex-start;
align-items: flex-end;
align-items: center;
align-items: baseline;
}
Flex Items
.item {
flex-grow: 0; /* default - don't grow */
flex-grow: 1; /* grow to fill space */
flex-shrink: 1; /* default - can shrink */
flex-shrink: 0; /* don't shrink */
flex-basis: auto; /* default */
flex-basis: 200px; /* initial size */
/* Shorthand */
flex: 1; /* flex-grow: 1; flex-shrink: 1; flex-basis: 0; */
flex: 0 0 200px; /* don't grow, don't shrink, 200px */
}
Common Flexbox Patterns
/* Center anything */
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* Equal width cards */
.cards {
display: flex;
gap: 1rem;
}
.card {
flex: 1; /* All cards equal width */
}
/* Sticky footer */
.body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.main {
flex: 1; /* Fills remaining space */
}
/* Responsive navigation */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
CSS Grid: Two-Dimensional Layouts
Grid is designed for two-dimensional layouts - rows and columns simultaneously.
Basic Grid
.container {
display: grid;
gap: 1rem;
/* Fixed columns */
grid-template-columns: 200px 200px 200px;
/* Flexible columns */
grid-template-columns: 1fr 2fr 1fr;
/* Repeat */
grid-template-columns: repeat(3, 1fr);
/* Auto-fit responsive grid */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
/* Rows */
grid-template-rows: auto 1fr auto;
}
Grid Areas
.layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
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 Placement
.item {
grid-column: 1 / 3; /* Span columns 1 to 3 */
grid-column: span 2; /* Span 2 columns */
grid-row: 1 / 2;
/* Named lines */
grid-column: content-start / content-end;
}
/* Or use start/span syntax */
.item {
grid-column: 1 / span 2;
}
Common Grid Patterns
/* Holy Grail Layout */
.layout {
display: grid;
grid-template:
"header header header" auto
"nav main aside" 1fr
"footer footer footer" auto
/ 200px 1fr 200px;
min-height: 100vh;
}
/* Photo Gallery */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
/* Card Grid with Spanning */
.cards {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
}
.featured {
grid-column: span 2;
grid-row: span 2;
}
When to Use Which?
Use Flexbox When:
- Layout is one-dimensional (row OR column)
- Content should determine sizing
- Aligning items within a container
- Navigation bars, card contents, form layouts
/* Perfect for nav */
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
/* Perfect for card internals */
.card {
display: flex;
flex-direction: column;
}
.card-footer {
margin-top: auto; /* Push to bottom */
}
Use Grid When:
- Layout is two-dimensional (rows AND columns)
- You need precise control over placement
- Building page layouts
- Complex component layouts
/* Perfect for page layout */
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
}
/* Perfect for complex components */
.dashboard {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, auto);
}
Combining Grid and Flexbox
The real power comes from combining both:
/* Grid for page layout, Flexbox for components */
.page {
display: grid;
grid-template-columns: 1fr min(800px, 100%) 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
grid-column: 1 / -1;
}
.main {
grid-column: 2;
}
/* Card grid with flexed internals */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.card {
display: flex;
flex-direction: column;
}
.card-content {
flex: 1;
}
Responsive Design
Flexbox Responsive
.container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.item {
flex: 1 1 300px; /* Grow, shrink, base 300px */
max-width: 100%;
}
/* Or use media queries */
@media (max-width: 768px) {
.container {
flex-direction: column;
}
}
Grid Responsive
/* Auto-responsive grid */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
gap: 1rem;
}
/* Media query approach */
.grid {
display: grid;
gap: 1rem;
}
@media (min-width: 640px) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
.grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1280px) {
.grid { grid-template-columns: repeat(4, 1fr); }
}
Gap Property
Both support the gap property:
.flex-container {
display: flex;
gap: 1rem; /* Between all items */
row-gap: 0.5rem; /* Between rows */
column-gap: 1rem; /* Between columns */
}
.grid-container {
display: grid;
gap: 1rem 2rem; /* row-gap column-gap */
}
Practical Examples
Navigation
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.nav-links {
display: flex;
gap: 2rem;
}
@media (max-width: 768px) {
.nav {
flex-direction: column;
gap: 1rem;
}
}
Dashboard Layout
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr;
min-height: 100vh;
}
.sidebar {
grid-row: 1 / -1;
background: #f5f5f5;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.main {
padding: 1rem;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1rem;
}
Conclusion
- Flexbox: One-dimensional, content-first, alignment
- Grid: Two-dimensional, layout-first, precise placement
- Combine: Grid for page layouts, Flexbox for components
Master both, and you'll have complete control over any layout challenge!