3.4: Flexbox Layout

Master CSS Flexbox for creating flexible, responsive one-dimensional layouts. Learn how to align, distribute, and order elements along rows or columns with powerful flex properties.

1. Introduction to Flexbox

Flexbox (Flexible Box Layout) is a CSS layout module designed for one-dimensional layouts (row or column).

Why Flexbox?

Before Flexbox:

/* Old way - float-based layout (messy) */
.nav-item {
  float: left;
  width: 25%;
}

.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

With Flexbox:

/* Modern way - clean and simple */
.nav {
  display: flex;
  gap: 20px;
}

When to Use Flexbox

Perfect for:

  • ✅ Navigation bars
  • ✅ Card layouts
  • ✅ Centering elements
  • ✅ Equal-height columns
  • ✅ Distributing space
  • ✅ Reordering items

Not ideal for:

  • ❌ Complex 2D grids (use CSS Grid instead)
  • ❌ Overall page layout (Grid is better)

2. Flex Container

To use Flexbox, create a flex container with display: flex.

Creating a Flex Container

.container {
  display: flex;
}

/* Inline flex (rare) */
.container {
  display: inline-flex;
}

HTML:

<div class="container">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>

Result: Items are laid out horizontally (default direction)


3. Flex Direction

Controls the main axis direction.

Flex Direction Values

/* Horizontal (default) */
.container {
  display: flex;
  flex-direction: row;
}

/* Horizontal reversed */
.container {
  display: flex;
  flex-direction: row-reverse;
}

/* Vertical */
.container {
  display: flex;
  flex-direction: column;
}

/* Vertical reversed */
.container {
  display: flex;
  flex-direction: column-reverse;
}

Main Axis vs Cross Axis

flex-direction: row
┌─────────────────────────────────┐
│  → → → → MAIN AXIS → → → →     │
│  ↑                              │
│  ↓  [Item 1] [Item 2] [Item 3] │
│  ↑                              │
│  CROSS AXIS                     │
└─────────────────────────────────┘

flex-direction: column
┌───────────────┐
│  → → CROSS → →│
│  ↓            │
│  [Item 1]     │
│  ↓            │
│  [Item 2]     │
│  ↓            │
│  [Item 3]     │
│  ↓            │
│  MAIN AXIS    │
└───────────────┘

Key concept: Main axis = flex-direction, Cross axis = perpendicular


4. Justify Content (Main Axis Alignment)

Aligns items along the main axis.

Justify Content Values

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

/* End */
.container {
  justify-content: flex-end;
}

/* Center */
.container {
  justify-content: center;
}

/* Space between */
.container {
  justify-content: space-between;
}

/* Space around */
.container {
  justify-content: space-around;
}

/* Space evenly */
.container {
  justify-content: space-evenly;
}

Visual Examples

flex-start:     [1][2][3]___________

flex-end:       ___________[1][2][3]

center:         _____[1][2][3]_____

space-between:  [1]_______[2]_______[3]

space-around:   __[1]____[2]____[3]__

space-evenly:   ___[1]___[2]___[3]___

Practical Examples

Navigation bar:

.nav {
  display: flex;
  justify-content: space-between;
}

Centered buttons:

.button-group {
  display: flex;
  justify-content: center;
  gap: 10px;
}

5. Align Items (Cross Axis Alignment)

Aligns items along the cross axis.

Align Items Values

/* Stretch (default) */
.container {
  display: flex;
  align-items: stretch;
}

/* Start */
.container {
  align-items: flex-start;
}

/* End */
.container {
  align-items: flex-end;
}

/* Center */
.container {
  align-items: center;
}

/* Baseline (align by text baseline) */
.container {
  align-items: baseline;
}

Visual Examples (flex-direction: row)

stretch:
┌──────────────────┐
│ [1]  [2]  [3]   │  ← Items stretch to fill height
│                  │
└──────────────────┘

flex-start:
┌──────────────────┐
│ [1]  [2]  [3]   │  ← Items at top
│                  │
│                  │
└──────────────────┘

center:
┌──────────────────┐
│                  │
│ [1]  [2]  [3]   │  ← Items centered vertically
│                  │
└──────────────────┘

flex-end:
┌──────────────────┐
│                  │
│                  │
│ [1]  [2]  [3]   │  ← Items at bottom
└──────────────────┘

Perfect Centering

/* Center both horizontally and vertically */
.container {
  display: flex;
  justify-content: center;  /* Main axis */
  align-items: center;       /* Cross axis */
  height: 400px;
}

