DEV Community

Discussion on: Responsive Navbar using HTML, CSS, and Javascript

Collapse
 
tleperou profile image
Info Comment hidden by post author - thread only visible in this permalink
Thomas Lepérou

Thanks for sharing.

Being evolving in the web industry since the very early 2000's, I'd say that dealing with navigation, is tricky. A navigation fulfils critical responsibilities:

  • it designates an informational structure to users and crawlers (SEO-able)
  • it provides a way to navigate through the information (readable)
  • it presents a certain state of the information (addressable)
  • it has a way to interact with itself (usable)
  • and might be used within different platform (interoperable)

SEO-able

Delegating the most critical part of the navigation with a div > span must be avoided. Except if you have a good reason and you provide the proper aria-attributes to take over with the right DOM's semantic.

With better semantic, better structure, better opportunities for the SEO.

addressable

The state of the nav__link.hide should be bubbled up to the top level's viewport. Why? Because the display: fixed is applied to the viewport, and become a first (depth) level of reading. As a rule of thumb, always use the URL to represent the first level of reading, eg:

Thus, the state of your main navigation is addressed within the URL. Sharing a link and refreshing the page work!

usable

I consider relying on the native navigation of the browser as one of the best practice in frontend development. Updating the the URL via a link and without using JS make things sure to work, and easy to maintain over the time.

interoperable

Nowadays, frontend developers face with complexity by coding programs executed in web browsers, webworkers and backends. Adding listeners should be done carefully, cause it's tightly coupled with the DOM's rendering (browser only).

Could be something like,

  <body>
    <header>
      <a href="/">logo</a>
      <nav>
        <ul>
          <li><a href="#">home</a></li>
          <li><a href="#">about</a></li>
          <li><a href="#">contact</a></li>
          <li><a href="#">blog</a></li>
        </ul>
      </nav>
      <a href="#open-main-nav">
        <span>Toggle main navigation</span>
        <i class="burger-icon" aria-hidden="true"></i>
      </a>
    </header>
  </body>
Enter fullscreen mode Exit fullscreen mode

For the css,

// nav when open
body.main-nav-open header > nav {}

// nav by default
header > nav {}

// links on nav
header > nav a {}

// logo
header > a:first-child {}

// button to open main nav
header > a:last-child {}

// keep visible the trigger for screen reader only
header > a:last-child span {
    position: absolute !important;
    height: 1px; width: 1px;
    overflow: hidden;
    clip: rect(1px 1px 1px 1px); /* IE 7+ support */
    clip: rect(1px, 1px, 1px, 1px); /* other browsers */
}

// your own icon's implementation (fontawesome or whatever)
// CSS-based only. DOM must not be required
i.burger-icon {}

// responsiveness
@media screen and (/* your breakpoints */) {
  header > nav > ul { /* display or not */ }
}
Enter fullscreen mode Exit fullscreen mode

Finally, the JS

const toggleNavWhenLocationAsks = () => {
  const body = document.getElementsByTagName('body')[0];

  if (location.hash === '#main-nav-open') {
    return body.classList.add('main-nav-open');
  }

  return body.classList.remove('main-nav-open');
}

// toggle nav onload
// run only when window is available
window && toggleNavWhenLocationAsks();

// toggle nav on URL changes
// run only when window is available
window && window.addEventListener('hashchange', toggleNavWhenLocationAsks);
Enter fullscreen mode Exit fullscreen mode

Best

Some comments have been hidden by the post's author - find out more