Flexbox Layouts
Flexbox (Flexible Box Layout) is the CSS superpower that makes alignment and distribution of elements finally predictable. Before Flexbox, centering a div was famously painful. Now? One line: display: flex; align-items: center; justify-content: center. In this lesson you'll learn every key property — parent and child — and build real UI patterns with confidence.
What is Flexbox?
Flexbox is a one-dimensional layout system. "One-dimensional" means it arranges items along a single axis — either a row (horizontal) or a column (vertical). Compare this to CSS Grid which handles two dimensions at once.
You activate Flexbox on a container element. Its direct children automatically become flex items and follow the flex rules.
display: flex) and flex items (the direct children). Some properties go on the container, others go on individual items. Knowing which is which is the key to understanding Flexbox..container { display: flex; /* That's it! Children are now flex items */ } /* The children automatically arrange in a row (default) */ .container div { background: steelblue; padding: 1rem; color: white; }
Main Axis & Cross Axis
Flexbox revolves around two axes. The main axis is the primary direction items flow (set by flex-direction). The cross axis runs perpendicular to it.
flex-direction: column, the main axis becomes vertical and the cross axis becomes horizontal. This means justify-content now controls vertical alignment and align-items controls horizontal. Keep this in mind — it's the #1 source of Flexbox confusion.Container Properties
These properties go on the parent container. They control how children are arranged, spaced, and aligned.
| Property | Values | What it does | Applied to |
|---|---|---|---|
| flex-direction | row · row-reverse · column · column-reverse | Sets the main axis direction | Parent |
| justify-content | flex-start · flex-end · center · space-between · space-around · space-evenly | Aligns items along the main axis | Parent |
| align-items | stretch · flex-start · flex-end · center · baseline | Aligns items along the cross axis | Parent |
| flex-wrap | nowrap · wrap · wrap-reverse | Controls whether items wrap to next line | Parent |
| gap | any length (e.g. 1rem, 16px) | Space between flex items (replaces margin hacks) | Parent |
| align-content | flex-start · center · space-between · stretch | Aligns rows when there are multiple (needs flex-wrap) | Parent |
.nav { display: flex; justify-content: space-between; /* logo left, links right */ align-items: center; /* vertical center */ padding: 1rem 2rem; } .hero { display: flex; justify-content: center; /* center horizontally */ align-items: center; /* center vertically */ min-height: 100vh; /* full screen */ } .card-row { display: flex; gap: 1.5rem; /* space between cards */ flex-wrap: wrap; /* wrap on small screens */ }
Child (Item) Properties
These properties go on individual flex items (the children), giving you per-item control over sizing, order, and alignment.
| Property | Values | What it does | Applied to |
|---|---|---|---|
| flex-grow | 0 (default) · 1 · any number | How much the item grows to fill remaining space | Child |
| flex-shrink | 1 (default) · 0 · any number | How much the item shrinks if there isn't enough space | Child |
| flex-basis | auto · 0 · any size (200px, 30%) | The starting size before growing/shrinking | Child |
| flex | flex: 1 (= 1 1 0) · flex: auto | Shorthand for grow, shrink, basis | Child |
| align-self | auto · flex-start · flex-end · center · stretch | Override align-items for this one item | Child |
| order | 0 (default) · any integer | Change visual order without changing HTML | Child |
.sidebar { flex: 0 0 260px; } /* fixed 260px, won't grow or shrink */ .main-content { flex: 1; } /* takes all remaining space */ /* Two equal columns */ .col { flex: 1; } /* both grow equally */ /* Three columns: 1:2:1 ratio */ .col-sm { flex: 1; } .col-lg { flex: 2; } /* gets twice as much space */
fixed 100px
flex: 1 is shorthand for flex: 1 1 0 — grow to fill space, shrink if needed, start from 0 basis. It's the most versatile pattern for fluid layouts. Use it on the "stretchy" part of a layout and fixed dimensions on the rigid parts.Real-World Flex Patterns
Flexbox shines for common UI patterns. Here are the four most important ones you'll use constantly:
.centered { display: flex; justify-content: center; align-items: center; min-height: 100vh; /* works for any container */ }
/* HTML */ <nav class="navbar"> <a class="logo">MySite</a> <ul class="nav-links"> <li><a>Home</a></li> <li><a>About</a></li> <li><a>Contact</a></li> </ul> <button>Sign Up</button> </nav> /* CSS */ .navbar { display: flex; justify-content: space-between; align-items: center; padding: 1rem 2rem; } .nav-links { display: flex; list-style: none; gap: 2rem; }
.cards { display: flex; flex-wrap: wrap; gap: 1.5rem; } .card { flex: 1 1 280px; /* grow, shrink, start at 280px wide */ padding: 1.5rem; border-radius: 12px; background: #0a1230; } /* Cards are naturally responsive — 3 per row on desktop, 1 per row on mobile, automatically! */
<div class="layout"> <aside class="sidebar">...</aside> <main class="content">...</main> </div> .layout { display: flex; gap: 2rem; align-items: flex-start; /* prevent equal height stretch */ } .sidebar { flex: 0 0 260px; } /* fixed width */ .content { flex: 1; } /* fills remaining space */
flex: 1 mean in full?flex-direction: column. What does justify-content: center do?align-self: flex-end. What does this do?Build a
<nav> with logo on the left, 3 links centered, and a "Sign Up" button on the right. Use justify-content: space-between and align-items: center. The links themselves should be a nested flex container with gap: 2rem.Part B — Wrapping Card Row:
Create a
.cards wrapper with display: flex; flex-wrap: wrap; gap: 1.5rem. Inside, place 4 .card elements each with flex: 1 1 220px. Give each card an icon, title, and description. They should automatically reflow from 4-across on desktop to 2-across on medium screens to 1 per row on mobile — without any media queries.
💡 Show hints
- Nav:
nav { display: flex; justify-content: space-between; align-items: center; } - Nav links:
ul { display: flex; list-style: none; gap: 2rem; } - Card row:
.cards { display: flex; flex-wrap: wrap; gap: 1.5rem; } - Each card:
.card { flex: 1 1 220px; }— this is the magic that makes it responsive without media queries - To push the button to the right in nav, you could also use
margin-left: autoon the button
/* nav.css */ * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: sans-serif; background: #05091a; color: #eef3ff; } nav { display: flex; justify-content: space-between; align-items: center; padding: 1rem 2rem; background: #0a1230; border-bottom: 1px solid rgba(255,255,255,.08); } ul { display: flex; list-style: none; gap: 2rem; } ul a { color: #8ca8d8; text-decoration: none; font-size: .9rem; } ul a:hover { color: #eef3ff; } .btn { padding: .5rem 1.2rem; background: linear-gradient(135deg, #4f9eff, #1a78ff); color: white; border: none; border-radius: 999px; font-weight: 700; cursor: pointer; } /* Card Row */ .cards { display: flex; flex-wrap: wrap; gap: 1.5rem; padding: 2rem; } .card { flex: 1 1 220px; background: #0a1230; border: 1px solid rgba(255,255,255,.08); border-radius: 12px; padding: 1.5rem; } .card-icon { font-size: 2rem; margin-bottom: .8rem; } .card-title { font-weight: 700; margin-bottom: .4rem; } .card-desc { font-size: .85rem; color: #8ca8d8; line-height: 1.6; }