6. Flex Wrap

Controls whether items wrap to new lines.

Flex Wrap Values

/* No wrap (default - items shrink) */
.container {
  display: flex;
  flex-wrap: nowrap;
}

/* Wrap to next line */
.container {
  display: flex;
  flex-wrap: wrap;
}

/* Wrap in reverse */
.container {
  display: flex;
  flex-wrap: wrap-reverse;
}

Practical Example: Card Grid

.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 0 0 calc(33.333% - 14px); /* 3 columns */
}

7. Align Content (Multi-line Alignment)

Aligns multiple lines along the cross axis (only works with flex-wrap: wrap).

Align Content Values

.container {
  display: flex;
  flex-wrap: wrap;
  height: 400px;

  align-content: flex-start;
  align-content: flex-end;
  align-content: center;
  align-content: space-between;
  align-content: space-around;
  align-content: space-evenly;
  align-content: stretch; /* Default */
}

Note: Only applies when there are multiple lines of flex items


8. Gap (Spacing Between Items)

Modern way to add space between flex items.

.container {
  display: flex;
  gap: 20px; /* Space between items */
}

/* Individual gaps */
.container {
  row-gap: 20px;    /* Vertical space */
  column-gap: 30px; /* Horizontal space */
}

Old way (before gap):

.item {
  margin-right: 20px;
}

.item:last-child {
  margin-right: 0;
}

New way (with gap):

.container {
  display: flex;
  gap: 20px; /* Much simpler! */
}

9. Flex Items Properties

Flex Grow

Controls how items grow to fill available space.

.item {
  flex-grow: 1; /* Grow to fill space */
}

/* Different growth ratios */
.item-1 { flex-grow: 1; } /* 1 part */
.item-2 { flex-grow: 2; } /* 2 parts (twice as much) */
.item-3 { flex-grow: 1; } /* 1 part */

/* Total: 4 parts
   Item 1 gets 25%, Item 2 gets 50%, Item 3 gets 25% */

Flex Shrink

Controls how items shrink when space is limited.

.item {
  flex-shrink: 1; /* Default - can shrink */
  flex-shrink: 0; /* Won't shrink */
}

Flex Basis

Sets the initial size of an item.

.item {
  flex-basis: 200px;     /* Start at 200px */
  flex-basis: 50%;       /* Start at 50% */
  flex-basis: auto;      /* Based on content (default) */
  flex-basis: 0;         /* No initial size */
}

Flex Shorthand

Combines grow, shrink, and basis.

/* flex: grow shrink basis */
.item {
  flex: 1 1 auto;    /* Can grow, can shrink, auto basis */
  flex: 0 0 200px;   /* Fixed 200px */
  flex: 1;           /* Grow, shrink, 0 basis (common) */
}

/* Common patterns */
.item {
  flex: 1;           /* Grow to fill, equal widths */
  flex: 0 0 auto;    /* Don't grow/shrink, size by content */
  flex: 0 0 300px;   /* Fixed 300px */
}

Align Self

Override align-items for individual items.

.container {
  display: flex;
  align-items: flex-start;
}

.item-special {
  align-self: flex-end; /* This item aligns differently */
}

Order

Change the visual order of items.

.item-1 { order: 2; }
.item-2 { order: 1; } /* Shows first */
.item-3 { order: 3; }

/* Default order is 0 */

10. Common Flexbox Patterns

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background: #2c3e50;
}

.nav-logo {
  flex: 0 0 auto;
}

.nav-menu {
  display: flex;
  gap: 30px;
  list-style: none;
}

.nav-actions {
  display: flex;
  gap: 10px;
}

Card Grid (Equal Heights)

.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 0 0 calc(33.333% - 14px); /* 3 columns */
  display: flex;
  flex-direction: column;
}

.card-content {
  flex: 1; /* Grow to fill */
}

.card-footer {
  margin-top: auto; /* Push to bottom */
}
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.main-content {
  flex: 1; /* Grow to fill space */
}

.footer {
  flex: 0 0 auto;
}

Holy Grail Layout

.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.main {
  display: flex;
  flex: 1;
}

.sidebar-left {
  flex: 0 0 200px;
}

.content {
  flex: 1;
}

.sidebar-right {
  flex: 0 0 250px;
}

Perfect Centering

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

Responsive Cards

.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 300px; /* Min 300px, grow to fill */
  max-width: 400px;
}

11. Responsive Flexbox

Mobile-First Approach

