Course outline · 0% complete

0/30 lessons0%

Course overview →

Build a real navbar, step by step

lesson 6-3 · ~8 min · 20/30

Step 1: semantic markup

Every layout starts with meaning, as lesson 3-3 established, rather than with looks.

<header class="site-header">
  <a class="logo" href="/">Hack U</a>
  <nav class="site-nav">
    <a href="/courses">Courses</a>
    <a href="/dsa">DSA</a>
    <a href="/apply">Apply</a>
  </nav>
</header>
ElementDefault displayResult unstyled
headerblockfull-width band
navblockdrops below the logo
ainlinelinks sit on one line

Unstyled, this renders awkwardly, with the nav on its own line below the logo. Flexbox fixes it at two levels, which is the point of the next step.

Step 2: two flex containers

.site-header {
  display: flex;
  justify-content: space-between; /* logo left, nav right */
  align-items: center;            /* vertical centering */
  padding: 12px 24px;
}

.site-nav {
  display: flex;
  gap: 24px;                      /* even spacing between links */
}
ContainerIts flex itemsJob
.site-headerthe logo and the navpush them to opposite ends
.site-navthe three linksspace them evenly

Read with the axis model from lesson 6-1, the header pushes logo and nav to opposite ends of its main axis, and the nav is itself a flex container spacing its links with gap.

Nesting flex containers like this is how most real headers, cards, and toolbars are built. The nav is simultaneously an item of the outer container and a container for its own children, which is the composition that makes flexbox scale.

One more line helps on small screens, since flex-wrap: wrap; lets items break onto a second line instead of overflowing.

The most common layout on the web

A logo on the left, navigation on the right, both vertically centered.

CSS

body { font-family: sans-serif; margin: 0; }

.site-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 24px;
  border-bottom: 2px solid #d4af37;
}

.site-nav {
  display: flex;
  gap: 24px;
}

.logo { font-weight: bold; text-decoration: none; color: black; }
.site-nav a { text-decoration: none; color: black; }
SelectorDeclarations that matterEffect
.site-headerdisplay: flex, justify-content: space-between, align-items: centerlogo and nav at opposite ends, centered
.site-navdisplay: flex, gap: 24pxlinks in a row, evenly spaced

space-between pushes the first and last children to opposite ends and puts all the leftover space between them, while align-items: center lines them up on the same invisible middle line.

If the links still stack vertically, the missing declaration is display: flex on .site-nav. That is the single most common cause, because the outer container being flex says nothing about how its children lay out their own contents.

What space-between does in the header

In .site-header, justify-content: space-between pins the logo to the left edge and the nav to the right edge.

With exactly two flex items, space-between pushes them to opposite ends of the main axis, which is exactly the logo-left, menu-right shape of most sites.

Item countWhere the space goes
twoall of it between the pair
threesplit into two equal gaps

The 24px between individual links comes from the nav's own gap rather than from the header, which is the practical payoff of nesting the two containers.

Letting items wrap

The container property that lets flex items break onto a new line is flex-wrap: wrap.

By default a flex row squeezes everything onto one line, shrinking items or overflowing the container. With wrapping enabled, items that no longer fit move to the next line.

ValueBehavior when items do not fit
nowrapstay on one line, shrink or overflow
wrapmove onto new lines

The property name says exactly what the items do, which makes it easy to remember. On a nav with many links it is often the only change needed to make a header usable on a phone.