Flexbox Introduction
Understand what Flexbox is, the flex container/item model, and the main and cross axes.
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-direction | Main axis | Cross axis |
|---|---|---|
row (default) | Horizontal (left → right) | Vertical (top → bottom) |
row-reverse | Horizontal (right → left) | Vertical (top → bottom) |
column | Vertical (top → bottom) | Horizontal (left → right) |
column-reverse | Vertical (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-betweenputs 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-contentandalign-itemsgo on the container, not the items. A very common beginner error. -
Confusing main axis and cross axis. When
flex-direction: column,justify-contentaligns vertically andalign-itemsaligns 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__linksis both a flex item (inside the navbar) and a flex container (for itslichildren). 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
gapinstead of margins for spacing between flex items — cleaner and more predictable. - Add
flex-wrap: wrapfor 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
- Create a div with three coloured boxes inside. Add
display: flexto the parent. Observe how they line up horizontally. - Add
flex-direction: column. Observe how they stack vertically. - Change back to
row. Addjustify-content: centerandalign-items: centerwith a fixed height. Observe the result. - Build a simple navbar: logo on the left, three links on the right. Use Flexbox for both the main nav and the link list.
- 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