<< Home

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.

💡 Think in axes. Flexbox has a main axis and a cross axis. Alignment and spacing properties refer to one of these two directions.

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-directionMain axisCross axis
rowLeft to rightTop to bottom
row-reverseRight to leftTop to bottom
columnTop to bottomLeft to right
column-reverseBottom to topLeft 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>
⚠️ Avoid mixing 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>
💡 Prefer 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>
⚠️ Keep interactive targets large enough to tap. A comfortable minimum is around 44 by 44 CSS pixels. Flexbox aligns and spaces elements, but you still set adequate padding on the items themselves.

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.

PropertyPurposeTypical values
displayEnables the flex contextflex
flex-directionSets main axis directionrow; column
flex-wrapAllows items to wrapnowrap; wrap
justify-contentDistributes items on main axisflex-start; center; space-between
align-itemsAligns items on cross axisstretch; center; flex-start
align-contentDistributes wrapped linesflex-start; center; space-between
gapSets consistent spacing between itemsLength 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.