CSS 从无显示到显示块的过渡,反之亦然 [英] CSS Transition from display none to display block and vice versa

查看:22
本文介绍了CSS 从无显示到显示块的过渡,反之亦然的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

.dropdown-menu {填充:0 0;显示:无;-webkit-animation:向下滑动 .3s 缓出;-moz-animation:向下滑动 0.3s 缓出;}.table-下拉打开{显示:块;-webkit-animation:向下滑动 .3s 缓出;-moz-animation:向下滑动 0.3s 缓出;}@-webkit-keyframes 滑下 {0% {不透明度:0;-webkit-transform: translateY(-10%);}100% {不透明度:1;-webkit-transform: translateY(0);}}@-moz-keyframes 滑下 {0% {不透明度:0;-moz-transform: translateY(-10%);}100% {不透明度:1;-moz-transform: translateY(0);}}

这不是重复,因为我试图从 block 过渡到.不是从 noneblock

解决方案

display 你的元素在任何时候都只有 transition 任何 animatable 属性.在您的情况下, opacity 看起来是一个不错的选择,尽管使用 transform 也可能会给您想要的结果.简单例子:

any {变换:比例(0);过渡:变换 .4s 三次贝塞尔曲线(.5,0,.3,1);}任何动画{变换:比例(1);}

实际上,opacitytransform 应该是仅有的两个你应该设置动画的属性,因为它们不需要 DOM 重新绘制任何东西动画元素除外,因此不会影响浏览器性能,即使您同时为大量元素设置动画.

请注意,即使没有绘制,您的元素实际上也位于它们根本没有转换时的位置.因此,当它们处于 不可见" 状态时,您可能希望给它们 pointer-events:nonepointer-events:all处于 可见" 状态,因此它们在不可见时不会捕获任何指针事件.

<小时>

考虑到您的示例,我给了您两个动画示例(有关键帧和没有关键帧).请记住,您需要为代码添加前缀.为了完全兼容浏览器,请使用 >0% 设置(底部的小框).

setTimeout(function(){var dm = document.querySelector('.dropdown-menu');dm.classList.remove('隐藏菜单');}, 300);

/* 简单的动画示例,在父级上.没有关键帧.*/.dropdown-menu.hide-menu {不透明度:0;}.下拉式菜单 {不透明度:1;过渡:不透明度 0.2s 立方贝塞尔曲线(.4,0,.2,1);位置:相对;动画:延迟溢出 0.3 秒;动画填充模式:向前;动画迭代计数:1;}.下拉菜单:悬停{动画:无;光标:指针;}/* 带有关键帧的动画示例,在子对象上 */.下拉菜单ul {位置:绝对;边距顶部:0;填充顶部:1rem;顶部:100%;不透明度:0;变换:translateY(-10%);动画:向上滑动 0.3 秒;动画填充模式:向前;动画迭代计数:1;}.drowdown-menu.hide-menu ul {动画持续时间:0s;}.dropdown-menu:hover ul {动画:向下滑动 0.3 秒;动画填充模式:向前;}@keyframes 向下滑动 {从 {不透明度:0;变换:translateY(-10%);}到 {不透明度:1;变换:translateY(0);}}@keyframes 向上滑动 {从 {不透明度:1;变换:translateY(0);}到 {不透明度:0;变换:translateY(-10%);}}@keyframes 延迟溢出{0% {溢出:可见;}99% {溢出:可见;}100% {溢出:隐藏;}}

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

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 display initially 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:

.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 block to none. Not from none to block

解决方案

display your element at all times and only transition any animatable property. In your case, opacity looks like a good candidate, though playing with transform might also give you the desired result. Simple example:

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

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

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:none when they are in the "invisible" state and pointer-events:all when they are in "visible" state, so they don't catch any pointer events while not visible.


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).

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 animation property 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:hidden applying on the parent (and overflow is 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:hidden applies and it no longer catches mouse events outside the menu opener.

这篇关于CSS 从无显示到显示块的过渡,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