CSS project 2b, centering the menu links and the logo
"How do I center this?" comes up in CSS more than almost any other question, because there is no single answer. What you use depends on what kind of box you are centering. The header from the previous lesson has two things that need it, and they happen to need two different tools: the menu, which is a flex container, and the logo, which is an inline link.
At this point the band shows the logo on its own line at the left and the row of menu links below it, also at the left. The goal of this lesson is a centered header: logo in the middle, menu centered underneath.
The menu: justify-content
In a flex container, the children are laid out along a main axis, which is horizontal for a normal row. Any space left over on that axis is free space, and justify-content decides where it goes. The default behaves like flex-start and puts all of it after the last item, so the links pack to the left. center splits it in half and puts one half on each side.
Add one line to the .menu rule:
.menu {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 8px;
margin: 0;
padding: 0;
list-style: none;
}
Because flex-wrap is on, a narrow window can push the menu onto two rows. Each row gets centered on its own, so a lone link on the second row sits in the middle rather than hanging off to the left.
The logo: text-align
The logo is an <a> element, and links are inline. Inline content lives inside line boxes, the same way words do in a paragraph, and the property that moves content within a line box is text-align. It goes on the parent block, not on the inline element itself:
.site-header {
padding: 16px 24px;
background-color: #1d3b53;
color: #ffffff;
border-bottom: 4px solid #f2c14e;
text-align: center;
}
Setting text-align: center on the logo would do nothing, since an inline element is only as wide as its text and has no room to center anything in. On the header, it centers every line of inline content in the band, which here means the site name.
text-align is also inherited, so it flows down into the nav, the list and the links. It does not move the list items, though. Flex items are not inline content, so text-align has no say over where they sit; it only affects the text inside each one. That is why the menu needs justify-content and the logo needs text-align, even though both live in the same header.
If you had built the menu the older way, with display: inline-block on the list items as described in the last lesson, then text-align: center on the <ul> would center them. Inline-block items are inline content, just like words.
Which tool for which job
A short guide you can come back to:
- Text, links, images and inline-block elements inside a block:
text-align: centeron the block that contains them. - Children of a flex container, along the row:
justify-content: centeron the container. Across the row, vertically in a normal header,align-items: center, which lesson 20 uses. - A block box with a set width, such as a content column with
max-width: 960px:margin-left: autoandmargin-right: auto(or the shorthandmargin: 0 auto), which share the leftover space equally. The margin lesson explains how the shorthand values map to each side.
When something will not center, ask first what kind of box it is. Most failed attempts use the right property on the wrong element, like text-align on a flex container's children or justify-content on something that is not a flex container.
Other ways to share the free space
center is one of several values. These are worth knowing before the next two lessons:
.menu { justify-content: flex-start; } /* all items at the start, like the default */
.menu { justify-content: flex-end; } /* all items at the end */
.menu { justify-content: space-between; } /* first and last at the edges, rest spread between */
.menu { justify-content: space-evenly; } /* equal space around every item, edges included */
Lesson 20 uses space-between on the whole header to push the logo and the menu apart. When it does, the header becomes a row, and the two centering lines from this lesson stop having a visible effect on wide screens, because the logo and the menu are each exactly as wide as their content and there is no space left to share. They stay in the stylesheet anyway. On a phone the header stacks again, and if the menu wraps onto two rows, the centering keeps both rows tidy.
Try it
In the online HTML editor, with the project CSS in a <style> element as before, add justify-content: center and text-align: center. Then try each justify-content value above on .menu and narrow the window to watch the wrapped rows. Move text-align: center from .site-header to .logo to see it do nothing at all.