显示屏上的转换:属性

问题描述 投票:1246回答:31

我目前正在设计一个CSS'mega dropdown'菜单 - 基本上是一个常规的CSS-only下拉菜单,但包含不同类型的内容。

目前,似乎CSS3 Transitions不适用于'display'属性,即你不能进行从display: nonedisplay: block(或任何组合)的任何转换。

当有人将鼠标悬停在其中一个顶级菜单项上时,是否有人会想到上述示例中的第二层菜单可以“淡入”?

我知道你可以在visibility:属性上使用转换,但我想不出有效利用它的方法。

我也尝试过使用身高,但这只是失败了。

我也知道使用JavaScript实现这一点是微不足道的,但我想挑战自己只使用CSS而且我认为我现在有点短。

欢迎所有和任何建议。

css css3 css-transitions
31个回答
1194
投票

你可以连接两个或更多的转换,visibility这次是方便的。

div {
  border: 1px solid #eee;
}
div > ul {
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity 0.5s linear;
}
div:hover > ul {
  visibility: visible;
  opacity: 1;
}
<div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
</div>

(不要忘记transition属性的供应商前缀)

更多细节在this article


12
投票

编辑:在此示例中未显示任何未应用。

@keyframes hide {
  0% {
    display: block;
    opacity: 1;
  }
  99% {
    display: block;
  }
  100% {
    display: none;
    opacity: 0;
  }
}

上面发生的是,99%的动画显示设置为阻止,而不透明度淡出。在最后一刻,display属性设置为none。

最重要的一点是在动画结束后使用动画填充模式保留最后一帧:前进

.hide {
   animation: hide 1s linear;
   animation-fill-mode: forwards;
}

以下是两个例子:https://jsfiddle.net/qwnz9tqg/3/


10
投票

我今天遇到了这个问题,我正在重复使用position: fixed模式。我无法保持它display: none,然后动画它,因为它只是跳入外观,并且z-index(负值等)也做了奇怪的事情。

我也使用height: 0height: 100%,但它只在模态出现时才有用。这与使用left: -100%或其他东西时相同。

然后让我感到有一个简单的答案。等瞧:

首先,你隐藏的模态。请注意height0,并查看转换中的height声明...它有一个500ms,比我的opacity过渡更长。请记住,这会影响外出的淡出过渡:将模态返回到其默认状态。

#modal-overlay {
    background: #999;
    background: rgba(33,33,33,.2);
    display: block;
    overflow: hidden;
    height: 0;
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    opacity: 0;
    z-index: 1;
    -webkit-transition: height 0s 500ms, opacity 300ms ease-in-out;
       -moz-transition: height 0s 500ms, opacity 300ms ease-in-out;
            -ms-transition: height 0s 500ms, opacity 300ms ease-in-out;
         -o-transition: height 0s 500ms, opacity 300ms ease-in-out;
        transition: height 0s 500ms, opacity 300ms ease-in-out;
}

第二,你的可见模态。假设你正在为.modal-active设置body。现在height100%,我的过渡也发生了变化。我希望height立即改变,而opacity采取300ms

.modal-active #modal-overlay {
    height: 100%;
    opacity: 1;
    z-index: 90000;
    -webkit-transition: height 0s, opacity 300ms ease-in-out;
       -moz-transition: height 0s, opacity 300ms ease-in-out;
        -ms-transition: height 0s, opacity 300ms ease-in-out;
         -o-transition: height 0s, opacity 300ms ease-in-out;
            transition: height 0s, opacity 300ms ease-in-out;
}

就是这样,它就像一个魅力。


8
投票

从其中一些答案和其他地方的一些建议中得出,以下内容适用于悬停菜单(我将其与bootstrap 3一起使用,具体而言):

nav .dropdown-menu {
    display: block;
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height 500ms, opacity 300ms;
    -webkit-transition: max-height 500ms, opacity 300ms;
}
nav .dropdown:hover .dropdown-menu {
    max-height: 500px;
    opacity: 1;
    transition: max-height 0, opacity 300ms;
    -webkit-transition: max-height 0, opacity 300ms;
}

