Most developers learn just enough Flexbox to center a div and just enough Grid to feel confused. Then they reach for a CSS framework. But Flexbox and Grid together handle every layout you will ever need — sidebars, card grids, holy grail layouts, responsive navigation — without a single framework dependency.

The One Rule: Grid for Layout, Flexbox for Alignment

  • CSS Grid: Two-dimensional (rows AND columns). Use for page-level layout and component structure.
  • Flexbox: One-dimensional (row OR column). Use for aligning items within a container.

They are not competitors. Use Grid for the overall page structure, then Flexbox inside each Grid cell for alignment.

Flexbox Essentials

/* The container controls how children behave */
.flex-container {
  display: flex;
  flex-direction: row;        /* row | column | row-reverse | column-reverse */
  justify-content: center;    /* Main axis: start | center | end | space-between | space-around | space-evenly */
  align-items: center;        /* Cross axis: start | center | end | stretch | baseline */
  gap: 1rem;                  /* Spacing between items */
  flex-wrap: wrap;            /* Allow wrapping to next line */
}

/* Children control their own sizing */
.flex-item {
  flex: 1;                    /* Grow to fill available space */
  /* flex: 1 is shorthand for: flex-grow: 1; flex-shrink: 1; flex-basis: 0; */
}

Common Flexbox Patterns

/* 1. Center anything (the classic) */
.center-everything {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* 2. Navigation bar */
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}
.navbar-links {
  display: flex;
  gap: 1.5rem;
}

/* 3. Card footer pushed to bottom */
.card {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.card-body {
  flex: 1;   /* Takes all available space, pushes footer down */
}
.card-footer {
  margin-top: auto;  /* Alternative: push to bottom */
}

/* 4. Input with button */
.search-bar {
  display: flex;
}
.search-bar input {
  flex: 1;           /* Input takes remaining space */
}
.search-bar button {
  flex-shrink: 0;    /* Button never shrinks */
}

CSS Grid Essentials

/* Define rows and columns */
.grid-container {
  display: grid;
  grid-template-columns: 250px 1fr 250px;  /* sidebar | main | sidebar */
  grid-template-rows: auto 1fr auto;        /* header | content | footer */
  gap: 1rem;
  min-height: 100vh;
}

/* Place items by name (much clearer than line numbers) */
.grid-container {
  grid-template-areas:
    "header  header  header"
    "left    main    right"
    "footer  footer  footer";
}

.header { grid-area: header; }
.sidebar-left { grid-area: left; }
.main-content { grid-area: main; }
.sidebar-right { grid-area: right; }
.footer { grid-area: footer; }

Responsive Grid Without Media Queries

/* Auto-fit: cards that wrap and fill available space */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}
/* On wide screen: 3-4 columns
   On tablet: 2 columns
   On mobile: 1 column
   ZERO media queries! */

/* Auto-fill vs auto-fit:
   auto-fill: creates empty columns even with few items
   auto-fit: collapses empty columns so items stretch */

/* Fixed minimum, flexible maximum */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
}

Common Grid Patterns

/* 1. Holy grail layout */
.page {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
  min-height: 100vh;
}

/* Make it responsive with one media query */
@media (max-width: 768px) {
  .page {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "nav"
      "main"
      "aside"
      "footer";
  }
}

/* 2. Dashboard layout */
.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto;
  gap: 1rem;
}
.widget-large {
  grid-column: span 2;
  grid-row: span 2;
}
.widget-wide {
  grid-column: span 2;
}

/* 3. Masonry-like layout (with Grid) */
.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 10px;  /* Small base row */
  gap: 1rem;
}
.masonry-item-small { grid-row: span 20; }
.masonry-item-medium { grid-row: span 30; }
.masonry-item-large { grid-row: span 40; }

Grid + Flexbox Together

/* Grid for page layout, Flexbox inside each cell */
.app {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas:
    "sidebar header"
    "sidebar main";
  height: 100vh;
}

/* Header uses Flexbox for alignment */
.header {
  grid-area: header;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 2rem;
}

/* Main content uses Grid for card layout */
.main {
  grid-area: main;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
  padding: 2rem;
  overflow-y: auto;
}

/* Each card uses Flexbox for internal layout */
.card {
  display: flex;
  flex-direction: column;
  border-radius: 8px;
  overflow: hidden;
}
.card-content { flex: 1; padding: 1rem; }
.card-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 1rem;
}

Subgrid: Aligning Nested Grids

/* Parent grid */
.card-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

/* Child uses parent's grid lines for consistent alignment */
.card {
  display: grid;
  grid-template-rows: subgrid;   /* Inherit parent's row tracks */
  grid-row: span 3;              /* Card occupies 3 rows */
}
/* Now all card titles, bodies, and footers align across cards
   even when content lengths differ */

Decision Guide

Use Case Use Why
Page layout (header/sidebar/main) Grid Two-dimensional, named areas
Card grid Grid auto-fit/minmax for responsive wrapping
Navigation links Flexbox One row of items with spacing
Center content Flexbox justify-content + align-items
Form layout Grid Label/input pairs in columns
Toolbar buttons Flexbox Single row, variable spacing
Dashboard widgets Grid Spanning rows/columns
Sticky footer Flexbox or Grid Both work well

Key Takeaways

  • Grid for two dimensions, Flexbox for one — this rule alone solves 90% of layout decisions
  • Use grid-template-areas for readable, maintainable page layouts
  • repeat(auto-fit, minmax(300px, 1fr)) creates responsive grids without media queries
  • Combine Grid and Flexbox: Grid for structure, Flexbox for alignment within cells
  • flex: 1 on a child makes it grow to fill available space — perfect for push-to-bottom patterns
  • gap works in both Grid and Flexbox — no more margin hacks
  • Subgrid aligns nested content across sibling elements — use it for card lists
  • You probably do not need a CSS framework — Grid + Flexbox + custom properties handle everything

The secret to CSS layout is not memorizing properties — it is understanding the mental model. Grid thinks in tracks (rows and columns). Flexbox thinks in flow (main axis and cross axis). Once you internalize these two mental models, layout stops being a guessing game and becomes intentional design.