CSS project 2d, moving the menu to the right and stacking it on small screens
Up to now the header has been a centered stack: site name on top, menu below. Most sites put the two side by side, name on the left and menu on the right, which keeps the band short and leaves more of the screen for content. This lesson makes that switch with flexbox on the header itself, then adds a media query so the header stacks again when the screen gets too narrow for one row.
Make the header a flex container
The header has exactly two children, the logo link and the nav:
<header class="site-header">
<a class="logo" href="index.html">Bench Notes</a>
<nav class="main-nav" aria-label="Main">
<!-- the menu list from lesson 16 -->
</nav>
</header>
That is all flexbox needs. Update the .site-header rule so it reads like this, and add the media query at the very end of style.css:
.site-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 16px 24px;
background-color: #1d3b53;
color: #ffffff;
border-bottom: 4px solid #f2c14e;
text-align: center;
}
@media (max-width: 600px) {
.site-header {
flex-direction: column;
gap: 8px;
}
}
display: flex puts the logo and the nav in a row. justify-content: space-between, which you saw at the end of the centering lesson, places the first item at the start and the last at the end, with all the free space between them. With two items, that means logo left, menu right. align-items: center lines them up vertically on the middle of the band, so the larger logo text and the padded menu links share a center line instead of both hugging the top. The gap keeps at least 16 pixels between them if the window gets tight.
The text-align: center from lesson 18 stays. In this row layout it has nothing to do, and that is fine; it matters again below.
The other way: an auto margin
You can get the same result without space-between:
.site-header {
display: flex;
align-items: center;
}
.main-nav {
margin-left: auto;
}
In a flex container, an auto margin takes up all the free space on its side. A left margin of auto on the nav pushes it as far right as it can go. It is the same trick as margin: 0 auto for centering a block with a set width, where both sides split the leftover space; here only one side is auto, so it takes all of it. Margins in general are covered in the margin lesson.
The two approaches look identical with two items. They differ when you add a third. Say you later put a search box after the nav. With space-between, the three items spread out and the menu lands in the middle. With margin-left: auto on the nav, the logo stays left and the nav and search box sit together on the right. For this project, space-between is enough. If you write right-to-left languages too, margin-inline-start: auto is the version that flips with the text direction.
Stacking on small screens
On a narrow screen, the logo and four links no longer fit in one row. Without the media query, the nav shrinks and its links wrap into a cramped block beside the logo. The media query above changes the rules below 600 pixels:
@media (max-width: 600px)applies its rules only while the viewport is 600 pixels wide or less. Current browsers also accept the shorter range form,@media (width <= 600px), which means the same thing.flex-direction: columnturns the row into a column, so the logo sits on top and the nav below.- In a column, the cross axis runs left to right, so the
align-items: centeralready on the header now centers both items horizontally. If the menu still has to wrap onto two rows on a very small phone, thejustify-content: centeron.menufrom lesson 18 centers each row, andtext-align: centerkeeps a long site name centered if it wraps.
Why 600? With a typical system font, this logo and these four links need a little over 500 pixels to sit in one row, padding included, so 600 switches to the stacked layout before the row gets tight. Yours may differ with a longer site name or more links. Narrow the window slowly, note the width where the row starts to look cramped, and use a number a little above that.
When it does not work
A short list of the usual causes:
- Nothing moved.
display: flexwent on.menuor.main-navinstead of.site-header.justify-contentonly arranges the direct children of the element it is set on. - Both items are still at the left. The header has only one child. Check that the logo is not inside the nav, and that the two are not wrapped together in an extra div. With a single item,
space-betweenhas nothing to spread. - The menu sits higher or lower than the logo.
align-items: centeris missing from the header rule. - The media query never applies. If it fails on a real phone, the viewport meta tag is missing from the
<head>, so the phone lays the page out on a wide virtual screen and never reaches 600 pixels. If it fails in a narrow desktop window, the media query is probably above the main.site-headerrule. A media query adds no weight to a selector, so the later rule wins; keep media queries at the end. - The header is stacked on a wide screen. You wrote
min-widthwhere you meantmax-width.
Try it
Load the project in the online HTML editor with the CSS in a <style> element, update .site-header, and add the media query at the end of the style block. Then make your browser window narrower. The media query measures the preview frame, not your whole screen, so the header stacks once the preview itself drops under 600 pixels. Try the margin-left: auto version too, and the final code lesson puts every rule together.