你可以使用height代替max-height,如果你指定这两个值,因为height:auto不允许使用transitionmax-height的悬停值需要大于菜单的height


6
投票

overflow:hidden改为overflow:visible。它效果更好。我用这样的:

#menu ul li ul {
    background-color:#fe1c1c;
    width:85px;
    height:0px;
    opacity:0;
    box-shadow:1px 3px 10px #000000;
    border-radius:3px;
    z-index:1;
    -webkit-transition:all 0.5s ease;
    -moz-transition:all 0.6s ease;
}

#menu ul li:hover ul  {
    overflow:visible;
    opacity:1;
    height:140px;
}

visible更好,因为overflow:hidden的行为与display:none完全相同。


5
投票

不需要javascript,也不需要巨大的最大高度。而是在文本元素上设置最大高度,并使用字体相对单位,如rem或em。这样,您可以设置大于容器的最大高度,同时避免延迟或菜单关闭时“弹出”:

HTML

<nav>
  <input type="checkbox" />
  <ul>
    <li>Link 1</li>
    <li>Link 1</li>
    <li>Link 1</li>
    <li>Link 1</li>
  </ul>
</nav>

CSS

nav input + ul li { // notice I set max-height on li, not ul
   max-height: 0;
}

nav input:checked + ul li {
   max-height: 3rem; // a little bigger to allow for text-wrapping - but not outrageous
}

在这里查看示例:http://codepen.io/mindfullsilence/pen/DtzjE


5
投票

在Guillermo接受的答案被写入后,2012年4月3日的CSS转换规范改变了可见性转换的行为,现在可以在不使用转换延迟的情况下以更短的方式解决此问题:

.myclass > div { 
                   transition:visibility 1s, opacity 1s; 
                   visibility:hidden;  opacity:0
               }
.myclass:hover > div 
               {   visibility:visible; opacity:1 }

为两个转换指定的运行时间通常应该相同(尽管稍长的可见性时间不是问题)。有关正在运行的版本,请参阅我的博客http://www.taccgl.org/blog/css-transition-visibility.html#visibility-opacity

W.r.t.问题的标题“显示过渡:属性”,并回应Rui Marques和josh对已接受答案的评论:此解决方案适用于如果使用显示或可见性属性无关紧要的情况(因为它可能是这个问题中的情况)。它不会完全删除元素display:none,只是让它不可见但它仍然停留在文档流中并影响以下元素的位置。完全删除类似于display的元素的过渡:none可以使用height(如其他答案和注释所示),max-height或margin-top / bottom来完成,但也可以查看How can I transition height: 0; to height: auto; using CSS?和我的博客http://www.taccgl.org/blog/css_transition_display.html

回应GeorgeMillo的评论:需要属性和两个转换:不透明度属性用于创建淡入和淡出动画以及可见性属性,以避免元素仍对鼠标事件做出反应。视觉效果的不透明度和延迟隐藏的可见性需要转换,直到淡出结束。


4
投票

我怀疑任何刚启动CSS转换的人都会发现,如果你同时修改了display属性(block / none),它们就无法工作。一个尚未提及的解决方法是你可以继续使用display:block / none隐藏/显示元素,但将其不透明度设置为0,这样即使它显示:block,它仍然是不可见的。然后将其淡入,添加另一个CSS类,例如“on”,它将不透明度设置为1并定义不透明度的过渡。正如您可能想象的那样,您必须使用JavaScript将“on”类添加到元素中,但至少您仍在使用CSS进行实际转换。

附:如果您发现自己处于需要同时执行display:block和添加类“on”的情况下,请同时使用setTimeout推迟后者。否则,浏览器只会立即看到这两件事情并禁用转换。


4
投票

我多次遇到过这个问题,现在只需要:

