DEV Community

Alex Chen
Alex Chen

Posted on

CSS Flexbox & Grid: The Layout Guide I Wish I Had (2026)

CSS Flexbox & Grid: The Layout Guide I Wish I Had (2026)

CSS layout used to be painful. Flexbox and Grid changed everything. Here's the practical guide that makes them click.

Flexbox: One-Dimensional Layout

/* The core concept: Flexbox manages layout in ONE direction (row or column)
   Think of it as: "I have items, how do I arrange them in a line?" */

.container {
  display: flex;

  /* Main axis direction */
  flex-direction: row;         /* Left to right (default) */
  /* flex-direction: row-reverse; */ /* Right to left */
  /* flex-direction: column;     */ /* Top to bottom */
  /* flex-direction: column-reverse; */ /* Bottom to top */

  /* Wrapping behavior */
  flex-wrap: nowrap;           /* Single line (default) */
  /* flex-wrap: wrap;          */ /* Multi-line when overflow */
  /* flex-wrap: wrap-reverse;  */ /* Wrap upwards */

  /* Shorthand for direction + wrap */
  flex-flow: row wrap;

  /* Main axis alignment (how items spread along the main axis) */
  justify-content: flex-start;  /* Start (default) */
  /* justify-content: flex-end;    */ /* End */
  /* justify-content: center;     */ /* Centered */
  /* justify-content: space-between; */ /* Space between items, no space at edges */
  /* justify-content: space-around;  */ /* Equal space around each item */
  /* justify-content: space-evenly;  */ /* Perfectly equal spacing */

  /* Cross axis alignment (perpendicular to main axis) */
  align-items: stretch;        /* Stretch to fill (default) */
  /* align-items: flex-start;   */ /* Start of cross axis */
  /* align-items: flex-end;     */ /* End of cross axis */
  /* align-items: center;       */ /* Center of cross axis */
  /* align-items: baseline;     */ /* Text baseline alignment */
}

/* Item-level control */
.item {
  /* How much this item can grow relative to others */
  flex-grow: 0;               /* Don't grow (default) */
  /* flex-grow: 1;            */ /* Grow equally with other growable items */
  /* flex-grow: 2;            */ /* Grow 2x more than flex-grow:1 items */

  /* How much this item can shrink */
  flex-shrink: 1;             /* Shrink if needed (default) */
  /* flex-shrink: 0;          */ /* Never shrink (important for icons!) */

  /* Base size before growing/shrinking */
  flex-basis: auto;           /* Auto or specific size */
  /* flex-basis: 200px;       */ /* Start at 200px */

  /* Shorthand: grow | shrink | basis */
  flex: 0 0 auto;             /* Don't grow, don't shrink, auto size (= flex: none) */
  flex: 1 1 auto;             /* Grow, shrink, auto (= flex: auto) */
  flex: 0 1 auto;             /* Default value */

  /* Override container's cross-axis alignment */
  align-self: center;         /* This item centers itself! */

  /* Ordering (visual only, affects DOM order for accessibility) */
  order: 0;                   /* Default */
  order: -1;                  /* Appears BEFORE items with order 0 */
  order: 1;                   /* Appears AFTER items with order 0 */
}
Enter fullscreen mode Exit fullscreen mode

Common Flexbox Patterns

/* === Pattern 1: Perfect Centering === */
.center-all {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;          /* Full viewport height */
}
/* Works for ANY content size — no width/height needed on child! */

/* === Pattern 2: Navbar === */
.navbar {
  display: flex;
  justify-content: space-between; /* Logo left, links right */
  align-items: center;           /* Vertically centered */
  padding: 0 2rem;
}
.nav-links {
  display: flex;
  gap: 2rem;                    /* Space between nav items (modern!) */
  list-style: none;
}

