Search code examples
javascripthtmlcsssassnav

Why can't I target the nav for a drop down transition?


I am trying to get a transition to activate when the burger menu is clicked. My javascript, and css work for everything but creating a slow nav drop down transition from top to bottom.

Trying to find an answer online has led me to many different ways of creating a transition. So I am lost on that, if there is a standard way to do this please assist me. Not trying to be lazy but I have seen 5 different ways. Not sure what i need to target in my css. Thank you

<header>
  <button class="hamburger hamburger--squeeze" type="button">
    <span class="hamburger-box">
        <span class="hamburger-inner"></span>
    </span>
  </button>
  <img class="header-logo" src="/logo/piancavallo-logo.svg" alt="">
  <nav>
    <ul class="nav-links">
      <li><a href="index.html">home</a></li>
      <li><a href="shop.html">shop</a></li>
      <li><a href="sport.html">sport</a></li>
      <li><a href="read.html">read</a></li>
      <li><a href="about.html">about</a></li>
    </ul>
  </nav>
  <img class="search-icon" src="/logo/search-icon.svg" alt="">
  <img class="shopping-cart" src="/logo/shopping-cart.svg" alt="">
</header>
nav {
  position: absolute;
  text-align: left;
  top: 100%;
  left: 0;
}
nav .nav-links {
  display: none;
  background-color: orange;
  font-size: 1.4rem;
  position: absolute;
  width: 100vw;
}
nav .nav-active {
  display: block;
}
nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav li {
  margin: 5px;
  padding: 5px;
}
nav a {
  text-decoration: none;
  color: green;
  font-weight: 700;
}
nav ul {
  -webkit-transition: height 1s ease-in;
  transition: height 1s ease-in;
}
const revealNav = () => {
  const hamburger = document.querySelector('.hamburger');
  const nav = document.querySelector('.nav-links');

  hamburger.addEventListener('click', () => {
    hamburger.classList.toggle('is-active');
  }, false);

  hamburger.addEventListener('click', () => {
    nav.classList.toggle('nav-active');
  });
}

revealNav();

Solution

  • As far as I know there isn't a standard or better way to do this, it very much depends on the visual effect you are trying to achieve.

    I have a solution here and I have stripped out most of the CSS that is not needed for the top/bottom transition.

    I also have a jump in opacity that may be helpful while developing as it shows you exactly when the class is added or removed.

    const revealNav = () => {
      const hamburger = document.querySelector('.hamburger');
      const nav = document.querySelector('.nav-links');
    
      hamburger.addEventListener('click', () => {
        nav.classList.toggle('is-active');
      });
    }
    
    revealNav();
    nav {
      overflow: hidden;
    }
    
    .nav-links {
      opacity: 1; /* only to show when class is added */
      background-color: orange;
      margin: 0;
      padding: 0;
      list-style: none;
      transition: transform 1s;
      transform: translateY(-100%);
    }
    
    .nav-links.is-active {
      opacity: 1; /* only to show when class is added */
      transform: translateY(0);
    }
    <header>
      <button class="hamburger hamburger--squeeze" type="button">
        <span class="hamburger-box">
            <span class="hamburger-inner">hamburger</span>
        </span>
      </button>
      <nav>
        <ul class="nav-links">
          <li><a href="index.html">home</a></li>
          <li><a href="shop.html">shop</a></li>
          <li><a href="sport.html">sport</a></li>
          <li><a href="read.html">read</a></li>
          <li><a href="about.html">about</a></li>
        </ul>
      </nav>
    </header>