Home Module 05 Flex Container Properties

1. Introduction

In the previous lesson you learned what Flexbox is and how to activate it. In this lesson we go deep on the six most important flex container properties — the ones you write on the parent element to control how all the children are laid out.

These six properties are:

  1. flex-direction — which way items flow
  2. justify-content — distribute space along the main axis
  3. align-items — align items along the cross axis
  4. flex-wrap — whether items wrap to new lines
  5. align-content — align multiple lines along the cross axis
  6. gap — space between items

These properties only work on the flex container. They control all direct children.

2. Theory

flex-direction

Sets the main axis direction.

ValueItems flow
row (default)Left to right
row-reverseRight to left
columnTop to bottom
column-reverseBottom to top
.container {
  display: flex;
  flex-direction: column; /* stack vertically */
}

justify-content

Distributes space along the main axis.

ValueEffect
flex-start (default)Items packed at start
flex-endItems packed at end
centerItems centred in container
space-betweenFirst item at start, last at end, equal gaps between
space-aroundEqual space around each item (half at edges)
space-evenlyEqual space between items AND at edges
.navbar { justify-content: space-between; } /* logo left, links right */
.btn-group { justify-content: center; }      /* buttons centred */
.card-row { justify-content: space-evenly; } /* equal gaps everywhere */

align-items

Aligns items along the cross axis (one row/column at a time).

ValueEffect
stretch (default)Items stretch to fill container height
flex-startItems align to the start of cross axis
flex-endItems align to the end
centerItems centred on the cross axis
baselineItems aligned by their text baseline
.navbar { align-items: center; } /* vertically centred logo + links */
.card-row { align-items: stretch; } /* all cards same height (default) */

flex-wrap

Controls whether items wrap to new lines when they run out of space.

ValueEffect
nowrap (default)All items on one line, may shrink
wrapItems wrap to next line when needed
wrap-reverseItems wrap upward (rare)
.card-grid {
  display: flex;
  flex-wrap: wrap;    /* cards wrap to next row on small screens */
  gap: 16px;
}

align-content

Like align-items but for multiple rows. Only has effect when flex-wrap: wrap and there are multiple lines.

.wrap-container {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between; /* gaps between rows */
  height: 400px; /* container needs height for this to work */
}

gap (row-gap, column-gap)

Sets the space between flex items. Cleaner than margins.

gap: 16px;           /* same gap in both directions */
gap: 24px 16px;      /* row-gap: 24px, column-gap: 16px */
row-gap: 24px;       /* just row gaps */
column-gap: 16px;    /* just column gaps */

flex-flow Shorthand

Combines flex-direction and flex-wrap:

flex-flow: row wrap;      /* flex-direction: row + flex-wrap: wrap */
flex-flow: column nowrap; /* flex-direction: column + flex-wrap: nowrap */

3. Real World Example

A responsive card grid using flex-wrap:

  • Desktop: 3 cards per row, each takes ~30% width
  • Tablet: 2 cards per row, each takes ~48% width
  • Mobile: 1 card per row, each takes 100% width

This is achieved with display: flex; flex-wrap: wrap; on the container, and controlling the card width with percentages or min-width. No JavaScript, no complex media queries.

4. Code Example

/* ===== ALL JUSTIFY-CONTENT VALUES DEMO ===== */

/* 1. flex-start (default) */
.demo-1 { display: flex; justify-content: flex-start; }

/* 2. flex-end */
.demo-2 { display: flex; justify-content: flex-end; }

/* 3. center */
.demo-3 { display: flex; justify-content: center; }

/* 4. space-between — most common for navbars */
.demo-4 { display: flex; justify-content: space-between; }

/* 5. space-around */
.demo-5 { display: flex; justify-content: space-around; }

/* 6. space-evenly — most balanced */
.demo-6 { display: flex; justify-content: space-evenly; }


/* ===== RESPONSIVE CARD GRID ===== */
.card-grid {
  display: flex;
  flex-wrap: wrap;    /* wrap to next line */
  gap: 24px;
}

.card-grid .card {
  flex: 1 1 300px;    /* grow, shrink, min 300px wide */
  /* on wide screens: 3 cards per row
     on medium: 2 cards
     on small: 1 card (each takes full width) */
}


/* ===== NAVIGATION BAR ===== */
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 24px;
  height: 64px;
  background: #1e293b;
}

.navbar__nav {
  display: flex;      /* nested flex */
  align-items: center;
  gap: 4px;
  list-style: none;
}


/* ===== FOOTER COLUMNS ===== */
.footer {
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  padding: 48px 24px;
  background: #0f172a;
  color: white;
}

.footer__column {
  flex: 1 1 200px; /* minimum 200px wide */
}