/* === Pattern 3: Card Grid (with Flexbox) */
.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;                     /* Space between cards (replaces margin hacks!) */
}
.card {
  flex: 1 1 300px;              /* Min 300px, grow equally, can shrink */
  border-radius: 8px;
  padding: 1.5rem;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* Result: Responsive grid without media queries!
   Narrow screen → 1 card per row
   Medium → 2 cards
   Wide → 3+ cards depending on space */

/* === Pattern 4: Sticky Footer === */
.page-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
.main-content {
  flex: 1;                      /* Push footer to bottom even with little content */
}
.footer {
  padding: 1rem;
  background: #333;
  color: white;
}

/* === Pattern 5: Media Object (avatar + text) === */
.media-object {
  display: flex;
  align-items: flex-start;      /* Top-align (not stretch!) */
  gap: 1rem;
}
.media-avatar {
  flex-shrink: 0;               /* Avatar never squishes! */
  width: 48px;
  height: 48px;
  border-radius: 50%;
}
.media-body {
  flex: 1;                       /* Text takes remaining space */
  min-width: 0;                  /* Allows text truncation to work */
}
.media-body h3 {
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;      /* Truncate long titles */
}
Enter fullscreen mode Exit fullscreen mode

CSS Grid: Two-Dimensional Layout

/* The core concept: Grid manages layout in TWO directions simultaneously
   Think of it as: "I have a table-like structure, how do I place items?" */

.grid-container {
  display: grid;

  /* Define columns (the superpower!) */
  grid-template-columns: 200px 1fr 200px;        /* Fixed / fluid / Fixed */
  grid-template-columns: repeat(3, 1fr);          /* 3 equal columns */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* Responsive! */
  grid-template-columns: 1fr 2fr 1fr;             /* Ratio-based */
  grid-template-columns: minmax(200px, 400px) 1fr; /* Range constraint */

  /* Define rows */
  grid-template-rows: auto 1fr auto;              /* Header / Content / Footer */
  grid-template-rows: masonry;                    /* Masonry layout (experimental but cool!) */

  /* Gap between cells */
  gap: 1rem;                                     /* Uniform gap (replaces margin!) */
  row-gap: 0.5rem;
  column-gap: 1rem;

  /* Place items within the grid */
  justify-items: start;                           /* Horizontal alignment in cell */
  /* justify-items: end | center | stretch (default) */
  align-items: start;                             /* Vertical alignment in cell */
  /* align-items: end | center | stretch (default) */

  /* Entire grid placement (when grid is smaller than container) */
  justify-content: center;
  align-content: center;
}

/* Item placement (THE real power of Grid!) */
.grid-item {
  /* Span across columns/rows */
  grid-column: 1 / -1;                            /* From first to last column = full width */
  grid-column: 1 / span 2;                        /* Start at col 1, span 2 cols */
  grid-column: 2 / 4;                             /* From col 2 to col 4 */
  grid-row: 1 / 3;                                /* Span rows 1-2 */

  /* Shorthand */
  grid-area: 2 / 1 / 4 / 3;                       /* row-start / col-start / row-end / col-end */

  /* Named areas (readable layout definition!) */
  grid-area: header;
}

/* Named Grid Areas — layout as ASCII art! */
.page-grid {
  display: grid;
  grid-template-columns: 250px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "sidebar main   aside"
    "footer footer footer";
  gap: 1rem;
  min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
Enter fullscreen mode Exit fullscreen mode

When to Use Which?

┌─────────────────────┬──────────────────┬──────────────────┐
│ Scenario            │ Use Flexbox      │ Use Grid          │
├─────────────────────┼──────────────────┼──────────────────┤
│ Navbar              │ ✅ Yes           │ ❌ No             │
│ Center one item     │ ✅ Yes (simpler) │ ✅ Yes            │
│ Card components     │ ✅ Yes           │ ❌ No             │
│ Full page layout    │ ⚠️ Can work      │ ✅ Better         │
│ Dashboard/masonry   │ ❌ Hard          │ ✅ Yes            │
│ Row of equal items  │ ✅ Yes           │ ✅ Yes            │
│ Complex 2D layout   │ ❌ Painful       │ ✅ Made for this  │
│ Unknown item count  │ ✅ Yes (wrap)    │ ⚠️ auto-fill     │
│ Overlapping items   │ ❌ No            │ ✅ Yes            │
└─────────────────────┴──────────────────┴──────────────────┘

Rule of thumb:
→ One dimension (row OR column) → Flexbox
→ Two dimensions (rows AND columns) → Grid
→ They work TOGETHER! Use Grid for page layout, Flexbox inside each component
Enter fullscreen mode Exit fullscreen mode

Modern Layout Shortcuts

/* Gap property (works on BOTH flex and grid!) */
/* Replaces the old margin hack for spacing */
.flex-container { display: flex; gap: 1rem; }
.grid-container { display: grid; gap: 1rem; }

/* Aspect ratio */
.card-image {
  aspect-ratio: 16 / 9;     /* Maintains ratio automatically */
  object-fit: cover;         /* Fills area without distortion */
}
.avatar {
  aspect-ratio: 1 / 1;       /* Always square */
  border-radius: 50%;
}

/* Logical properties (for RTL/internationalization) */
/* Instead of physical directions (left/right/top/bottom): */
.box {
  margin-inline-start: 1rem;   /* = margin-left in LTR, margin-right in RTL */
  margin-block-end: 0.5rem;    /* = margin-bottom */
  padding-inline: 1rem;        /* Horizontal padding (respects text direction) */
  inset-inline-start: 0;       /* = left: 0 in LTR */
  text-align: start;           /* = left in LTR, right in RTL */
}

/* Container Queries (responsive to parent, not viewport!) */
.card-container {
  container-type: inline-size;
}
@container (min-width: 400px) {
  .card { display: grid; grid-template-columns: 150px 1fr; }
}
@container (max-width: 399px) {
  .card { display: block; }
}

/* Subgrid (child grid inherits parent's tracks) */
.grid-parent {
  display: grid;
  grid-template-columns: subgrid; /* Inherits parent's column definitions! */
  grid-row: span 3;
}
Enter fullscreen mode Exit fullscreen mode

Which layout challenge frustrates you most? Flexbox, Grid, or something else entirely?

Follow @armorbreak for more practical developer guides.

Top comments (0)