.block {
  opacity: 1;
  transition: opacity 250ms ease;
}

.block--invisible {
  pointer-events: none;
  opacity: 0;
}

通过添加类block--invisible,整个Elements将无法点击,但其背后的所有元素都将是因为所有主流浏览器都支持的pointer-events:none(没有IE <11)。


3
投票

我终于找到了一个解决方案,通过将opacityposition absolute相结合(隐藏时不占用空间)。

.toggle {
  opacity: 0;
  position: absolute;
  transition: opacity 0.8s;
}

.parent:hover .toggle {
  opacity: 1;
  position: static;
}

2
投票

我认为SalmanPK有最接近的答案,它确实淡入或淡出一个项目,使用以下CSS动画。但是,display属性不能平滑动画,只有不透明度。

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}

@-webkit-keyframes fadeOut {
    from { opacity: 1; }
      to { opacity: 0; }
}

如果你想动画元素从显示块移动到显示无,我看不到它目前只有CSS,你必须获得高度并使用CSS动画来降低高度。这可以通过CSS实现,如下面的示例所示,但要知道元素动画所需的确切高度值会很棘手。

jsFiddle的例子

CSS

@-webkit-keyframes pushDown {
  0% {
    height: 10em;
  }
  25% {
    height: 7.5em;
  }
  50% {
    height: 5em;
  }
  75% {
    height: 2.5em;
  }
  100% {
    height: 0em;
  }
}

.push-down {
    -webkit-animation: pushDown 2s forwards linear;
}

JavaScript

var element = document.getElementById("element");

// push item down
element.className = element.className + " push-down";

734
投票

您需要通过其他方式隐藏元素才能使其生效。

我通过绝对定位两个<div>s并将隐藏的一个设置为opacity: 0来完成效果。

如果您甚至将display属性从none切换到block,则不会发生对其他元素的转换。

要解决此问题,请始终允许元素为display: block,但通过调整以下任何方法来隐藏元素:

  1. height设置为0
  2. opacity设置为0
  3. 将元素放在具有overflow: hidden的另一个元素的框架之外。

可能有更多解决方案,但如果您将元素切换到display: none,则无法执行转换。例如,您可能尝试尝试这样的事情:

div {
    display: none;
    transition: opacity 1s ease-out;
    opacity: 0; 
}
div.active {
    opacity: 1;
    display: block;
}

但那不行。根据我的经验,我发现这无所事事。

因此,你总是需要保留元素display: block - 但你可以通过做这样的事情来绕过它:

div {
    transition: opacity 1s ease-out;
    opacity: 0; 
    height: 0;
    overflow: hidden;
}
div.active {
    opacity: 1;
    height: auto;
}

2
投票

我觉得用这么多答案回答问题几乎是不好的,但是这个解决方案具有很好的兼容性,我还没有看到它:

.hidden-element {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity .5s ease-out;
}

.hidden-element.visible {
  position: static;
  z-index: auto;
  pointer-events: auto;
  visibility: visible;
  opacity: 1;
}

说明:它使用visibility: hidden技巧(在一步中与“show-and-animate”兼容)但使用组合position: absolute; z-index: -1; pointer-events: none;来确保隐藏容器不占用空间而不回答用户交互。


1
投票

您可以将元素“屏幕外”存储到您需要的位置,然后将其位置设置到您想要的位置并同时进行转换,而不是使用显示。这带来了许多其他设计问题,所以ymmv。您可能不想使用显示器,因为您希望屏幕阅读器可以访问内容,这在大多数情况下都会尝试遵守可见性规则 - 即,如果它不应该对眼睛可见,它不会显示为代理的内容。


1
投票

这个问题的最简单的通用解决方案是:随意在CSS中指定display:none,但是你将使用JavaScript将它更改为block(或其他任何东西),然后你还需要为你的元素添加一个类实际上用setTimeout()进行转换。就这样。

即:

