ML

Here is a little trick to have CSS animation while using display block on that element. Also animation does not work like transition to have animate enterence and exit (showing and hiding) so this trick solves this problem too.

In example on dropdown menu, consider this very standard layout:

HTML

<div class="menu">
  <ul>
    <li><a href="#">Hover me</a>
      <ul>
        <li><a href="#">Submenu</a>
        </li>
        <li><a href="#">Submenu</a>
        </li>
        <li><a href="#">Submenu</a>
        </li>
        <li><a href="#">Submenu</a>
        </li>
      </ul>
    </li>
  </ul>
</div>

STANDARD MENU CSS

.menu {
  display: inline-block;
}
.menu ul {
  list-style: none;
  position: relative;
  margin: 0;
  padding: 0;
}
.menu ul:before, .menu ul:after {
  display: table;
  content: ' ';
}
.menu ul:after {
  clear: both;
}
.menu ul > li {
  margin: 0;
  padding: 0;
  float: left;
}
.menu ul > li > a {
  padding: 20px 30px;
  background: #f5f5f5;
  display: block;
  color: #333;
  text-decoration: none;
}
.menu ul > li > ul {
  display: none;
  position: absolute;
  z-index: 99;
  left: 0;
  width: 200px;
}
.menu ul > li > ul > li {
  float: none;
  display: block;
}
.menu ul > li > ul > li > a {
  background: #0071bc;
  color: #fff;
  font-size: .9em;
}

So dropdown menu is hidden ( or .menu > ul > li > ul ) with dispay block and to animate display block you would have to use jquery or some animation library, you colud not do it with CSS only.

Here is a solution with a little help from jquery.

Firstly you write some nice CSS animation or like me just use ones from animate.css by Daniel Eden. Make sure you have enterence (IN, SHOW) animation and exit (OUT, HIDE) animation so you can have both states animated like in transition:

@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translate3d(0, -20px, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.fadeInDown {
  animation: .2s ease;
  animation-name: fadeInDown;
}

@keyframes fadeOutUp {
  from {
    opacity: 1;
    transform: none;
  }
  to {
    opacity: 0;
    transform: translate3d(0, -20px, 0);
  }
}

.fadeOutUp {
  animation: .2s ease;
  animation-name: fadeOutUp;
}

Then add that little help from jquery

$('.menu > ul > li').on({
      mouseenter: function() {
        $(this).children('ul').css('display', 'block').removeClass('fadeOutUp').addClass('fadeInDown');
      },
      mouseleave: function() {
        $(this).children('ul').removeClass('fadeInDown').addClass('fadeOutUp').delay(200).queue(function(next) {
          $(this).css('display', 'none');
          next();
        });
      }
    });

With jquery, you separate hover event into two parts, on mouseenter and on mouseleave. On mouseenter you firstly add display: block so animation can be visible, because without display: block there is no element displayed and so nothing visible is animated. Then you add an enterence animation class. Exit animation class is removed before for future hovering (so it removes exit and add enterence class every time on mouseenter . On mouseleave you remove the enterence animation class you added on mouseenter and then you add exit animation class.

Now most important thing. When you added a exit animation class you must wait for this animation to finish animating. We put animation to be animation: .2s ease; so the animation will need 200ms from start to finish animation. So we must wait exactly 200ms (time of animation from CSS) for animation to finish and then we add display: none; to hide the submenu again. We wait for animation to finish wit jquery's .delay() and then with .queue() we add display: none; because the queued function will execute right after the animation.

DEMO

See the Pen CSS animation with display property using jquery trick by Mario Loncarek (@riogrande) on CodePen.

Blog Comments Powered by Disqus