/* Mobile: Stack vertically */
.container {
  display: flex;
  flex-direction: column;
}

/* Tablet: 2 columns */
@media (min-width: 768px) {
  .container {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .item {
    flex: 0 0 calc(50% - 10px);
  }
}

/* Desktop: 3 columns */
@media (min-width: 1024px) {
  .item {
    flex: 0 0 calc(33.333% - 14px);
  }
}

Responsive Navigation

/* Mobile: Vertical menu */
.nav {
  display: flex;
  flex-direction: column;
}

/* Desktop: Horizontal menu */
@media (min-width: 768px) {
  .nav {
    flex-direction: row;
    justify-content: space-between;
  }
}

12. Debugging Flexbox

Browser DevTools

Chrome/Edge/Firefox:

  1. Inspect flex container
  2. Elements panel shows "Flexbox" badge
  3. Click badge to see flex overlay
  4. Adjust properties in real-time

Flexbox overlay shows:

  • Main axis direction
  • Cross axis direction
  • Gaps between items
  • Alignment guides

Common Issues

Issue: Items not wrapping

/* Add flex-wrap */
.container {
  display: flex;
  flex-wrap: wrap;
}

Issue: Items not filling container

/* Make items grow */
.item {
  flex: 1;
}

Issue: Items overflowing

/* Allow shrinking */
.item {
  flex-shrink: 1;
  min-width: 0; /* Important for text overflow */
}

13. Practical Exercises

Exercise 3.4.1: Navigation Bar

Create a responsive navigation with:

  • Logo on left
  • Menu items centered
  • Login button on right
  • Mobile: stack vertically

Exercise 3.4.2: Card Grid

Build a card grid that:

  • Shows 1 column on mobile
  • Shows 2 columns on tablet
  • Shows 3 columns on desktop
  • Cards have equal heights

Exercise 3.4.3: Centering Challenge

Center a modal dialog:

  • Horizontally and vertically on screen
  • Modal is 500px wide
  • Content is centered inside modal

Exercise 3.4.4: Pricing Cards

Create 3 pricing cards where:

  • All cards have equal heights
  • Buttons always at bottom
  • Middle card is highlighted
  • Responsive on mobile

14. Knowledge Check

Question 1: What's the difference between justify-content and align-items?

Show answer justify-content aligns items along the main axis, align-items aligns along the cross axis.

Question 2: When does align-content take effect?

Show answer Only when flex-wrap: wrap is used and there are multiple lines of flex items.

Question 3: What does flex: 1 mean?

Show answer flex: 1 is shorthand for flex: 1 1 0 (can grow, can shrink, 0 basis). Items will grow to fill space equally.

Question 4: How do you prevent a flex item from shrinking?

Show answer Use flex-shrink: 0 or flex: 0 0 auto

Question 5: What's the modern way to add space between flex items?

Show answer Use the gap property (e.g., gap: 20px) instead of margins.

Question 6: How do you center an element both horizontally and vertically?

Show answer display: flex; justify-content: center; align-items: center;

15. Common Mistakes to Avoid

❌ Forgetting flex-wrap

/* Bad - items will shrink infinitely */
.container {
  display: flex;
}

/* Good - items wrap to new lines */
.container {
  display: flex;
  flex-wrap: wrap;
}

❌ Using width instead of flex-basis

/* Less flexible */
.item {
  width: 200px;
}

/* More flexible */
.item {
  flex-basis: 200px;
}

❌ Forgetting min-width: 0

/* Text might overflow */
.item {
  flex: 1;
}

/* Prevents overflow */
.item {
  flex: 1;
  min-width: 0;
}

16. Key Takeaways

Flexbox - One-dimensional layout (row or column) ✅ Flex container - Parent with display: flex ✅ Main axis - Direction of flex-direction ✅ Cross axis - Perpendicular to main axis ✅ justify-content - Main axis alignment ✅ align-items - Cross axis alignment (single line) ✅ align-content - Cross axis alignment (multi-line) ✅ flex-wrap - Allow wrapping to multiple lines ✅ gap - Modern spacing between items ✅ flex shorthand - flex: grow shrink basis ✅ Perfect centering - justify-content: center + align-items: center


17. Further Resources

Official Documentation:

Interactive Learning:

Tools:


Next Steps

Excellent! You've mastered Flexbox for one-dimensional layouts.

In Lesson 3.5: Grid Layout, you'll learn CSS Grid for powerful two-dimensional layouts with rows and columns.