<style>
#el {
    display: none;
    opacity: 0;
}
#el.auto-fade-in {
    opacity: 1;
    transition: all 1s ease-out; /* future, future, please come sooner! */
    -webkit-transition: all 1s ease-out;
    -moz-transition: all 1s ease-out;
    -o-transition: all 1s ease-out;
}
</style>

<div id=el>Well, well, well</div>

<script>
var el = document.getElementById('el');
el.style.display = 'block';
setTimeout(function () { el.className = 'auto-fade-in' }, 0);
</script>

在最新的理智浏览器中测试过。显然不应该在IE9或更早版本中工作。


1
投票

您可以使用转换事件执行此操作,因此,您为转换构建2个css类,一个保持动画另一个,保持display none状态。并在动画结束后切换它们?在我的情况下,如果我按下btn,我可以再次显示div,并删除这两个类。

试试下面的剪辑......

$(document).ready(function() {
  //assign transition event
  $("table").on("animationend webkitAnimationEnd", ".visibility_switch_off", function(event) {
    //we check if this is the same animation we want  
    if (event.originalEvent.animationName == "col_hide_anim") {
      //after the animation we assign this new class that basically hides the elements.    
      $(this).addClass("animation-helper-display-none");
    }

  });

  $("button").click(function(event) {

    $("table tr .hide-col").toggleClass(function() {
      //we switch the animation class in a toggle fashion...
      //and we know in that after the animation end, there is will the animation-helper-display-none extra class, that we nee to remove, when we want to show the elements again, depending on the toggle state, so we create a relation between them.
      if ($(this).is(".animation-helper-display-none")) {
        //im toggleing and there is already the above classe, then what we want it to show the elements , so we remove both classes...        
        return "visibility_switch_off animation-helper-display-none";
      } else {
        //here we just want to hide the elements, so we just add the animation class, the other will be added later be the animationend event...        
        return "visibility_switch_off";
      }

    });

  });

});
table th {
  background-color: grey;
}

table td {
  background-color: white;
  padding:5px;
}

.animation-helper-display-none {
  display: none;
}

table tr .visibility_switch_off {
  animation-fill-mode: forwards;
  animation-name: col_hide_anim;
  animation-duration: 1s;
}

