display your element at all times and only transition any property animatable . In your case, opacity looks like a good candidate, although playing with transform can also give you the desired result. A simple example:
any { transform: scale(0); transition: transform .4s cubic-bezier(.5,0,.3,1); } any.animated { transform: scale(1); }
In fact, opacity and transform should be the only two properties that need to be revived, since they do not require the DOM redrawn on anything other than an animated element, thus without affecting browser performance, even if you're animating a significant number of elements at the same time.
Note that even if they are not colored, your elements are essentially where they would be if it weren't for ed ed at all. Therefore, you can give them pointer-events:none when they are in the "invisible" state, and pointer-events:all when they are in the "invisible" state, so they will not catch any pointer events until they are visible.
Given your example, I gave you two examples of animation (with and without keyframes). Remember that you need prefix your code . For full browser compatibility, use > 0% in the settings (small block at the bottom).
setTimeout(function(){ var dm = document.querySelector('.dropdown-menu'); dm.classList.remove('hide-menu'); }, 300);
.dropdown-menu.hide-menu { opacity: 0; } .dropdown-menu { opacity: 1; transition: opacity .2s cubic-bezier(.4,0,.2,1); position: relative; animation: delay-overflow .3s; animation-fill-mode: forwards; animation-iteration-count: 1; } .dropdown-menu:hover { animation: none; cursor: pointer; } .dropdown-menu ul { position: absolute; margin-top: 0; padding-top: 1rem; top: 100%; opacity: 0; transform: translateY(-10%); animation: slide-up .3s; animation-fill-mode: forwards; animation-iteration-count: 1; } .drowdown-menu.hide-menu ul { animation-duration: 0s; } .dropdown-menu:hover ul { animation: slide-down .3s; animation-fill-mode: forwards; } @keyframes slide-down { from { opacity: 0; transform: translateY(-10%); } to { opacity: 1; transform: translateY(0); } } @keyframes slide-up { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-10%); } } @keyframes delay-overflow { 0% { overflow: visible; } 99% { overflow: visible; } 100% { overflow: hidden; } }
<div class="dropdown-menu hide-menu"> <span>Menu</span> <ul> <li>A menu item</li> <li>Another menu item</li> <li>...</li> <li>And so on...</li> </ul> </div>
Note. A very convenient trick with the animation property is that it allows you to delay the application of any property, even non-animative ones, from filing an application for the required amount of time. I use this trick to delay the overflow:hidden application to the parent (and the overflow not animated), so the animation of the child that occurs outside the parent is visible to the end. After its completion, overflow:hidden is applied, and it no longer catches mouse events outside the menu opener.
source share