Senior 4 min · March 05, 2026

CSS Flexbox — Why flex-wrap Defaults Break Mobile Grids

Flexbox defaults to nowrap, causing card overlaps below 480px.

N
Naren · Founder
Plain-English first. Then code. Then the interview question.
About
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • Flexbox is a one-dimensional layout model that distributes space along a main axis.
  • The flex container (display: flex) controls the layout of its direct children.
  • justify-content aligns items on the main axis; align-items on the cross axis.
  • flex: 1 is shorthand for grow/shrink/basis: items share space equally.
  • flex-wrap: wrap + flex-basis creates responsive grids without media queries.
  • Biggest mistake: putting alignment properties on the wrong element — always on the container.
Plain-English First

Imagine you're packing books onto a shelf. Normally you'd place each book one by one, guessing how much space is left. Flexbox is like a magic shelf that automatically figures out how to space, stretch, and align every book for you — even if the books are different sizes. You just tell the shelf the rules ('keep everything centred', 'spread them out evenly') and it handles the maths. That's exactly what Flexbox does for elements on a webpage.

Before Flexbox arrived, building even a simple two-column layout in CSS felt like solving a puzzle with missing pieces. Developers leaned on floats, negative margins, and inline-block hacks just to centre a button on screen — and those solutions broke the moment the screen size changed. Flexbox (short for Flexible Box Layout) was introduced specifically to fix this pain point, and it's now the backbone of nearly every modern web layout you see. It's not a replacement for CSS Grid — it's a complementary tool for distributing space in one direction.

The Two Players: Flex Container and Flex Children

Flexbox always involves a relationship between two things: a parent element called the flex container and the direct children inside it called flex items. Think of it like a food tray (the container) holding individual dishes (the items). When you apply display: flex to the tray, it immediately gains superpowers — it can decide how to line up, space out, and resize every dish automatically.

The key rule beginners miss: Flexbox properties split into two groups. Some properties go on the container (like justify-content and align-items) and some go on the items (like flex-grow and align-self). Mixing them up on the wrong element is the number-one source of confusion.

To activate Flexbox you write exactly one CSS rule on the parent: display: flex. That single line transforms the layout behaviour of every direct child underneath it. Children don't need to do anything — they become flex items the moment their parent becomes a flex container.

flexbox-basics.htmlCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>FlexboxContainer vs Items</title>
  <style>

    /* ── THE FLEX CONTAINER ──────────────────────────────── */
    .recipe-card-row {
      display: flex;           /* This single line activates Flexbox */
      background: #f0f4f8;
      padding: 16px;
      gap: 12px;               /* Adds equal breathing space between items */
    }

    /* ── THE FLEX ITEMS (children of .recipe-card-row) ───── */
    .recipe-card {
      background: #ffffff;
      border: 1px solid #d1d9e0;
      border-radius: 8px;
      padding: 20px;
      /* No width needed — Flexbox handles distribution */
    }

  </style>
</head>
<body>

  <!-- The PARENT is the flex container -->
  <div class="recipe-card-row">

    <!-- Each direct child automatically becomes a flex item -->
    <div class="recipe-card">🍕 Pizza</div>
    <div class="recipe-card">🍣 Sushi</div>
    <div class="recipe-card">🥗 Salad</div>

  </div>

</body>
</html>
Output
Three white cards sit side by side on a light-grey background, each with 12px of gap between them. Without writing a single float or inline-block rule, they line up horizontally because display: flex made the parent a flex container.
Watch Out:
display: flex only affects DIRECT children, not grandchildren. If you nest a div inside a flex item and want THAT to also use Flexbox, you must add display: flex to the inner div separately.
Production Insight
A common production bug: applying display: flex to a child element to 'help it align' and wondering why nothing changes.
The container property must be on the parent — always.
DevTools 'Computed' tab shows if an element is a flex container.
Key Takeaway
display: flex goes on the parent.
Only direct children become flex items.
This is the #1 rule beginners miss and it causes most layout confusion.