@-webkit-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@-moz-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@-o-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@keyframes col_hide_anim {
  0%   {opacity: 1;}
  100% {opacity: 0;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <theader>
    <tr>
      <th>Name</th>
      <th class='hide-col'>Age</th>
      <th>Country</th>
    </tr>
  </theader>
  <tbody>
    <tr>
      <td>Name</td>
      <td class='hide-col'>Age</td>
      <td>Country</td>
    </tr>
  </tbody>
</table>

<button>Switch - Hide Age column with fadeout animation and display none after</button>

1
投票

就像:)一样简单

@keyframes fadeout {
0% { opacity: 1; height: auto; }
90% { opacity: 0; height: auto; }
100% { opacity: 0; height: 0;
}
animation: fadeout linear 0.5s 1 normal forwards !important;

让它消失,然后使其高度为0;还要确保使用前进,以使其保持最终状态。


0
投票

您可以简单地使用css visibility:hidden / visible而不是display:none / block

div {
    visibility:hidden;
    -webkit-transition: opacity 1s ease-out;
    -moz-transition: opacity 1s ease-out;
    -o-transition: opacity 1s ease-out;
    transition: opacity 1s ease-out;
    opacity: 0; 
}

parent:hover > div {
    opacity: 1;
    visibility: visible;
}

0
投票

你也可以用这个:

.dropdown {
height: 0px;
width: 0px;
opacity: .0;
color: white;
}
.dropdown:hover {
height: 20px;
width: 50px;
opacity: 1;
transition: opacity 200ms;
/* Safari */
-webkit-transition: opacity 200ms;
}

0
投票

你可以使用你想要的自然方式 - 使用显示 - 但是你必须使用JS来限制浏览器以使其工作,或者正如其他人已经建议在另一个标签中使用一个标签的花哨技巧。我不关心内部标记,因为它进一步使CSS和维度复杂化,所以这里是JS解决方案:

https://jsfiddle.net/b9chris/hweyecu4/1/

从如下框开始:

<div class="box hidden">Lorem</div>

一个隐藏的盒子。您可以点击进行转换:

function toggleTransition() {
  var el = $("div.box1");

  if (el.length) {
    el[0].className = "box";
    el.stop().css({maxWidth: 10000}).animate({maxWidth: 10001}, 2000, function() {    
        el[0].className = "box hidden";
    });
  } else {
    el = $("div.box");
    el[0].className = "box";
    el.stop().css({maxWidth: 10001}).animate({maxWidth: 10000}, 50, function() {    
        el[0].className = "box box1";
    });
  }

  return el;
}

someTag.click(toggleTransition);

CSS就是你猜的:

.hidden {
  display: none;
}
.box {
    width: 100px;
    height: 100px;
    background-color: blue;
    color: yellow;
    font-size: 18px;
    left: 20px;
    top: 20px;
    position: absolute;
    -webkit-transform-origin: 0 50%;
    transform-origin: 0 50%;
    -webkit-transform: scale(.2);
    transform: scale(.2);
  -webkit-transition: transform 2s;
  transition: transform 2s;
}
.box1{
    -webkit-transform: scale(1);
    transform: scale(1);
}

关键是限制显示属性。通过删除隐藏的类然后等待50ms,然后通过添加的类开始转换,我们让它出现然后像我们想要的那样展开,而不是只是在没有任何动画的情况下闪烁到屏幕上。类似的情况发生在另一种方式,除了我们等到动画结束之前应用隐藏。

注意:我在这里滥用.animate(maxWidth)以避免setTimeout竞争条件。当你或其他人不知道它的代码时,setTimeout会迅速引入隐藏的错误。 .animate()很容易被.stop()杀死。我只是用它在标准的fx队列上放置50ms或2000ms的延迟,在这之上很容易找到/解决其他编码器。


0
投票

我开始了一个名为Toggle Display Animate的开源骨架项目

https://marcnewton.github.io/Toggle-Display-Animate/

这个骨架帮助器将允许您轻松模仿jQuery显示/隐藏,但具有输入/输出CSS3过渡动画。

它使用类切换,因此除了display:none | block | table | inline等以及可以想到的其他替代用途之外,您还可以在元素上使用所需的任何css方法。

它的主要设计目的是用于元素切换状态,它支持一个恢复状态,其中隐藏对象允许您反向运行关键帧或播放替代动画以隐藏元素。

我正在研究的概念的大多数标记是CSS,实际使用的javascript非常少。

这里有一个演示:http://marcnewton.co.uk/projects/toggle-display-animate/


0
投票

我有一个类似的问题,我无法找到答案。之后的一些谷歌搜索引发了我的兴趣。考虑到我没有找到我希望的简单答案,我偶然发现了一个既优雅又有效的解决方案。

事实证明,visibility CSS属性的值为collapse,通常用于表项。但是,如果在任何其他元素上使用它,它会有效地将它们渲染为隐藏,与display: hidden几乎相同,但具有添加的能力,即元素不会占用任何空间,您仍然可以为相关元素设置动画。

下面是一个简单的例子。

function toggleVisibility() {
  let exampleElement = document.querySelector('span');
  if (exampleElement.classList.contains('visible')) {
    return;
  }
  exampleElement.innerHTML = 'I will not take up space!';
  exampleElement.classList.toggle('hidden');
  exampleElement.classList.toggle('visible');
  setTimeout(() => {
    exampleElement.classList.toggle('visible');
    exampleElement.classList.toggle('hidden');
  }, 3000);
}
#main {
  display: flex;
  flex-direction: column;
  width: 300px;
  text-align: center;
}

.hidden {
  visibility: collapse;
  opacity: 0;
  transition: visibility 2s, opacity 2s linear;
}

.visible {
  visibility: visible;
  opacity: 1;
  transition: visibility 0.5s, opacity 0.5s linear;
}
<div id="main">
  <button onclick="toggleVisibility()">Click Me!</button>
  <span class="hidden"></span>
  <span>I will get pushed back up...</span>
</div>

241
投票

在这篇文章的时候,如果你试图改变display属性,所有主流浏览器都会禁用CSS转换,但CSS动画仍然可以正常工作,所以我们可以将它们用作解决方法。

示例代码: - (您可以相应地将它应用到您的菜单)Demo

将以下CSS添加到样式表: -

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}  
@keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}

