Key Takeaways
- Flexbox is one-dimensional (row OR column); Grid is two-dimensional (rows AND columns)
- Use Flexbox for navigation bars, button groups, and component-level alignment
- Use Grid for page-level layout and any design that needs rows and columns together
- CSS Grid's fr unit and auto-fill/auto-fit eliminate most media query layout code
- Both can be combined — Grid for page structure, Flexbox inside grid items
CSS layout has a reputation for being frustrating. That reputation is outdated. With Grid and Flexbox fully supported across all modern browsers, positioning elements exactly where you want them is straightforward once you understand what each tool is designed for. This guide gives you the mental model and practical patterns to stop fighting CSS and start using it confidently.
Flexbox Fundamentals: One Direction at a Time
Flexbox works along a single axis — either row (horizontal) or column (vertical). Apply display: flex to the parent container, and children become flex items. The main axis is controlled by justify-content (space distribution along the flex direction) and the cross axis by align-items (alignment perpendicular to flex direction).
Core properties: flex-direction (row/column), justify-content (flex-start, center, space-between, space-around, space-evenly), align-items (stretch, center, flex-start, flex-end), flex-wrap (wrap allows items to wrap to new lines). On items: flex: 1 makes an item take up remaining space. flex: 0 0 200px fixes an item at 200px. align-self overrides align-items for a single item.
Flexbox Patterns You'll Use Every Day
Center anything: display: flex; justify-content: center; align-items: center; on the parent. Works for both horizontal and vertical centering. Navigation bar: display: flex; justify-content: space-between; — logo on left, links on right. Equal-height cards: Put cards in a flex container with align-items: stretch (default) and they match height automatically. Sticky footer: On the page wrapper use display: flex; flex-direction: column; min-height: 100vh; and on the main content use flex: 1; — footer stays at the bottom regardless of content length.
CSS Grid: Two-Dimensional Layout Done Right
Grid lets you define rows and columns simultaneously. display: grid; on the parent. grid-template-columns: repeat(3, 1fr); creates three equal columns using fractional units. grid-template-rows defines row heights. gap sets spacing between cells (replaces the old grid-gap). Children can span multiple cells: grid-column: 1 / 3; (start at line 1, end at line 3 — spanning 2 columns). grid-area with named template areas is powerful for complex layouts.
The fr unit is the key to fluid layouts without media queries. 1fr means one fraction of available space. Three columns defined as 1fr 2fr 1fr give you 25%, 50%, 25% of the width.
Grid Patterns for Real-World Layouts
Responsive card grid without media queries:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}This creates as many columns as fit at 280px wide, expanding to fill space. Cards reflow automatically at any viewport width. Classic page layout:
.page {
display: grid;
grid-template-areas:
'header header'
'sidebar main'
'footer footer';
grid-template-columns: 250px 1fr;
}Each area is named, making the layout visually obvious in code.
Grid vs Flexbox: How to Choose
The mental model: Flexbox is content-driven — items define their size and the container responds. Grid is layout-driven — you define the grid structure and place items into it. Use Flexbox when you have a list of items and want smart distribution (navigation, button rows, card wrapping). Use Grid when you're designing a layout structure that items must conform to (page templates, dashboard panels, complex forms). They work together: Grid handles the page skeleton, Flexbox handles the internals of each section.
Modern CSS That Makes Grid and Flexbox Even Better
Container queries (now widely supported) let components respond to their container's size rather than the viewport — huge for component-based design systems. CSS custom properties (variables) keep spacing and color systems consistent. :has() selector enables parent selection — style a form when it contains an invalid input. Logical properties (margin-inline, padding-block) make internationalized layouts easier. subgrid lets nested grids align to their parent's grid tracks — finally solving the aligned card content problem without JavaScript.
Frequently Asked Questions
- When should I use Grid instead of Flexbox?
- Use Grid when you need to control both rows and columns simultaneously, like a page layout or dashboard. Use Flexbox when aligning items along a single axis, like a navigation bar or a row of cards.
- Can I use CSS Grid and Flexbox together?
- Yes, and you should. A common pattern is Grid for the overall page layout and Flexbox inside each grid section for aligning content within that section.
- Do I need to use Bootstrap or Tailwind for layout?
- No. With native Grid and Flexbox, you can build any layout without a framework. That said, utility-first CSS frameworks like Tailwind can speed up development once you understand the underlying CSS concepts.
- What is the fr unit in CSS Grid?
- fr stands for fraction. It represents a portion of the available space in the grid container. 1fr takes up one equal share, so three columns of 1fr each get one-third of the space each.
Ready to Level Up Your Skills?
Learn CSS, modern JavaScript, React, and full-stack development at our hands-on bootcamp. Join professionals from all backgrounds who've built real projects and changed careers. Next cohorts October 2026 in 5 cities. Only $1,490.
View Bootcamp Details