/* ===== CENTRED HERO ===== */
.hero {
  display: flex;
  flex-direction: column; /* title, subtitle, button stacked */
  align-items: center;    /* horizontally centred (cross axis = horizontal when column) */
  justify-content: center; /* vertically centred (main axis = vertical when column) */
  min-height: 100vh;
  text-align: center;
  gap: 24px;
}

5. Code Breakdown

flex: 1 1 300px on cards
This shorthand (flex-grow flex-shrink flex-basis) tells each card: grow to fill available space (1), shrink if needed (1), start at 300px minimum. So on a 900px container, 3 cards each get ~300px. On 650px, 2 cards each get ~325px. Covered fully in Lesson 3.
flex-direction: column + align-items: center on hero
When direction is column, the cross axis is horizontal. So align-items: center centres items horizontally. justify-content: center centres them vertically. This is the opposite of what they do in row direction — keep this in mind!
flex: 1 1 200px on footer columns
Each column has a minimum of 200px. On a wide screen, all columns fit in one row. On a narrow screen, columns wrap to form rows of 2 or 1. A simple responsive footer without a single media query.
gap: 24px instead of margins
Using gap is cleaner than adding margin-right to every item (then removing it from the last child with :last-child { margin: 0 }). gap automatically handles this — no gap at the edges, gaps only between items.

6. Common Mistakes

  • Using justify-content: center to vertically centre with flex-direction: row. In a row, justify-content centres horizontally (main axis). Use align-items: center for vertical centering.
  • Expecting align-content to work with a single line. align-content only has an effect when there are multiple lines (flex-wrap: wrap creates multiple lines). It is ignored when all items are on one row.
  • Using margins between flex items instead of gap. Margins add to the outer edges too, requiring :last-child { margin: 0 } hacks. gap only adds space between items.
  • Forgetting that the default align-items is stretch. Items stretch to match the tallest item's height. This is usually desirable for equal-height cards but can be surprising if you expected items to only be as tall as their content.

7. Best Practices

  • Use gap for spacing between flex items — avoid margins that apply to outer edges.
  • Use flex-wrap: wrap for responsive rows — items naturally reflow without media queries.
  • Remember the axis rules: justify-content → main axis, align-items → cross axis.
  • Use flex-flow shorthand when setting both direction and wrap: flex-flow: row wrap.
  • Use align-items: stretch (default) for equal-height cards — all cards in a row automatically match the tallest card's height.

8. Practice Exercise

  1. Create a container with 5 coloured boxes. Try each justify-content value and observe the result.
  2. Set a container height of 200px. Try each align-items value and observe the differences.
  3. Create a card container with 6 cards. Add flex-wrap: wrap. Make each card flex: 1 1 200px. Resize the browser window and watch them reflow.
  4. Build a responsive navigation: logo + three nav links + button. All in one row on desktop. Logo centred on mobile (change to flex-direction: column).

9. Assignment

Build a complete responsive blog layout using Flexbox container properties:

  • A horizontal navbar using justify-content: space-between and align-items: center
  • A tag/filter bar using flex-wrap: wrap; gap: 8px; for a row of tag buttons
  • A blog post grid: flex-wrap: wrap; gap: 24px; with cards that are flex: 1 1 280px
  • A centred "Load More" button row using justify-content: center
  • A three-column footer using flex-wrap: wrap

10. Interview Questions

Q1: What is the difference between justify-content and align-items?

Answer: justify-content distributes space along the main axis. align-items aligns items along the cross axis. In the default row direction, justify-content is horizontal and align-items is vertical. When flex-direction is column, they swap roles.

Q2: What does flex-wrap do and when would you use it?

Answer: flex-wrap: wrap allows flex items to wrap onto multiple lines when there isn't enough space. Use it for card grids, tag clouds, and any row of items that should reflow on small screens rather than overflow or shrink below their minimum size.

Q3: What is the difference between align-items and align-content?

Answer: align-items aligns items within a single row/column (the cross axis of each line). align-content distributes space between multiple lines — it only works when flex-wrap: wrap has created multiple lines. align-items works even with a single line.

Q4: What are the values of justify-content and what does each do?

Answer: flex-start (default) — items at start. flex-end — items at end. center — items centred. space-between — first at start, last at end, equal gaps between. space-around — equal space around each item, half at edges. space-evenly — equal space between items and at edges.

Q5: Why is gap better than using margins for flex item spacing?

Answer: Gap only adds space between items, not at the outer edges. With margins, you add margins to all items but then have to remove the margin from the first or last item using :first-child or :last-child selectors. Gap is cleaner, simpler, and works correctly with wrapping.

11. Additional Resources

  • CSS-Tricks — A Complete Guide to Flexbox (search "css-tricks flexbox guide")
  • Flexbox Froggy — flexboxfroggy.com
  • MDN — justify-content (search "MDN justify-content")
  • MDN — align-items (search "MDN align-items")
  • Visual Flexbox Cheatsheet — search "flexbox cheatsheet"