Search code examples
reactjssassnavbartransitionstyling

Transitions is not working on my responsive navbar component


I have this navbar component, here is an image of it on a mobile view: enter image description here My question is, I cannot see a transition when clicking the hamburger menu to show the ul, I do not see it despite adding the transition on the ul itself, it just pops up immediately.

For reference, here is my Navbar.jsx

import React, {useState} from 'react'
import "../App.scss"
import { FaBars, FaTimes } from 'react-icons/fa';

const Navbar = () => {

const [isOpen, setIsOpen] = useState(false);
const toggleNav = () => {
    setIsOpen(!isOpen);
};
  return (
    <nav className="wrapper">
     <div className="navbar">
        <a href="/#" className="logo">LOGO</a>
        <div className= {`nav-links ${isOpen && "show"}`}>
            <ul>
                <li><a href="/#">Home</a></li>
                <li><a href="/#">About</a></li>
                <li><a href="/#">Services</a></li>
                <li><a href="/#">Contact</a></li>
            </ul>
        </div>
        <div className="nav-toggle" onClick={toggleNav}>
                {isOpen ? <FaTimes /> : <FaBars />}
        </div>
     </div>
    </nav>
  )
}

export default Navbar

And here is my SCSS

*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  list-style-type: none;
  text-decoration: none ;
}.wrapper{
  width: 100%;
  height: 90px;
  background: #333;
  z-index: 1;
  transition: 0.5s ease-in;
}

.navbar{
  width: 80%;
  margin-inline: auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  text-align: center;
  padding: 1em 0;

  .logo{
    font-size: 3rem;
  }

  .nav-toggle{
    display: none;
    background-color: transparent;
    border: none;
    color: #FFF;
    font-size: 2rem;
  }

  .nav-links ul{
    display: flex;
    gap: 2em;

    li{
      font-size: 1.5rem;

      a{
        color: #fff;
      }
    }
  }

  @media screen and (max-width: 768px){
    .nav-links ul{
      display: none;
    }

    .nav-links.show ul{
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 90vh;
      position: absolute;
      top: 90px;
      left: 0;
      background-color: antiquewhite;
      transition: 1s ease-in-out;
      a{
        color: red;
        font-size: 2rem;
      }
    }

    .nav-toggle{
      display: block;
    }

  }
}//end of navbar

I have tried to debug it and I have noticed something:

.nav-links.show ul{
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 90vh;
      position: absolute;
      top: 90px;
      left: 0;
      background-color: antiquewhite;
      transition: 4s ease-in-out;

      a{
        color: red;
        font-size: 2rem;
      }
    }

If I change the top: 90px to top: 100% while monitoring the changes, the transitions seems to work. Undoing it again back to top: 90px seems to do nothing. So I thought, maybe adding: top: -100% on .nav-links ul will do the trick but unfortunately still no. So I tried to debug again and noticed that given the addition top: -100%, if I try to remove top: 90px-> save it, then add it again, the transition work. I'm confused, what do I have to do?


Solution

  • Transitions on display property don't work in CSS. In order to achieve the similar result, use the opacity property and set height to zero instead.

    For example:

    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      list-style-type: none;
      text-decoration: none ;
    }.wrapper{
      width: 100%;
      height: 90px;
      background: #333;
      z-index: 1;
      transition: 0.5s ease-in;
    }
    
    .navbar{
      width: 80%;
      margin-inline: auto;
      display: flex;
      justify-content: space-between;
      align-items: center;
      text-align: center;
      padding: 1em 0;
    
      .logo{
        font-size: 3rem;
      }
    
      .nav-toggle{
        display: none;
        background-color: transparent;
        border: none;
        color: #FFF;
        font-size: 2rem;
      }
    
      .nav-links ul{
        display: flex;
        gap: 2em;
    
        li{
          font-size: 1.5rem;
    
          a{
            color: #fff;
          }
        }
      }
    
      @media screen and (max-width: 768px){
        .nav-links ul{
          // set height and opacity to zero
          height: 0;
          // to prevent overflowing
          overflow: hidden;
          opacity: 0;
        }
    
        .nav-links.show ul{
          // set height and opacity back
          height: auto;
          opacity: 1;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          width: 100%;
          height: 90vh;
          position: absolute;
          top: 90px;
          left: 0;
          background-color: antiquewhite;
          transition: 1s ease-in-out;
          a{
            color: red;
            font-size: 2rem;
          }
        }
    
        .nav-toggle{
          display: block;
        }
    
      }
    }//end of navbar
    

    Learn more: Transitions on the CSS display property.