#15DaysOfCSS Day 7: Horizontal navbars with Flexbox

Simple, clean, and horizontal

Now that we've covered some basic CSS styling concepts (and some navbar concepts along the way), let's move on to horizontal navbars.

Horizontal bars have been challenging through the years, particularly with responsive design in mind. However, with the rise of Flexbox, nothing could be easier to lay out than a horizontal navbar.

Does the HTML change with a horizontal navbar?

Follow along with today’s CodePen example

Nope. Same HTML we've worked with to this point:

<nav class="example1">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Products</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>

Start with our boilerplate navbar styling

Follow along with today’s CodePen example

Regardless of what kind of navbar you want to make, you'll probably want to add the standard styling. It's pretty much the same stuff: turn off default bullets and spacing, make BIG CLICKABLE AREAS, and change or assign some colors.

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}
a {
  color: #3867d6;
  display: block;
}
a:hover {
  background-color: #fed330;
  text-decoration: none;
}

Flexbox is all about parents and children

Follow along with today's CodePen example

The secret to understanding Flexbox is understanding parents and children. Which element becomes our series of boxes? Which element is the container?

In the case of the navbar, the container or parent is the ul element, while the items or children are the li elements.

Once you've got that identified, there's a simple formula that will work 99% of the time.

ul {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
}

The first two declarations mean we'll put the navigation items in a horizontal bar which will wrap to the next line if needed, via Flexbox.

The only item that may need to be modified is the justify-content property. This property controls how boxes and space are distributed within the row. The center property will, shockingly, center the boxes within the row. Other properties that may be helpful include flex-start (left-aligned), flex-end (right-aligned), space-between (justified), or space-evenly (even spacing around the boxes within the navbar).

In this case, aligning the boxes in the center mean the links are touching, they're so close.

However, with the new gap property that works with Flexbox, we can easily assign some space between our links. Best of all, it won't stick extra space on the ends of the bar. Our final CSS looks like this:

.example1 ul {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  gap: 1rem;
}

And our final simple text navbar looks like this:

Next-level styling

From here, add colors, turn off underlines, add an interesting font, add a background color on hover, and you'll have a much more interesting navbar.

For example, here I've changed colors, fonts, added borders, and so forth - all kinds of pretty things! Check Example 2 in today’s example CodePen for the details.

The most interesting point is this:

.example2 ul {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
}
.example2 a {
  padding: 1rem;
}

Why did Jen include padding on the a style instead of gap on the ul style?

Great question!

gap behaves more like margin in CSS. It has no background color that may be associated with it. Therefore, if you want your hover state to have a little space around it in its contrasting color, padding is a better choice than gap in this situation. Otherwise, the background hover color will be right against the letters in the navigation button.

You should experiment in today's CodePen, though -- try removing padding and switching to gap for space between links. What do you like better from a design perspective?

Navbars with "pipes"

Navbars with a "pipe" character | separating links remains a popular option today, particularly in footer navigation. Can we achieve that with Flexbox and our same old HTML? Sure! No need to type pipe characters, either. All of the code is in Example 3 in today’s CodePen:

.example3 ul {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  gap: 1rem;
}
.example3 li + li {
  border-left: 2px #000 solid;
  padding-left: 1rem;
}

Uh oh, more selector craziness! 🤯

Always remember, when working in CSS, write your CSS from left to right, but read it from right to left.

In the .example3 ul style, we've set the gap to 1rem, which will place 1rem between each <li> element.

In the .example3 li + li style, we're saying "for any <li> element that's immediately adjacent to a <li> element, descended from .example3, assign these characteristics." The + is the adjacent sibling selector. Here it's looking for a <li> following a <li>.

Why do that? Because with our first <li>, we do NOT want a | to start our navigation. This starts the | with our second navigation item. By placing the border on the left, we don't have to worry about the last navigation item getting a line next to it, as we would if we placed the border on the right. Spiffy!

Why padding AND gap? Gap acts like margin. If you placed a full border around each <li> element, you'd find the gap goes in between the boxes. Padding gives us space between the border and the content on the left, while gap manages the space on the right.

(You may be able to put padding on the right instead of using gap, but you'd need another declaration for that. Can you figure out why this is?)

Wait, that’s a border, not a character! Yes! Why type characters when there’s a reasonable alternative? Also, maybe there’s a consequence with screen readers. We are not experts in this area, and the only reference we could find to screen readers and “pipes” is from 2008. At that time, some readers would say “vertical bar” for each pipe character — how annoying! If anyone has updated information about screen readers and pipes, we’d love to hear about it.

🎉📚Get the #15DaysOfCSS e-book📚🎉

These #15DaysOfCSS posts will be compiled into an e-book — pre-order now!

Email is great, and blogs are awesome, but it can be challenging to use them as a reference in the future. We'll be assembling this month's work into an e-book.

Pre-order the book

🖥 Today’s CodePen examples

Today’s CodePen examples map out the code described in this email.

Today's CodePen Examples

👩🏽‍💻 Challenge: Make your own horizontal navbar

👩🏽‍💻 Today’s challenge features a list of sources for free fonts and great font pairs (two fonts that look good together). Get your designer hat on and make us some beautiful navbars!

Take the CodePen Challenge

📚 More information and examples

📚 MDN: Adjacent sibling selector

📚 CSS Tricks: Minding the Gap

📚 CSS Tricks: A complete guide to Flexbox

📽 LinkedIn Learning: CSS Selectors (subscription required)

📽 Flexbox and Grid version 2 at Frontend Masters (subscription required)