Understanding the Two Axes — Main and Cross

Here's the concept that unlocks everything else in Flexbox: there are always two invisible lines running through your flex container. The main axis is the direction your items flow. The cross axis is perpendicular to it — at a right angle.

By default the main axis runs left to right (horizontal), so items line up in a row. You change this with flex-direction. Set it to column and the main axis flips to top-to-bottom, stacking items vertically like a list.

Why does this matter? Because the alignment properties — justify-content and align-items — are defined relative to these axes, not to specific directions. justify-content always controls the main axis. align-items always controls the cross axis. Once this clicks, you'll never forget which property does what.

Think of a road (main axis) and a pavement beside it (cross axis). justify-content moves cars along the road. align-items moves them sideways onto or off the pavement.

flex-axes-demo.htmlCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Flexbox AxesMain vs Cross</title>
  <style>

    .navigation-bar {
      display: flex;
      flex-direction: row;       /* Default: main axis = LEFTRIGHT */
      justify-content: space-between; /* Spread items along the MAIN axis */
      align-items: center;       /* Centre items on the CROSS axis (top↕bottom) */
      background: #1a202c;
      padding: 0 24px;
      height: 60px;
    }

    .nav-logo {
      color: #63b3ed;
      font-weight: bold;
      font-size: 1.2rem;
    }

    .nav-links {
      display: flex;             /* Nested flex container for the link group */
      gap: 20px;
      list-style: none;
      margin: 0;
      padding: 0;
    }

    .nav-links a {
      color: #e2e8f0;
      text-decoration: none;
    }

    /* ── COLUMN DIRECTION EXAMPLE ─────────────────────────── */
    .sidebar-menu {
      display: flex;
      flex-direction: column;    /* Main axis flips: now TOPBOTTOM */
      align-items: flex-start;   /* Items hug the LEFT side of the cross axis */
      gap: 8px;
      background: #2d3748;
      padding: 16px;
      width: 200px;
    }

    .sidebar-menu a {
      color: #e2e8f0;
      text-decoration: none;
      padding: 8px 12px;
      border-radius: 4px;
      width: 100%;
    }

    .sidebar-menu a:hover {
      background: #4a5568;
    }

  </style>
</head>
<body>

  <!-- HORIZONTAL nav (flex-direction: row) -->
  <nav class="navigation-bar">
    <span class="nav-logo">TheCodeForge</span>
    <ul class="nav-links">
      <li><a href="#">Home</a></li>
      <li><a href="#">Articles</a></li>
      <li><a href="#">About</a></li>
    </ul>
  </nav>

  <!-- VERTICAL sidebar (flex-direction: column) -->
  <div class="sidebar-menu">
    <a href="#">Dashboard</a>
    <a href="#">Projects</a>
    <a href="#">Settings</a>
  </div>

</body>
</html>
Output
A dark horizontal navigation bar appears at the top with 'TheCodeForge' on the far left and three links on the far right, perfectly vertically centred. Below it, a dark sidebar shows three links stacked vertically, each taking full width.
Memory Trick:
justify-content → J → think 'Journey along the main axis'. align-items → A → think 'Across the cross axis'. That association alone will save you from Googling which is which for the rest of your career.
Production Insight
When flex-direction is column, justify-content moves items vertically, align-items horizontally — the opposite of what most expect.
I've seen production UIs where a vertical menu's items were centred horizontally instead of vertically because the developer forgot the axis swap.
Always draw the two axes on a whiteboard before writing code.
Key Takeaway
justify-content controls main axis, align-items controls cross axis.
When flex-direction changes, the axes swap — properties do not change.
Draw axes first, write code second.

Alignment Deep Dive — justify-content, align-items, and align-self

Now that you know the axes exist, let's master the properties that control them. These three are responsible for roughly 80% of every layout you'll ever build with Flexbox.

