devto 2026-08-18 원문 보기 ↗
I was building a dashboard for a side‑project last month. The design called for a header, a sidebar, a main content area, and a footer that needed to stay glued to the bottom no matter how short the page was. I reached for Flexbox because, honestly, it’s the go‑to for most layout tasks. I whipped up a column flex container, stuck the sidebar and main area inside, and set flex: 1 on the main block so it would take up the remaining space.
Everything looked fine… until I resized the browser. The sidebar would collapse weirdly when the viewport got narrow, and the footer would jump up whenever the main content was shorter than the viewport height. I spent an embarrassing amount of time fiddling with min-height, flex-basis, and media queries, only to end up with a brittle mess that felt like I was trying to herd cats.
That’s when I realized I was using the wrong tool for the job. Flexbox is fantastic for one‑dimensional layouts—think a row of buttons or a column of cards—but when you need to control both rows and columns at the same time, you’re essentially asking a screwdriver to hammer a nail. The dragon I was slaying wasn’t a bug; it was a mismatch between the problem and the solution.
CSS Grid entered the scene like a wise old mentor who finally hands you the map to the treasure. Grid lets you define a two‑dimensional grid explicitly: you set up rows and columns, place items wherever you want, and the browser takes care of the rest. It’s not a replacement for Flexbox; it’s a complementary power‑up.
The “aha!” moment came when I sketched out the layout on paper:
+-------------------+
| Header |
+-------+-----------+
| Sidebar| Main |
+-------+-----------+
| Footer |
+-------------------+
With Grid, I could declare that structure in a few lines, tell the browser that the header and footer each span the full width, and let the sidebar and main area share the remaining space. No more fighting with flex-grow or guessing at percentages.
Here’s the core idea:
It’s like choosing between a Swiss army knife (Flexbox) and a blueprint‑driven construction set (Grid). Both are invaluable; you just pick the right one for the task at hand.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dashboard – Flexbox Fight</title>
<style>
body {
margin: 0;
font-family: system-ui, sans-serif;
display: flex;
flex-direction: column;
min-height: 100vh;
}
header, footer {
background: #4a90e2;
color: white;
padding: 1rem;
}
.container {
flex: 1;
display: flex; /* row layout for sidebar + main */
}
aside {
background: #ffe066;
width: 250px;
padding: 1rem;
flex-shrink: 0; /* don’t let it shrink below 250px */
}
main {
background: #f5f5f5;
flex: 1;
padding: 1rem;
overflow: auto;
}
</style>
</head>
<body>
<header>Header</header>
<div class="container">
<aside>Sidebar</aside>
<main>Main content</main>
</div>
<footer>Footer</footer>
</body>
</html>
What went wrong?
.container is flex: 1. If the main content is short, the container still pushes the footer down, but the sidebar’s fixed width can cause overflow on narrow screens.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dashboard – Grid Grace</title>
<style>
body {
margin: 0;
font-family: system-ui, sans-serif;
display: grid;
/* Define rows: header (auto), main body (1fr), footer (auto) */
grid-template-rows: auto 1fr auto;
/* Define columns: sidebar (250px), main (1fr) */
grid-template-columns: 250px 1fr;
min-height: 100vh;
}
header {
grid-column: 1 / -1; /* span all columns */
background: #4a90e2;
color: white;
padding: 1rem;
}
aside {
background: #ffe066;
padding: 1rem;
}
main {
background: #f5f5f5;
padding: 1rem;
overflow: auto;
}
footer {
grid-column: 1 / -1; /* span all columns */
background: #4a90e2;
color: white;
padding: 1rem;
}
</style>
</head>
<body>
<header>Header</header>
<aside>Sidebar</aside>
<main>Main content</main>
<footer>Footer</footer>
</body>
</html>
Why this feels like a win:
grid-template-rows / grid-template-columns). Changing the layout is as easy as editing those two lines.
grid-column: 1 / -1. No need for extra wrapper divs or flex hacks.
flex-shrink juggling.
@media (max-width: 600px) {
body {
grid-template-rows: auto auto 1fr auto; /* header, sidebar, main, footer */
grid-template-columns: 1fr;
}
aside { grid-row: 2; }
main { grid-row: 3; }
}
Now the sidebar stacks above the main area, and the flow stays clean.
| Trap | What Happens | How to Dodge It |
|---|---|---|
| Using Grid for simple one‑dimensional layouts | Over‑engineering; extra lines of code for nothing. | Reach for Flexbox when you only need a row or a column. |
Forgetting to set min-height: 100vh on the grid container |
Footer clings to the bottom of the content, not the viewport. | Always give the grid container a height that matches the viewport when you need a sticky footer. |
Mixing up grid-template-areas with explicit line numbers |
Confusion when you later rename areas. | Choose one naming strategy and stick with it per component. |
| Assuming Grid replaces Flexbox everywhere | You’ll end up with rigid layouts that don’t adapt to content size as fluidly as Flexbox can. | Use them together: a Grid container can hold Flexbox items inside its cells for internal alignment. |
With Grid in your toolbox, you can craft complex page skeletons—magazine layouts, dashboards, asymmetric galleries—without the mental gymnastics that Flexbox sometimes demands. It lets you think in terms of sections and regions, not just “push this item to the side.”
The real win is confidence. When you open a new design file, you can glance at the sketch and immediately map it to grid-template-rows and grid-template-columns. You spend less time wrestling with CSS and more time building the actual features that delight users.
And the best part? Grid and Flexbox are friends, not foes. Nest a Flexbox nav bar inside a Grid header, or put a Grid card deck inside a Flexbox‑centered section. The web becomes a playground where you pick the right swing for each moment.
I challenge you to take a layout you’ve built with Flexbox lately—maybe a product card list or a simple admin sidebar—and rebuild it using Grid. Notice how many lines of code you can drop, how the responsive breakpoints shrink, and how the overall structure feels more declarative.
Give it a shot, tweet your before/after, and tag me. I can’t wait to see the grids you conquer! 🚀