Home Module 05 Flexbox Introduction

1. Introduction

Before Flexbox, building horizontal layouts in CSS was painful. Developers used floats, inline-block hacks, and table layouts — all of which had quirky side effects. Centering something vertically was famously difficult.

Flexbox (Flexible Box Layout) was introduced in CSS3 to solve these problems. It is a one-dimensional layout system — it lays items out either in a row or in a column at a time.

With Flexbox you can:

  • Lay items out horizontally in a row
  • Lay items out vertically in a column
  • Distribute space evenly between items
  • Align items along any axis
  • Centre content both horizontally and vertically with 2 properties
  • Reorder items without changing HTML

Flexbox is now supported in 100% of modern browsers and is used on virtually every professional website.

2. Theory

Activating Flexbox

Apply display: flex to a container element. Its direct children automatically become flex items.

<div class="container">   ← flex container
  <div>Item 1</div>       ← flex item
  <div>Item 2</div>       ← flex item
  <div>Item 3</div>       ← flex item
</div>
.container {
  display: flex;
  /* items now line up horizontally by default */
}

The Flex Container and Flex Items

There are two roles in Flexbox:

  • Flex container — the parent with display: flex. You set layout properties here (direction, wrapping, alignment).
  • Flex items — the direct children. You control their individual sizing and ordering here.

Only direct children are flex items. Deeper nested elements are not affected unless they are also flex containers themselves.

The Main Axis and Cross Axis

Flexbox has two axes:

  • Main axis — the primary direction items flow (horizontal by default)
  • Cross axis — perpendicular to the main axis (vertical by default)

The axes change based on flex-direction:

flex-directionMain axisCross axis
row (default)Horizontal (left → right)Vertical (top → bottom)
row-reverseHorizontal (right → left)Vertical (top → bottom)
columnVertical (top → bottom)Horizontal (left → right)
column-reverseVertical (bottom → top)Horizontal (left → right)

This is crucial because alignment properties (justify-content, align-items) always work relative to these axes.

Default Flexbox Behaviour

When you add display: flex to a container, the default behaviour is:

  • Items display in a row (horizontal)
  • Items start at the left edge
  • Items stretch to fill the container's height
  • Items do NOT wrap to the next line when they overflow
  • Items shrink if necessary to fit in one line

display: flex vs display: inline-flex

display: flex;        /* container is a block (fills parent width) */
display: inline-flex; /* container is inline (sized to its content) */

3. Real World Example

Flexbox is used in almost every UI component:

  • Navigation bars — logo on left, links on right
  • Card headers — icon + title + badge all in one row, aligned
  • Button groups — buttons side by side with equal spacing
  • Centring a div — perfectly centred on screen (2 lines of CSS)
  • Footers — multiple columns on desktop, stacked on mobile
  • Toolbars — items spaced evenly across a bar

Flexbox is used for one-dimensional layouts (rows OR columns). For two-dimensional layouts (rows AND columns simultaneously), use CSS Grid (Module 06).

4. Code Example

<!-- HTML -->
<nav class="navbar">
  <div class="navbar__brand">MyApp</div>
  <ul class="navbar__links">
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
  <button class="btn btn--primary">Sign Up</button>
</nav>

<section class="hero">
  <div class="hero__content">
    <h1>Hello World</h1>
    <p>This is centred using Flexbox.</p>
  </div>
</section>
/* Navbar — flex row, items spread apart */
.navbar {
  display: flex;
  align-items: center;       /* vertical centre */
  justify-content: space-between; /* spread to edges */
  padding: 0 24px;
  height: 64px;
  background: #1e293b;
}

.navbar__links {
  display: flex;        /* links also a flex container */
  list-style: none;
  gap: 8px;             /* space between items */
}

