No Time Dad

A blog about web development written by a busy dad

Consistent Top Navigation Bar Spacing with Flexbox

Intro

Typically, in a top navigation bar you’ll have your app icon and app name, as well as some links to various pages of your application, and you might have some buttons like “Logout”, “Sign In”, or “Sign Up” all the way over on the right. Spacing these things out can be a little tricky. You might be tempted to just add padding or some margin between them. While that will space them out, the spacing can get awkward and clunky when you the viewport size changes.

Luckily, flexbox can help us out with the spacing. Really flexbox just takes care of it for us, and sets us up nicely if we want to make our top nav ready for small devices (e.g. hiding links and adding dropdown menus).

So in this post I’ll give an example of how you can use flexbox to create a top navigation bar with nice even spacing between your elements. We are going to assume our top nav has three elements (which seems to be the trend these days):

  1. Icon and name (start)
  2. Links (center)
  3. Alerts and buttons (end)

Spacing Things Out

As mentioned above, we’ll be creating three main sections in our top navigation bar. The nav bar itself will sit inside of a wrapper div with the class header. The html will look as follows:

<div class="header">
  <div class="header__start">Start</div>
  <div class="header__center">Center</div>
  <div class="header__end">End</div>
</div>

Now that we have a container and three elements, we need to implement flexbox in our header container. To do that we’ll add display: flex to our header css selector.

Next we’ll add justify-content: space-between to the header selector, which will put each element at the start, center, and end respectively. This little piece of magic did not require any padding or margin the elements, it just works.

Below is our css and an example of what the top nav will look like. The html remains the same from above. I added some colors from a custom color palette I created for this example.

/* Custom color palette */
:root {
  --black: #000000ff;
  --ghost-white: #f4f4f9ff;
}

.header {
  display: flex;
  justify-content: space-between;
  background-color: var(--black);
}

.header__start {
  color: var(--ghost-white);
}

.header__center {
  color: var(--ghost-white);
}

.header__end {
  color: var(--ghost-white);
}
Start
Center
End

That is pretty cool, and pretty painless. You’re probably going to want a fancier nav bar with icons and buttons and whatever else, but this little container example is an awesome starting point in my opinion.

Jazzing Things Up

Just to show some of the potenial this little nav bar has, I’ve added a few more selectors and elements to jazz up the demo a little bit. I grabbed an svg icon from heroicons, and added an app name to the header__start container. In that container I added some child elements that have their own selectors Next I added some links in the center with a simple :hover effect. The links were right on top of each other initially, so I added margin-left and margin-right to space them out a bit. Lastly, I added a user icon that doesn’t do much right now except change colors when you hover but it could be dropdown menu in the future.

You’ll notice that there are a few places where I added display: flex to the child elements for each of the three sections. This is to ensure that everything inside the sections also lines up as nicely as the parent elements do. The beauty of flexbox is that you can defined new flexboxes as children of parent flexboxes. What that means is that I could have nested justify-content.

Another important thing to note here is that I did not explicitly set a height property on the header or header_jazzy container. I let the content of the container determine the size. This will make things so much easier for responsiveness and when a content container is added later for the body of the page itself.

Below is the css, html, and jazzed up example.

/* Custom color palette */
:root {
  --black: #000000ff;
  --powder-blue: #b8dbd9ff;
  --ghost-white: #f4f4f9ff;
}

.header_jazzy {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: var(--black);
  padding-right: 1.5rem;
  padding-left: 1.5rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}

.header_jazzy__start {
  display: flex;
  align-items: center;
}

.header_jazzy__start_icon {
  width: 2rem;
  height: 2rem;
  color: var(--powder-blue);
}

.header_jazzy__start_text {
  font-size: 18px;
  color: var(--powder-blue);
  font-weight: 900;
}

.header_jazzy__center {
  display: flex;
}

.header_jazzy__center_link {
  margin-left: 0.5rem;
  margin-right: 0.5rem;
  text-decoration: none;
  color: var(--powder-blue);
  font-weight: 500;
}

.header_jazzy__center_link:hover {
  color: var(--ghost-white);
}

.header_jazzy__end_icon {
  width: 1.25rem;
  height: 1.25rem;
  color: var(--powder-blue);
}

.header_jazzy__end_icon:hover {
  color: var(--ghost-white);
}
<div class="header_jazzy">
  <div class="header_jazzy__start">
    <svg
      class="header_jazzy__start_icon"
      xmlns="http://www.w3.org/2000/svg"
      fill="none"
      viewBox="0 0 24 24"
      stroke="currentColor"
    >
      <path
        stroke-linecap="round"
        stroke-linejoin="round"
        stroke-width="2"
        d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
      />
      <path
        stroke-linecap="round"
        stroke-linejoin="round"
        stroke-width="2"
        d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
      />
    </svg>
    <div class="header_jazzy__start_text">Bored.io</div>
  </div>
  <div class="header_jazzy__center">
    <a href="#solutions" class="header_jazzy__center_link"> Solutions </a>
    <a href="#pricing" class="header_jazzy__center_link"> Pricing </a>
  </div>
  <div class="header_jazzy__end">
    <a href="#profile">
      <svg
        class="header_jazzy__end_icon"
        xmlns="http://www.w3.org/2000/svg"
        fill="none"
        viewBox="0 0 24 24"
        stroke="currentColor"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
        />
      </svg>
    </a>
  </div>
</div>