然后将fadeIn动画应用于父母悬停的孩子: - (当然设置display: block

.parent:hover .child {
    display: block;
    -webkit-animation: fadeIn 1s;
    animation: fadeIn 1s;
}

Update 2019 - Method that also supports fading out:

(有些JS需要)

// We need to keep track of faded in elements so we can apply fade out later in CSS
document.addEventListener('animationstart', function (e) {
  if (e.animationName === 'fade-in') {
      e.target.classList.add('did-fade-in');   
  }
});

document.addEventListener('animationend', function (e) {
  if (e.animationName === 'fade-out') {
      e.target.classList.remove('did-fade-in');
   }
});
div {
    border: 5px solid;
    padding: 10px;
}

div:hover {
    border-color: red;
}
 
.parent .child {
  display: none;
}
 
.parent:hover .child {
  display: block;
  animation: fade-in 1s;
}

.parent:not(:hover) .child.did-fade-in {
  display: block;
  animation: fade-out 1s;
} 

@keyframes fade-in {
  from { 
    opacity: 0; 
  }
  to { 
    opacity: 1; 
  }
}

@keyframes fade-out {
  from { 
    opacity: 1; 
  }
  to { 
    opacity: 0;
  }
}
<div class="parent">
    Parent
    <div class="child">
        Child
    </div>
</div>

-1
投票

它可以通过使用转换计时功能step-endstep-start来处理

例如:https://jsfiddle.net/y72h8Lky/

$(".run").on("click", function() {
    $(".popup").addClass("show");
});
$(".popup").on("click", function() {
    $(".popup").removeClass("show");
})
.popup {
    opacity: 0;
    display: block;
    position: absolute;
    top: 100%;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1450;
    background-color: rgba(0, 175, 236, 0.6);
    transition: opacity 0.3s ease-out, top 0.3s step-end;
}
.popup.show {
    transition: opacity 0.3s ease-out, top 0.3s step-start;
    opacity: 1;
    top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="popup"></div>
<button class="run" style="font-size: 24px;">Click on me</button>

63
投票

我怀疑如果“显示”发生变化,过渡被禁用的原因是因为显示实际上是什么。它不会改变任何可以想象得流畅动画的东西。

“display:none;”和“visibility:hidden;”是两个完全不同的东西。两者都具有使元素不可见的效果,但是“visibility:hidden;”它仍然在布局中呈现,但只是不明显。隐藏元素仍占用空间,仍然以内联或块或块内联或表格或“display”元素告诉它呈现为的方式呈现,并相应占用空间。其他元素不会自动移动以占据该空间。隐藏元素只是不将其实际像素渲染到输出。

另一方面,“display:none”实际上阻止了元素的完全渲染。它不占用任何布局空间。其他元素将占据该元素占用的部分或全部空间,现在可以调整占据该空间,就好像该元素根本不存在一样。

“显示”不仅仅是另一种视觉属性。它建立元素的整个渲染模式,例如它是块,内联,内联块,表,表行,表格单元,列表项还是其他什么!每个都有非常不同的布局分支,并且没有合理的方法来动画或平滑过渡它们(试图想象从“块”到“内联”的平滑过渡,或反之亦然,例如!)。

这就是为什么在显示改变时禁用转换的原因(即使改变是来自或来自“无” - “无”不仅仅是不可见,它是它自己的元素渲染模式,这意味着根本不进行渲染!),


47
投票

display不是转型所依据的财产之一。

请参阅https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties以获取可应用过渡的CSS属性列表。有关如何插值的信息,请参阅https://drafts.csswg.org/css-values-4/#combining-values

https://www.w3.org/TR/2017/WD-css-transitions-1-20171130/#animatable-css中列出了CSS3(只需关闭警告弹出窗口)

我也尝试过使用身高,但这只是失败了。

上次我不得不这样做,我使用了max-height,这是一个可动画的属性(尽管它有点像黑客,它确实有效)但请注意,对于复杂的页面或低级用户来说,它可能非常笨拙结束移动设备。


35
投票

我知道这是一个非常古老的问题,但是对于正在查看此线程的人,您现在可以向块属性添加自定义动画。

@keyframes showNav {
  from {opacity: 0;}
  to {opacity: 1;}
}
.subnav-is-opened .main-nav__secondary-nav {
  display: block;
  animation: showNav 250ms ease-in-out both;
}

Demo

在这个演示中,子菜单从display:none变为display:block,并且仍然设法淡出。


26
投票

我们可以使用transition-delay属性代替CSS中不存在的回调。

#selector {
    overflow: hidden; // hide the element content, while height = 0
    height: 0; opacity: 0;
    transition: height 0ms 400ms, opacity 400ms 0ms;
}
#selector.visible {
    height: 100%; opacity: 1;
    transition: height 0ms 0ms, opacity 600ms 0ms;
}