/* Hero — perfect vertical + horizontal centre */
.hero {
  display: flex;
  justify-content: center; /* horizontal centre */
  align-items: center;     /* vertical centre */
  min-height: 100vh;
  background: linear-gradient(135deg, #2563eb, #7c3aed);
  color: white;
  text-align: center;
}

/* flex-direction: column example */
.sidebar {
  display: flex;
  flex-direction: column;  /* stack items vertically */
  gap: 8px;
  padding: 16px;
}

5. Code Breakdown

align-items: center
Aligns items along the cross axis. With default flex-direction: row, the cross axis is vertical — so this centres items vertically. Without it, items would stretch to fill the container height.
justify-content: space-between
Distributes items along the main axis (horizontal here). space-between puts the first item at the start, last item at the end, and equal space between all others. Perfect for logos-and-links navbars.
gap: 8px
Sets the gap between flex items. Much cleaner than using margins on each item. Works for both rows and columns.
justify-content: center + align-items: center
The famous "centring with Flexbox" technique. These two properties together centre content both horizontally and vertically. Historically, vertical centering in CSS was extremely difficult — Flexbox makes it trivial.
flex-direction: column
Flips the layout to vertical. Now items stack on top of each other (like normal block flow), but with all the Flexbox alignment powers. The main axis is now vertical; cross axis is horizontal.

6. Common Mistakes

  • Applying flex properties to items instead of the container. justify-content and align-items go on the container, not the items. A very common beginner error.
  • Confusing main axis and cross axis. When flex-direction: column, justify-content aligns vertically and align-items aligns horizontally — the opposite of row. This confuses many learners.
  • Expecting Flexbox to affect non-direct children. Only direct children of the flex container are flex items. Nested elements are not affected unless their parent is also a flex container.
  • Forgetting that flex items can also be flex containers. In the navbar, .navbar__links is both a flex item (inside the navbar) and a flex container (for its li children). Nesting flex containers is normal and powerful.

7. Best Practices

  • Use Flexbox for one-dimensional layouts — rows or columns. Use Grid for two-dimensional.
  • Use gap instead of margins for spacing between flex items — cleaner and more predictable.
  • Add flex-wrap: wrap for responsive rows that should wrap to multiple lines on small screens (covered in Lesson 2).
  • Understand the axis system — burn this into memory: justify-content = main axis, align-items = cross axis.
  • Nest flex containers freely — a flex item can also be a flex container for its own children.

8. Practice Exercise

  1. Create a div with three coloured boxes inside. Add display: flex to the parent. Observe how they line up horizontally.
  2. Add flex-direction: column. Observe how they stack vertically.
  3. Change back to row. Add justify-content: center and align-items: center with a fixed height. Observe the result.
  4. Build a simple navbar: logo on the left, three links on the right. Use Flexbox for both the main nav and the link list.
  5. Create a centred hero section using display: flex; justify-content: center; align-items: center; min-height: 100vh;

9. Assignment

Build a complete page header and hero section using only Flexbox for layout:

  • A fixed header/navbar: logo left, navigation links centre, CTA button right — all using Flexbox
  • A hero section: full-viewport-height, content perfectly centred both axes, flex-direction column (title above subtitle above buttons)
  • A "features" row: three feature cards side by side, equal width, equal height — Flexbox row
  • No floats, no absolute positioning for layout (positioning is OK for decorative elements)

10. Interview Questions

Q1: What is Flexbox and what problem does it solve?

Answer: Flexbox (Flexible Box Layout) is a CSS layout model for one-dimensional layouts. It solves the problems of aligning, distributing, and ordering elements in a row or column — things that were very difficult with older techniques like floats and inline-block.

Q2: What is the difference between the main axis and cross axis in Flexbox?

Answer: The main axis is the primary direction flex items flow (horizontal by default with row). The cross axis is perpendicular (vertical by default). When you change flex-direction to column, the main axis becomes vertical and cross axis becomes horizontal. justify-content aligns along the main axis; align-items aligns along the cross axis.

Q3: What is the difference between a flex container and a flex item?

Answer: A flex container is the parent element with display: flex. Flex items are its direct children. Container properties (like justify-content, align-items, gap, flex-direction) control the layout of all children. Item properties (like flex-grow, align-self, order) control individual items.

Q4: How do you perfectly centre content both horizontally and vertically?

Answer: Apply display: flex; justify-content: center; align-items: center; to the container, with a defined height (like min-height: 100vh). This centres all flex items in both axes simultaneously.

Q5: What is the difference between display: flex and display: inline-flex?

Answer: Both make the element a flex container and apply the same layout to children. The difference is the container's own behaviour: flex makes the container a block element (takes full width, starts on new line), while inline-flex makes it inline (only as wide as its content, flows with text).

11. Additional Resources

  • CSS-Tricks — A Complete Guide to Flexbox (search "css-tricks complete guide flexbox")
  • Flexbox Froggy — flexboxfroggy.com (interactive game to learn Flexbox)
  • MDN Web Docs — Flexbox (search "MDN CSS flexbox")
  • web.dev — Learn CSS Flexbox (search "web.dev learn css flexbox")
  • Flexbox Playground — search "flexbox playground" to visualise properties live