Html CSS 从无显示到显示块的过渡,反之亦然

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42414565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:24:58  来源:igfitidea点击:

CSS Transition from display none to display block and vice versa

htmlcssdrop-down-menucss-transitionscss-animations

提问by DingDong

I know this question has probably been asked million times here in SO, but Ive tried most of the solution, I just dont know why it dont work for me.

我知道这个问题在这里可能已经被问了数百万次,但我已经尝试了大部分解决方案,我只是不知道为什么它对我不起作用。

So I have a dropdown with displayinitially targeted to none. When I click on it, it shows nice transition. (So far so good). But when I click on it again to go hide the dropdown, it hides immediately, but I dont want that. I want to hide with similar transition that was assigned to show. Here is my code for CSS:

所以我有一个display最初针对none. 当我点击它时,它显示了很好的过渡。(到现在为止还挺好)。但是当我再次点击它隐藏下拉菜单时,它会立即隐藏,但我不想要那样。我想用分配给显示的类似过渡来隐藏。这是我的 CSS 代码:

.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 dupliacte because Im trying to give transition from blockto none. Not from noneto block

这不是重复,因为我试图从blocknone. 不是从noneblock

回答by tao

displayyour element at all times and only transitionany animatableproperty. In your case, opacitylooks like a good candidate, though playing with transformmight also give you the desired result. Simple example:

display你的元素在任何时候,只有transition任何animatable属性。在你的情况下,opacity看起来是一个不错的候选人,虽然玩transform也可能会给你想要的结果。简单的例子:

any {
  transform: scale(0);
  transition: transform .4s cubic-bezier(.5,0,.3,1);
}
any.animated {
  transform: scale(1);
}

In effect, opacityand transformshould be the only two properties you should animate, as they don't require DOMrepaint on anything other than the animated element, thus not hitting browser performance, even when you're animating a considerable amount of elements simultaneously.

实际上,opacity并且transform应该是您应该设置动画的唯一两个属性,因为它们不需要DOM在动画元素以外的任何内容上重新绘制,因此不会影响浏览器性能,即使您同时为大量元素设置动画。

Please note that, even if not painted, your elements are, in effect, in the place where they would be when not transformed at all. So you might want to give them pointer-events:nonewhen they are in the "invisible"state and pointer-events:allwhen they are in "visible"state, so they don't catch any pointer events while not visible.

请注意,即使没有绘制,您的元素实际上也位于它们根本没有被transform编辑的位置。因此,您可能希望pointer-events:none在它们处于“不可见”状态和pointer-events:all处于“可见”状态时给予它们,以便它们在不可见时不会捕获任何指针事件。



Considering your example, I've given you two animation examples (with keyframes and without). Remember you need to prefix your code. For full browser compatibility, use > 0%in settings (the small box at the bottom).

考虑到你的例子,我给了你两个动画例子(有关键帧和没有关键帧)。记住你需要prefix your code。为了完全兼容浏览器,请> 0%在设置中使用(底部的小框)。

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 handy trick with animationproperty is that it allows you to delay applying any property, even non-animatable ones from applying for the desired amount of time. I'm using this trick to delay overflow:hiddenapplying on the parent (and overflowis not animatable) so the animation of the child - which happens outside the bounds of the parent - is visible until the end. After it finishes, the overflow:hiddenapplies and it no longer catches mouse events outside the menu opener.

注意:animation属性的一个非常方便的技巧是它允许您延迟应用任何属性,甚至是不可动画的属性,直到应用所需的时间。我正在使用这个技巧来延迟overflow:hidden对父级的应用(并且overflow不可动画),因此子级的动画 - 发生在父级边界之外 - 直到结束都是可见的。完成后,将overflow:hidden应用并且不再捕获菜单打开器之外的鼠标事件。

回答by Tsitso Makhakhe

it is just simple logic, you currently have styled you slide down but you have not styled the cancellation of the div. You must first have a closed state which i believe in your case is .dropdown-menu

这只是简单的逻辑,您当前已设置向下滑动的样式,但尚未设置取消 div 的样式。你必须首先有一个关闭状态,我相信你的情况是 .dropdown-menu

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

or just use

或者只是使用

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

If this does not work,

如果这不起作用,