那么,这里发生了什么?

  1. 当添加visible类时,heightopacity都会无延迟地开始动画(0ms),尽管height需要0ms来完成动画(相当于display: block)而opacity需要600ms。
  2. visible类被移除时,opacity开始动画(0ms延迟,400ms持续时间),并且高度等待400ms,然后立即(0ms)恢复初始值(相当于动画回调中的display: none)。

注意,这种方法比使用visibility的方法更好。在这种情况下,元素仍然占据页面上的空间,并不总是合适的。

有关更多示例,请参阅此article


20
投票

根据W3C Working Draft 19 November 2013 display不是一个动画属性。幸运的是,visibility是可动画的。您可以通过不透明度的转换(JSFiddle)链接其转换:

  • HTML: <a href="http://example.com" id="foo">Foo</a> <button id="hide-button">Hide</button> <button id="show-button">Show</button>
  • CSS: #foo { transition-property: visibility, opacity; transition-duration: 0s, 1s; } #foo.hidden { opacity: 0; visibility: hidden; transition-property: opacity, visibility; transition-duration: 1s, 0s; transition-delay: 0s, 1s; }
  • 用于测试的JavaScript: var foo = document.getElementById('foo'); document.getElementById('hide-button').onclick = function () { foo.className = 'hidden'; }; document.getElementById('show-button').onclick = function () { foo.className = ''; };

请注意,如果您只是使链接透明,而不设置visibility: hidden,那么它将保持可点击状态。


13
投票

我的整洁JavaScript技巧是将整个场景分成两个不同的功能!

为了准备事物,声明了一个全局变量并定义了一个事件处理程序:

  var tTimeout;
  element.addEventListener("transitionend", afterTransition, true);//firefox
  element.addEventListener("webkitTransitionEnd", afterTransition, true);//chrome

然后,当隐藏元素时,我使用这样的东西:

function hide(){
  element.style.opacity = 0;
}

function afterTransition(){
  element.style.display = 'none';
}

为了重新出现元素,我正在做这样的事情:

function show(){
  element.style.display = 'block';
  tTimeout = setTimeout(timeoutShow, 100);
}

function timeoutShow(){
  element.style.opacity = 1;
}

它到目前为止有效!

© www.soinside.com 2019 - 2024. All rights reserved.