justify-content accepts values like flex-start (pack left), flex-end (pack right), center (middle), space-between (first item at start, last at end, even gaps between), and space-around (equal space on both sides of each item). space-between is the most commonly used in real nav bars and card grids.

align-items works on the cross axis: stretch (default — items fill the container height), center, flex-start, and flex-end.

align-self is the escape hatch. It goes on an individual flex item and overrides align-items just for that one child. It's perfect when one card in a row needs to sit at the top while the rest are centred.

The classic 'centre a div on screen' problem — which tortured CSS developers for years — is solved in two lines with Flexbox.

flexbox-alignment.htmlCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Flexbox Alignment Examples</title>
  <style>

    * { box-sizing: border-box; margin: 0; padding: 0; }

    body {
      font-family: sans-serif;
      padding: 24px;
      background: #f7fafc;
    }

    /* ── EXAMPLE 1: Classic centred hero section ─────────── */
    .hero-section {
      display: flex;
      justify-content: center;   /* Centre content along main axis (horizontal) */
      align-items: center;       /* Centre content along cross axis (vertical) */
      height: 200px;
      background: #2b6cb0;
      border-radius: 8px;
      margin-bottom: 24px;
    }

    .hero-section h1 {
      color: white;
      font-size: 2rem;
    }

    /* ── EXAMPLE 2: space-between for a dashboard stat row ─ */
    .stats-row {
      display: flex;
      justify-content: space-between; /* Even gaps between stat cards */
      align-items: stretch;           /* All cards match the tallest card's height */
      gap: 16px;
      margin-bottom: 24px;
    }

    .stat-card {
      background: white;
      border: 1px solid #e2e8f0;
      border-radius: 8px;
      padding: 20px;
      flex: 1;  /* Each card takes an equal share of available width */
    }

    .stat-card.featured {
      align-self: flex-start; /* THIS card won't stretch — it stays its natural height */
      background: #ebf8ff;
      border-color: #63b3ed;
    }

    .stat-card h2 { font-size: 2rem; color: #2d3748; }
    .stat-card p  { color: #718096; font-size: 0.85rem; }

  </style>
</head>
<body>

  <!-- EXAMPLE 1: Perfect centring in two CSS rules -->
  <div class="hero-section">
    <h1>Welcome to TheCodeForge</h1>
  </div>

  <!-- EXAMPLE 2: Dashboard stats with align-self override -->
  <div class="stats-row">

    <div class="stat-card">
      <h2>1,284</h2>
      <p>Articles Published</p>
      <p>This is a longer description that makes this card taller than others.</p>
    </div>

    <!-- This card uses align-self to opt OUT of stretching -->
    <div class="stat-card featured">
      <h2>98%</h2>
      <p>Reader Satisfaction</p>
    </div>

    <div class="stat-card">
      <h2>42k</h2>
      <p>Monthly Readers</p>
    </div>

  </div>

</body>
</html>
Output
A blue banner with 'Welcome to TheCodeForge' perfectly centred both horizontally and vertically. Below it, three stat cards sit in a row: the first and third stretch to match the tallest card's height, while the 'featured' card (highlighted in light blue) stays only as tall as its own content because of align-self: flex-start.
Interview Gold:
If an interviewer asks 'How do you centre a div both horizontally and vertically?', the Flexbox answer is: display: flex + justify-content: center + align-items: center on the PARENT. This is the most asked CSS interview question and Flexbox makes it embarrassingly simple.
Production Insight
In production, I've seen justify-content: space-between used on a container with only one item — it gets pinned to one side, which is confusing.
Always check the number of items when using space-between.
align-self is heavily used in component libraries to handle exceptions like 'the last card has less content'.
Key Takeaway
justify-content and align-items go on the container.
align-self goes on the item — overrides align-items for that one child.
The centring trick is the #1 Flexbox interview answer.

flex-grow, flex-shrink, and flex-basis — Making Items Flexible

This is where 'Flexible' in Flexbox actually earns its name. These three properties control how each individual item behaves when there's extra space or not enough space.

flex-basis sets the starting size of an item before any space is distributed — think of it as the item's 'wish' for how big it wants to be. flex-grow says 'if there's leftover space, I want this share of it'. A value of 1 means 'take a fair share'. A value of 2 means 'take twice as much as items with 1'. flex-shrink works in reverse — when space runs out, how much should this item shrink? The default is 1, meaning all items shrink equally.

The shorthand flex: 1 is the most common thing you'll write in real projects. It expands to flex-grow: 1, flex-shrink: 1, flex-basis: 0%, meaning 'share all available space equally among siblings'.

flex-wrap is also critical here. By default, Flexbox squeezes all items into one line. Set flex-wrap: wrap and items spill onto the next row when they run out of room — essential for responsive card grids.

flex-grow-shrink-wrap.htmlCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>flex-grow, flex-shrink, flex-wrap</title>
  <style>

    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: sans-serif; padding: 24px; background: #f7fafc; }

    /* ── EXAMPLE 1: Unequal columns (sidebar + main content) ── */
    .page-layout {
      display: flex;
      gap: 16px;
      margin-bottom: 32px;
      height: 120px;
    }

    .page-sidebar {
      flex: 0 0 220px;   /* flex-grow:0, flex-shrink:0, flex-basis:220px */
                         /* NEVER grow, NEVER shrink — always exactly 220px */
      background: #2d3748;
      color: white;
      padding: 16px;
      border-radius: 8px;
    }

    .page-main-content {
      flex: 1;           /* Shorthand: grow to fill ALL remaining space */
      background: white;
      border: 1px solid #e2e8f0;
      padding: 16px;
      border-radius: 8px;
    }

    /* ── EXAMPLE 2: Responsive card grid with flex-wrap ─────── */
    .article-grid {
      display: flex;
      flex-wrap: wrap;    /* Items wrap to the next row when space runs out */
      gap: 16px;
    }

    .article-card {
      flex: 1 1 280px;   /* Grow and shrink, but never go below 280px wide */
                         /* This creates a naturally responsive grid */
      background: white;
      border: 1px solid #e2e8f0;
      border-radius: 8px;
      padding: 20px;
    }

    .article-card h3 { color: #2d3748; margin-bottom: 8px; }
    .article-card p  { color: #718096; font-size: 0.9rem; }

  </style>
</head>
<body>

  <!-- LAYOUT: Fixed sidebar + Fluid main area -->
  <div class="page-layout">
    <aside class="page-sidebar">Sidebar (always 220px)</aside>
    <main class="page-main-content">Main content (takes all remaining space)</main>
  </div>

  <!-- GRID: Cards wrap to new rows on small screens -->
  <div class="article-grid">
    <div class="article-card">
      <h3>Getting Started with CSS</h3>
      <p>Learn the fundamentals of styling web pages from zero.</p>
    </div>
    <div class="article-card">
      <h3>JavaScript Promises Explained</h3>
      <p>Understand async code without losing your mind.</p>
    </div>
    <div class="article-card">
      <h3>React Hooks Deep Dive</h3>
      <p>Master useState, useEffect, and custom hooks.</p>
    </div>
    <div class="article-card">
      <h3>Node.js for Beginners</h3>
      <p>Build your first server-side app step by step.</n></p>
    </div>
  </div>

</body>
</html>
Output
Top section: A dark 220px-wide sidebar sits fixed to the left; the white main content area expands to fill all remaining width regardless of screen size. Bottom section: Four article cards arranged in a row on wide screens. On narrower screens, cards automatically drop to two per row, then one per row, because flex-wrap: wrap lets them reflow naturally.
Pro Tip:
The pattern flex: 1 1 280px on cards combined with flex-wrap: wrap gives you a fully responsive grid with ZERO media queries. This is how modern CSS replaces entire Bootstrap grid systems with just a few lines.
Production Insight
Flex-shrink is often forgotten. On a very narrow screen, items with flex: 1 1 auto can shrink to 0 width — making them invisible.
Always provide a min-width or use flex-basis instead of auto for critical items.
The responsive grid pattern with flex-wrap is used by almost every production design system.
Key Takeaway
flex: 1 = flex-grow:1, flex-shrink:1, flex-basis:0%.
flex: 0 0 200px = fixed width sidebar.
flex-wrap: wrap + flex-basis = responsive grid without media queries.

Advanced Techniques: order, align-content, and gap

Once you've mastered the core properties, three advanced features give you finer control: order, align-content, and the gap shorthand.

order lets you reorder flex items visually without changing the HTML. All items have order: 0 by default. Set order: -1 to move an item to the front, or order: 1 to move it to the end. Use it for accessibility-friendly source order reordering — but don't rely on it for logical tab order (keyboard users follow DOM order, not visual order).

align-content controls spacing between rows of wrapped items. It only works when flex-wrap: wrap is active AND items have wrapped onto multiple lines. Values: flex-start, flex-end, center, space-between, space-around, stretch. If your items are all on one line, align-content has no effect.

gap is a shorthand for row-gap and column-gap (or gap in both directions). It adds fixed spacing between flex items, replacing the old hack of using margins on items. gap is supported in all modern browsers and is the cleaner solution.

flexbox-advanced.htmlCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Flexbox Advanced — order, align-content, gap</title>
  <style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: sans-serif; padding: 24px; background: #f7fafc; }

    /* ── ORDER EXAMPLE: Reorder cards without changing HTML ──── */
    .order-demo {
      display: flex;
      gap: 12px;
      margin-bottom: 32px;
    }

    .order-demo .card {
      flex: 1;
      padding: 20px;
      background: white;
      border: 1px solid #e2e8f0;
      border-radius: 8px;
    }

    .order-demo .card:nth-child(1) { order: 2; }
    .order-demo .card:nth-child(2) { order: 3; }
    .order-demo .card:nth-child(3) { order: 1; }

    /* ── ALIGN-CONTENT EXAMPLE ──────────────────────────────── */
    .align-content-demo {
      display: flex;
      flex-wrap: wrap;
      align-content: space-around; /* Space between rows of wrapped items */
      height: 300px;
      background: #edf2f7;
      gap: 8px;
      padding: 8px;
      margin-bottom: 32px;
    }

    .align-content-demo .item {
      flex: 0 0 150px;
      height: 60px;
      background: #63b3ed;
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;
    }

    /* ── GAP SHORTHAND ──────────────────────────────────────── */
    .gap-demo {
      display: flex;
      flex-wrap: wrap;
      gap: 24px 16px; /* row-gap:24px, column-gap:16px */
      background: #fefcbf;
      padding: 16px;
    }

    .gap-demo .item {
      flex: 1 1 200px;
      background: white;
      padding: 16px;
      border-radius: 4px;
    }
  </style>
</head>
<body>

  <!-- ORDER: HTML order is 1,2,3 but visual order is 3,1,2 -->
  <div class="order-demo">
    <div class="card">Card 1 (order:2)</div>
    <div class="card">Card 2 (order:3)</div>
    <div class="card">Card 3 (order:1)</div>
  </div>
  <p style="margin-bottom: 32px;">Visual order: Card 3, Card 1, Card 2</p>

  <!-- ALIGN-CONTENT: Rows spaced evenly in container -->
  <div class="align-content-demo">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
    <div class="item">Item 4</div>
    <div class="item">Item 5</div>
    <div class="item">Item 6</div>
  </div>
  <p style="margin-bottom: 32px;">Items wrap onto two rows; space-around distributes rows vertically.</p>

  <!-- GAP: separate row and column gaps -->
  <div class="gap-demo">
    <div class="item">Item A</div>
    <div class="item">Item B</div>
    <div class="item">Item C</div>
    <div class="item">Item D</div>
  </div>
  <p>24px vertical gap, 16px horizontal gap between items.</p>
</body>
</html>
Output
First section: Three cards displayed in visual order Card 3, Card 1, Card 2 despite HTML order being 1,2,3. Second section: Blue boxes wrapped onto two rows, vertically spaced with space-around within the container. Third section: Four cards with different gap sizes between rows and columns.
Accessibility Gotcha:
Changing order with CSS does NOT change the keyboard tab order or screen reader reading order. Use it only for visual reordering — never for logical content flow. If the sequence matters for navigation, modify the DOM or use tabindex carefully.
Production Insight
I've seen teams use order to reorder items for responsive breakpoints — then discover keyboard users get lost because tab order doesn't match.
Also, align-content does nothing if all items are on one line. Many developers add it and wonder why it's ignored.
Gap replaces margin hacks; it's 2026 — use gap everywhere.
Key Takeaway
order changes visual order only — not tab order.
align-content works only when flex-wrap wraps onto multiple rows.
Shorthand gap: row-gap column-gap — clean, modern spacing.
● Production incidentPOST-MORTEMseverity: high

The Card Grid That Overlapped on Mobile

Symptom
Product cards overlapped horizontally; content was unreadable below 480px width.
Assumption
The team assumed Flexbox would automatically wrap items when container width decreased.
Root cause
The card container had no flex-wrap property (default nowrap), and each card had flex-shrink: 0 to prevent squishing. Flexbox tried to keep all cards on one line, causing horizontal overflow.
Fix
Added flex-wrap: wrap to the container and removed flex-shrink: 0 from cards. Used flex: 1 1 250px on each card to allow wrapping at a sensible width.
Key lesson
  • Never assume Flexbox wraps by default — always set flex-wrap: wrap for row-based grids.
  • Avoid flex-shrink: 0 on items unless you absolutely need fixed widths.
  • Test responsive layouts at the smallest breakpoint first; overflow is silent.
Production debug guideA step-by-step guide to diagnosing misalignment, overflow, and missing responsiveness4 entries
Symptom · 01
Items are not aligning as expected (e.g., justify-content: center does nothing)
Fix
Check the parent has display: flex. Open DevTools, inspect the container, confirm it's a flex container in the computed styles. If it's not a container, the property is silently ignored.
Symptom · 02
Items overflow horizontally or are clipped
Fix
Check for missing flex-wrap. If flex-wrap is nowrap (default), items will shrink or overflow. Add flex-wrap: wrap and ensure items have a min-width or flex-basis.
Symptom · 03
Items appear stacked vertically instead of in a row
Fix
Default flex-direction is row. If items stack, check for flex-direction: column in parent styles. Could be from a media query or inherited from a parent flex container.
Symptom · 04
One item is taller/shorter than others in a row
Fix
align-items defaults to stretch, making all items same height. Check if that item has align-self set, or if its content is block-level causing extra height. Use align-items: flex-start to disable stretch.
★ Flexbox Quick Debug SheetWhen your flex layout breaks, run these checks in order.
Alignment property ignored
Immediate action
Verify parent has display: flex
Commands
Inspect parent element in DevTools → Computed → 'display'
Ensure no flex-direction: column if you expect horizontal alignment
Fix now
Add display: flex to the parent (if missing)
Items don't wrap on small screens+
Immediate action
Check if flex-wrap is set to wrap
Commands
Inspect container → Styles → scroll to 'flex-wrap'
Add flex-wrap: wrap and a flex-basis or min-width on items
Fix now
Add flex-wrap: wrap to container
One item refuses to match height of siblings+
Immediate action
Look for align-self on that item
Commands
Inspect that item → Styles → align-self
Remove align-self or set it to stretch
Fix now
Remove align-self from that item
Content overflows container (scrollbar appears)+
Immediate action
Check flex-shrink values and container overflow
Commands
Inspect container → check overflow property (default visible)
Set overflow: hidden temporarily to see actual child sizes
Fix now
Add flex-wrap: wrap and remove overflow: hidden
Flexbox vs CSS Grid
Feature / AspectCSS FlexboxCSS Grid
Best used forSingle-axis layouts (row OR column)Two-axis layouts (rows AND columns simultaneously)
Direction controlflex-direction: row | columnRows and columns defined together with grid-template
Item alignmentjustify-content + align-itemsjustify-items + align-items (same concept, grid context)
Content-driven sizingYes — items size to their content naturallyPossible but layout is more structure-driven
Responsive without media queriesYes — flex-wrap + flex-basis handles most casesYes — with repeat(auto-fill, minmax()) pattern
Typical use casesNavbars, button groups, card rows, centringPage layouts, photo galleries, dashboard grids
Browser supportAll modern browsers + IE11 (with prefixes)All modern browsers, IE11 partial support only
Learning curveLower — fewer properties to learn firstHigher — requires understanding both axes at once from the start

Key takeaways

1
display
flex goes on the PARENT container — that one rule makes all direct children into flex items automatically.
2
justify-content controls the MAIN axis, align-items controls the CROSS axis
and those axes SWAP when flex-direction changes to column.
3
flex
1 is the most powerful shorthand you'll write — it means 'grow and shrink equally with siblings', producing fluid layouts without hardcoded widths.
4
flex-wrap
wrap combined with flex: 1 1 [min-width] on children creates a fully responsive card grid with zero media queries — this pattern replaces entire grid frameworks.
5
order changes visual order only; tab and screen reader order remain tied to DOM order.
6
Use gap instead of margin hacks for spacing between flex items.

Common mistakes to avoid

3 patterns
×

Putting justify-content on the flex item instead of the container

Symptom
When you apply justify-content: center to a flex item, nothing happens. The property is silently ignored because it only works on flex containers.
Fix
Always put justify-content and align-items on the parent element that has display: flex. Confirm the parent is indeed a flex container using DevTools.
×

Forgetting that flex-direction: column swaps the axes

Symptom
You set justify-content: center expecting to centre items vertically, but they centre horizontally instead.
Fix
Remember that when flex-direction: column, the main axis becomes vertical. justify-content controls vertical alignment in that case. Draw the axes on paper before debugging.
×

Using flex without flex-wrap on card grids

Symptom
On small screens, cards squish into a single overflowing row instead of wrapping to the next line.
Fix
Add flex-wrap: wrap to the container. Provide a min-width or flex-basis on items (e.g., flex: 1 1 250px) so they wrap at a reasonable size.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What's the difference between justify-content and align-items in Flexbox...
Q02SENIOR
How would you build a navigation bar where the logo is on the left and t...
Q03SENIOR
What does flex: 1 actually expand to, and why would you use flex: 0 0 20...
Q01 of 03JUNIOR

What's the difference between justify-content and align-items in Flexbox, and what happens to each when you change flex-direction to column?

ANSWER
justify-content controls the main axis; align-items controls the cross axis. By default, main axis is horizontal (row), so justify-content moves items left/right and align-items moves up/down. When you set flex-direction: column, the main axis becomes vertical — justify-content now controls up/down, and align-items controls left/right. The properties don't change meaning; the axes flip.
FAQ · 3 QUESTIONS

Frequently Asked Questions

01
When should I use Flexbox instead of CSS Grid?
02
Why isn't my justify-content: center working?
03
What's the difference between align-items and align-content?
🔥

That's HTML & CSS. Mark it forged?

4 min read · try the examples if you haven't

Previous
CSS Basics and Box Model
3 / 16 · HTML & CSS
Next
CSS Grid Complete Guide