Search code examples
javascripthtmlcsshamburger-menu

Navigation - Burger Icon not transforming. Possible CSS or JS error


I'm currently working on a site and am trying to flair the navigation up with a snippet of JS code, I just want a (as you can see in the CSS) transform in degrees of the .line-top class and .line-bottom class, and at the same time make the .line-middle class have an opacity of 0; but for some reason the transformation won't change. I believe it could be something to do with the CSS section: .line-top.is-open, .line-middle.is-open and .line-bottom.is-open and the .is-closed part, maybe the JS can't call it, or its not coded in correctly to understand the animation: line-top-out 600ms linear normal; animation-fill-mode: forwards; part of the code. Code Below:

HTML:

   <div class="container_button_small">
    <div class="line-top"></div>
    <div class="line-middle"></div>
    <div class="line-bottom"></div>
   </div>

CSS:

.container_button_small {
  position: relative;
  height: 16px;
  width: 20px;
 cursor: pointer;
}


.line-top, .line-middle, .line-bottom {
    position: absolute;
    display: block;
    height: 2px;
    width: 20px;
    border-radius: 2px;
    background: #fff;
}

 .line-top {
   top: 0;
   transform-origin: 18px 1px;
 }

 .line-middle {
    top: 7px;
    transition: opacity 200ms linear;
 }

  .line-bottom {
    bottom: 0;
   transform-origin: 18px 1px;
 }



  .line-top.is-open {

     animation: line-top-out 600ms linear normal;
     animation-fill-mode: forwards;
  }

   .line-middle.is-open {
      opacity: 0;
   }

    .line-bottom.is-open {
       animation: line-bot-out 600ms linear normal;
       animation-fill-mode: forwards;
   }


    .line-top.is-closed {
       animation: line-top-in 600ms linear normal;
       animation-fill-mode: forwards;
   }

    .line-middle.is-closed {
       transition-delay: 200ms;
   }

    .line-bottom.is-closed {
       animation: line-bot-in 600ms linear normal;
       animation-fill-mode: forwards;
    }


     @keyframes line-top-in {
       0% {
       left: -5px;
       bot: 0;
      transform: rotate(-45deg);
     }
      20% {
      left: -5px;
      bot: 0;
      transform: rotate(-60deg);
     }
      80% {
      left: 0;
      bot: 0;
      transform: rotate(15deg);
      }
      100% {
        left: 0;
        bot: 1px;
       transform: rotate(0deg);
       }
     }

     @keyframes line-top-out {
       0% {
          left: 0;
          top: 0;
          transform: rotate(0deg);
       }
       20% {
        left: 0;
        top: 0;
        transform: rotate(15deg);
        }
        80% {
        left: -5px;
        top: 0;
        transform: rotate(-60deg);
         }
        100% {
        left: -5px;
        top: 1px;
       transform: rotate(-45deg);
         }
       }

      @keyframes line-bot-in {
       0% {
         left: -5px;
         transform: rotate(45deg);
          }
       20% {
         left: -5px;
         bot: 0;
         transform: rotate(60deg);
           }
       80% {
        left: 0;
        bot: 0;
        transform: rotate(-15deg);
           }
       100% {
        left: 0;
        transform: rotate(0deg);
       }
     }

     @keyframes line-bot-out {
       0% {
         left: 0;
         transform: rotate(0deg);
          }
       20% {
         left: 0;
         transform: rotate(-15deg);
            }
       80% {
         left: -5px;
         transform: rotate(60deg);
           }
       100% {
         left: -5px;
         transform: rotate(45deg);
        }
      }

JS:

    $(function() {
     $("container_button_small").on("click", function() {
       var that = $(this);    
    if (that.hasClass("is-open")) {
     that.removeClass("is-open").addClass("is-closed");      
    } else {
       that.removeClass("is-closed").addClass("is-open");      
           }    
   });
});



 

Solution

  • There's a typo in the classname and the selector on which the classes are changed are wrong; it should be done on the .line- classes and not the container. This is because in the CSS, the .is-open and .is-closed classes are attached with the .line- classes and not the container class.

    $(function() {
        var lines = $('.line-top, .line-middle, .line-bottom');
        $(".container_button_small").on("click", function() {
            var that = $(this);
            if (lines.hasClass("is-open")) {
                lines.removeClass("is-open").addClass("is-closed");
            } else {
                lines.removeClass("is-closed").addClass("is-open");
            }
        });
    });
    

    Link to JSFiddle

    You can also avoid the 'this' hack by using an arrow function:

    $(function() {
        var lines = $('.line-top, .line-middle, .line-bottom');
        $(".container_button_small").on("click", () => {
            //var that = $(this);
            if (lines.hasClass("is-open")) {
                lines.removeClass("is-open").addClass("is-closed");
            } else {
                lines.removeClass("is-closed").addClass("is-open");
            }
        });
    });