CSS Transition from display to display to display a block and vice versa

I know this question was probably asked a million times here in SO, but Ive tried most of the solution, I just don’t know why it doesn’t work for me.

So, I have a dropdown with display , initially aimed at none . When I click on it, it shows a good transition. (So ​​far, so good). But when I click on it again to hide the drop-down list, it hides immediately, but I don’t want it. I want to hide with the same transition that was assigned to show. Here is my CSS code:

 .dropdown-menu { padding: 0 0; display: none; -webkit-animation: slide-down .3s ease-out; -moz-animation: slide-down .3s ease-out; } .table-dropdown-open { display: block; -webkit-animation: slide-down .3s ease-out; -moz-animation: slide-down .3s ease-out; } @-webkit-keyframes slide-down { 0% { opacity: 0; -webkit-transform: translateY(-10%); } 100% { opacity: 1; -webkit-transform: translateY(0); } } @-moz-keyframes slide-down { 0% { opacity: 0; -moz-transform: translateY(-10%); } 100% { opacity: 1; -moz-transform: translateY(0); } } 

This is not a duplicate, because Im trying to pass the transition from block to none . Not from none to block

+5
source share
2 answers

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); 
 /* simple animation example, on parent. No keyframes. */ .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; } /* animation example with keyframes, on child */ .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.

+9
source

this is just simple logic, you currently styled your slide down, but you did not specify the div to be canceled. You must first have a closed state, which, I believe, in your case is -.dropdown-menu

  .dropdown-menu { transition:all 500ms ease; } 

or just use .dopdown-menu {

  transition: margin 300ms cubic-bezier(0.17, 0.04, 0.03, 0.94); } 

If this does not work,

0
source

Source: https://habr.com/ru/post/1264621/


All Articles