Chapter 13: Flexbox for One-Dimensional Layout
Flexbox lets you arrange elements along a single axis with precise control over spacing and alignment. It excels at components such as navigation bars, toolbars and card rows. You work with a flex container that controls the flow of its flex items. This chapter explains the essential properties you will use daily, then builds a practical navigation bar to lock in the ideas.
The flex container
A flex layout begins when you set display:flex on a parent element. This parent becomes the flex container, and its direct children become flex items. The container defines direction, wrapping and spacing rules. The items respond to those rules and can also override some behaviour with their own properties.
display:flex creates the layout context
Setting display:flex activates the flex formatting context. Items line up on a single row by default; if there is not enough room they will overflow unless you also enable wrapping. The container takes control of alignment with properties such as justify-content, align-items and gap.
<style>
.container { display:flex; }
.container > div { padding:0.5rem; border:1px solid #ccc; }
</style>
<div class="container">
<div>One</div><div>Two</div><div>Three</div>
</div>
Main axis and cross axis
The main axis follows flex-direction. With row the main axis runs horizontally left to right. With column it runs vertically top to bottom. The cross axis is perpendicular to the main axis. Understanding these two directions makes alignment properties feel straightforward.
| flex-direction | Main axis | Cross axis |
row | Left to right | Top to bottom |
row-reverse | Right to left | Top to bottom |
column | Top to bottom | Left to right |
column-reverse | Bottom to top | Left to right |
<style>
.stack { display:flex; flex-direction:column; gap:0.5rem; }
</style>
<div class="stack">
<button>Save</button><button>Export</button><button>Close</button>
</div>
Wrapping with flex-wrap
Flexbox defaults to a single line of items. Add flex-wrap:wrap to allow items to flow to the next line when space runs out. Combine with gap for clean spacing that respects the wrap.
<style>
.tags { display:flex; flex-wrap:wrap; gap:0.5rem; }
.tags a { padding:0.25rem 0.5rem; background:#f3f3f3; text-decoration:none; border-radius:4px; }
</style>
<p>Topics:</p>
<nav class="tags">
<a href="#">CSS</a><a href="#">Flexbox</a><a href="#">Layout</a><a href="#">Typography</a><a href="#">SVG</a><a href="#">Forms</a>
</nav>
gap with side margins on the same items. Prefer a single spacing system to keep layouts predictable.
Horizontal and vertical alignment
Flexbox gives you fine control over alignment with a small set of properties. Use justify-content for spacing along the main axis and align-items for alignment on the cross axis. When wrapping is enabled, align-content controls how the rows or columns of items distribute space across the cross axis.
justify-content controls main-axis spacing
Use justify-content to position items across the main axis. Common values include flex-start, center, space-between and space-around. The spacing values distribute free space between items so you do not have to juggle margins.
<style>
.toolbar { display:flex; justify-content:space-between; align-items:center; padding:0.5rem; border:1px solid #ddd; }
.toolbar .left, .toolbar .right { display:flex; gap:0.5rem; }
</style>
<div class="toolbar">
<div class="left"><button>New</button><button>Open</button></div>
<strong>Project</strong>
<div class="right"><button>Share</button><button>Export</button></div>
</div>
align-items aligns on the cross axis
Use align-items to line up item edges or centers on the cross axis. Values such as stretch, flex-start, center and flex-end handle the common cases. This is helpful when items have different heights or when text and icons need to sit on the same baseline visually.
<style>
.media { display:flex; align-items:center; gap:0.75rem; }
.media img { width:48px; height:48px; border-radius:50%; }
</style>
<div class="media">
<img src="avatar.png" alt="Profile">
<p>Hello from the profile card. This text aligns vertically with the image center.</p>
</div>
align-content for wrapped lines
When items wrap into multiple lines, align-content distributes the stack of lines along the cross axis. This does nothing when the layout has a single line. Values mirror those of justify-content which keeps the mental model consistent.
<style>
.gallery { display:flex; flex-wrap:wrap; gap:0.5rem; align-content:start; height:200px; border:1px dashed #bbb; padding:0.5rem; }
.gallery > div { flex:0 0 90px; height:60px; background:#e9eef6; }
</style>
<div class="gallery">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
Per-item control
You can let items push apart by giving one or more items margin-left:auto or margin-inline-start:auto in a row layout. For cross-axis overrides use align-self on an item to differ from the container’s align-items.
<style>
.bar { display:flex; align-items:center; gap:0.5rem; }
.bar .spacer { margin-left:auto; }
.bar button:last-child { align-self:flex-end; }
</style>
<div class="bar">
<button>A</button><button>B</button><span class="spacer"></span><button>C</button>
</div>
gap for consistent spacing, then use auto margins for strategic pushes such as separating primary and secondary actions.
Turning navigation into a flexible bar
A navigation bar is a perfect showcase for Flexbox. The container holds a brand on the left, links in the middle and a small group of actions on the right. The layout adapts smoothly across screen sizes and can wrap if space is tight.
HTML structure for a simple nav
Keep the markup clear. The container uses nav with three groups. The middle group is an unordered list of links. The right group holds small actions such as a search button or a theme toggle. Unknown or optional actions can be represented as … in examples when the exact content is not the focus.
<nav class="site-nav" aria-label="Primary">
<a class="brand" href="#">Brand</a>
<ul class="links">
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
<div class="actions">
<button aria-label="Search">Search</button><button>Sign in</button>
</div>
</nav>
Flexbox CSS for layout, spacing and wrapping
The navigation container becomes a flex context. The link list is also a flex row so the list items sit horizontally with clean gaps. A flexible spacer is not required when you can use justify-content:space-between on the container, but a targeted margin:auto on the middle group often reads clearly.
<style>
.site-nav { display:flex; align-items:center; gap:1rem; padding:0.5rem 1rem; border-bottom:1px solid #e5e5e5; flex-wrap:wrap; }
.site-nav .brand { font-weight:bold; text-decoration:none; }
.site-nav .links { list-style:none; display:flex; gap:1rem; padding:0; margin:0; }
.site-nav .links a { text-decoration:none; }
.site-nav .actions { display:flex; gap:0.5rem; margin-left:auto; }
@media (max-width:640px) {
.site-nav { gap:0.5rem; }
.site-nav .links { flex-basis:100%; order:1; justify-content:center; }
.site-nav .actions { order:2; margin-left:0; width:100%; justify-content:center; }
}
</style>
Handling long labels and overflow
Real menus gain long labels. Prevent crowding by allowing the link list to wrap and by setting sensible minimums. You can also let one item take spare space with flex:1 when appropriate, such as a search input that can grow.
<style>
.site-nav .links li { min-width:6ch; }
.site-nav .search { flex:1; display:flex; }
.site-nav .search input { flex:1; }
</style>
<nav class="site-nav" aria-label="Primary">
<a class="brand" href="#">Brand</a>
<ul class="links">
<li><a href="#">Documentation</a></li>
<li><a href="#">Community</a></li>
<li class="search"><input type="search" placeholder="Search"></li>
</ul>
<div class="actions"><button>Sign in</button></div>
</nav>
Quick reference to core container properties
These are the container properties you will use frequently. Learn them as a set and layouts become easier to reason about.
| Property | Purpose | Typical values |
display | Enables the flex context | flex |
flex-direction | Sets main axis direction | row; column |
flex-wrap | Allows items to wrap | nowrap; wrap |
justify-content | Distributes items on main axis | flex-start; center; space-between |
align-items | Aligns items on cross axis | stretch; center; flex-start |
align-content | Distributes wrapped lines | flex-start; center; space-between |
gap | Sets consistent spacing between items | Length units such as 0.5rem |
With these fundamentals in place you can build flexible, robust components that adapt smoothly across screen sizes and content changes.