Navbar dropdown animation not working

Navbar dropdown animation not working
0

I am trying to implement an animation when the navigation appears (slide down). I set the height properties on the @keyframe but it does not work.

Here is my HTML code:

<header class="header">
        <div class="header--one">
            <div class="header__logo-box">
                <a class="header__logo">myBlog</a>
            </div>
            <i class="header__navtoggle fa fa-bars"></i>
        </div>
        <div class="header--two">
            <nav class="header__nav">
                <a href="#" class="header__nav-item">Link 1</a>
                <a href="#" class="header__nav-item">Link 2</a>
                <a href="#" class="header__nav-item">Link 3</a>
            </nav>
        </div>
    </header>

Here is my SCSS code:

@import url('https://fonts.googleapis.com/css?family=Roboto+Slab:400,700&display=swap');

*,*::before,*::after{
    box-sizing: inherit;
    margin: 0;
    padding: 0;
}

html{
    font-size: 62.5%;
}

body{
    box-sizing: border-box;
    color: #777;
    font-family: 'Roboto Slab', serif;
    background:#f2f2f2;
}


.header{
    background:#333;
    display:flex;
    font-size:2.4rem;
    color:#999;

    &--one{
        flex:1;
        display:flex;
        align-items:center;
    }

    &--two{
        overflow:hidden;

    }

    &__logo-box{
        flex:1;
    }

    &__logo{
        display:block;
        padding:1rem;
    }

    &__navtoggle{
        display:block;
        padding:1rem;
        cursor:pointer;
    }

    &__nav{
        display:flex;
    }

    &__nav-item{
        display:block;
        padding:1rem;
        border-left:.8px solid #000;
        text-decoration:none;
        color:inherit;
        transition:.3s all;

        &:hover{
            background:#bca64b;
            color:#333;
        }
    }
}


@media(max-width: 650px){
    .header{
        flex-direction:column;

        &__nav{
            flex-direction:column;
        }

        &--one{
            border-bottom:1px solid #000;
        }

        &--two{
            background:#444;
            display:none;
            animation:slideDown .5s ease-out;
        }

        &--two.show{
            display:block;
        }
    }



}


@media(min-width: 651px){

    .header{

        align-items: center;

        &__navtoggle{
            display:none;
        }
    }

}

@keyframes slideDown{
    from{height:0;opacity:0;}
    to{height:100%;opacity:1;}
}

Here is my JS:

document.querySelector('.header__navtoggle').addEventListener('click',()=>{

            document.querySelector('.header--two').classList.toggle('show');

        });

What if you used a transition instead?

SCSS

@media (max-width: 650px) {
    .
    .
    .

    &--two {
      background: #444;
      opacity: 0;
      max-height: 0;
      overflow: hidden;
    }

    &--two.show {
      opacity: 1;
      max-height: 500px;
      transition: all .5s ease-out;
    }
  }
}

The max-height: 500px is just an arbitrary number which needs to be at least the height which would show all the content of the dropdown menu. You could make it 2000px if you wanted and it will not change anything. However, if you made it say 150px, then it would not be tall enough to show all the content.

1 Like

I was just whipping something in CodePen with transitions. Totally agree here.

@RandellDawson it is still not sliding down in a sliding motion

It seems like a sliding motion to me. Try changing the max-height to 300px and see if that makes it appear more like it is sliding down. Also, change the transition time from .5s to 1s which might make it more apparent.

Can you put your current code into Codepen so we can see exactly what you have?

1 Like

@RandellDawson here ya go…

https://codepen.io/hjb1694/pen/zQdWvO

For some reason, the navigation toggle is showing on full screen on codepen, yet this does not happen in the browser. I don’t know why.

Here’s the code:

&--two.show{
    position: absolute;
    width: 100%;
    top: 9%;
    height: 300px;
    animation: slideDown .3s ease-in-out;
}

@keyframes slideDown{
  
     from {
       height: 0px;
   } 
      to{
        height: 300px;
   }

}

I put show class position to absolute because each time it toggled, it affected the elements in the main tag

It’s because the initial property and the property being transitioned are not the same. I would also add a transition on the initial state so it transitions back to the closed state.

@media (max-width: 650px) {
  .header {
    flex-direction: column;

    &__nav {
      flex-direction: column;
    }

    &--one {
      border-bottom: 1px solid #000;
    }

    &--two {
      background: #444;
      height: 0;
      opacity: 0;
      transition: 1s all ease-out;
    }

    &--two.show {
      height: 30rem;
      opacity: 1;
      transition: 1s all ease-out;
    }
  }
}

BTW, one and two are not very good modifier names.