A Live Developer Journal

Building navigation menu with progress bar

I am spending most of today improving my website. I released it initially as a raw, text-only HTML site, and am slowly improving the design live in real time. This is so that I could share content without having to wait for the design to be 'finished'. Another benefit of this approach is that I get to show you how I'm designing and building out all of the new features.

Today I'm documenting my process for building the following navigation menu:

navigation menu

Raw HTML for the navigation menu


<nav class="navigation">

  <ul class="social-media">
    <li class="social-media__icon" title="github">
      <a href="https://github.com/Becca9941" target="_blank"><i class="fab fa-github"></i></a>
    </li>
    <li class="social-media__icon" title="codepen">
      <a href="https://codepen.io/Becca941" target="_blank"><i class="fab fa-codepen"></i></a>
    </li>
    <li class="social-media__icon" title="twitter">
      <a href="https://twitter.com/Becca9941" target="_blank"><i class="fab fa-twitter"></i></a>
    </li>
    <li class="social-media__icon" title="instagram">
      <a href="https://www.instagram.com/becca99941/" target="_blank"><i class="fab fa-instagram"></i></a>
    </li>
  </ul>

  <a href="/">
    <img class="logo" src="/assets/img/devbecca.svg" alt="">
  </a>

  <button class="show-site-links">MENU</button>

  <nav class="site-menu hidden">
    <li><a href="/">Home</a></li>
    <li><a href="/about.html">About</a></li>
  </nav>

</nav>

Navigation menus are mini programs in themselves. This navigation menu is composed of a list of social media icons (the hash symbols will be replaced with the links to each site), a logo, a button that opens another navigation menu which contains the site links.

I also used the title attribute on the icon list items. This is so that a small tooltip will show up explaining what the icon is for when you hover over it.

Styling the social media icons

The first step to styling the social media icons is to create a new sass file called 'social-media.scss' in a folder called 'components' inside of the 'sass' directory.

I imported the social media file into the 'main.scss' sass file like this: "@import 'components/social-media';"

This is the css for styling the social media icons:


.social-media {
  width: max-content;
  padding: 0; margin: 0;

  li {
    list-style-type: none;

    &:first-child:hover a { color: $mint; }
    &:nth-child(2):hover a { color: $pink; }
    &:nth-child(3):hover a { color: $blue; }
    &:last-child:hover a { color: $orange; }
  }

  a {
    text-decoration: none;
    color: $brand-grey;

    &:hover { background: none; }

  }

  &__icon {
    display: inline-block;
    font-size: 2rem;

    &:not(:last-child) {
      margin-right: .5rem;
    }

  }

}

social media icons

Hiding the site menu

To hide the site menu, I added a class called 'hidden' to the 'site-menu' navigation which contains the links to main pages in the site. Then I created a css file that applies sitewide called 'sass/base/_sitewide.css'. I added the hidden class selector to this file which sets the display to none.

Positioning elements inside navigation menu

The following CSS positions the elements inside the navigation menu.


.navigation {
  display: flex;
  justify-content: space-between;
  position: sticky;
  top: 0;
  background-color: white;

  a {
    background: none;
  }

  .logo {
    width: 7rem;
  }

  .show-site-links {
    background-color: white;
    border: none;
    outline: transparent;
    text-transform: uppercase;
    font-size: 1.5rem;
    font-weight: bold;
    height: 1.5rem;
    cursor: pointer;

    &:hover span:first-child { color: $mint; }
    &:hover span:nth-child(2) { color: $pink; }
    &:hover span:nth-child(3) { color: $blue; }
    &:hover span:last-child { color: $orange; }
  }
}

Adding the progress bar

The progress bar is inspired by this tutorial.

HTML


  <article class="progress">
    <section class="bar"></section>
  </article>

CSS


 .progress {
   position: absolute;
   bottom: 0;
   width: 100%;
   background-color: rgba($brand-grey, .1);

   .bar {
     width: 1%;
     height: 4px;
     background: repeating-linear-gradient(
       45deg,
       white,
       white, 4px,
       $brand-purple 4px,
       $brand-purple 8px,
     );
   }
 }

JS


 window.onscroll = function() { progressBar() };

 function progressBar() {
   const distanceFromTop = document.body.scrollTop || document.documentElement.scrollTop;
   const pageHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
   const progressBarWidth = (distanceFromTop / pageHeight) * 100;
   document.querySelector('.bar').style.width = progressBarWidth + '%';
 }

A few final improvements

Mobile Responsive

Completely forgot to make my navigation bar mobile responsive, that is fixed now.

Navigation.scss


@media only screen and (max-width: 600px) {
  .navigation {
    height: 5rem;

    .logo {
      width: 5rem;
    }

    .show-site-links {
      font-size: 1.3rem;
    }
  }
}

Social-media.scss


@media only screen and (max-width: 600px) {
  .social-media__icon {
    font-size: 1.3rem;

    &:not(:last-child) {
      margin-right: .2rem;
    }
  }
}

That's it for the navigation menu. In the next post, I'll document my process for showing/hiding the pop-up menu of site links when you click on the menu button.