带有可见性的 CSS 转换不起作用

在下面的小提琴,我有一个过渡的可见性和不透明度分开。后者起作用,但前者不起作用。此外,在可见的情况下,过渡时间被解释为悬停时的延迟。同时发生在 Chrome 和 Firefox 中。这是窃听器吗?

Http://jsfiddle.net/0r218mdo/3/

案例1:

#inner{
visibility:hidden;
transition:visibility 1000ms;
}
#outer:hover #inner{
visibility:visible;
}

案例2:

#inner1{
opacity:0;
transition:opacity 1000ms;
}
#outer1:hover #inner1{
opacity:1;
}
229821 次浏览

这不是 bug -您只能在序数/可计算属性上转换(一种简单的思考方式是任何具有数字开始和结束编号值的属性)。.不过也有少数例外)。

这是因为过渡工作通过计算两个 价值观之间的关键帧,并通过推断中间量生成动画。

在这种情况下,visibility是一个二进制设置(可见/隐藏) ,所以一旦转换持续时间过去,属性只是切换状态,你看到这作为一个延迟-但它实际上可以看作是转换动画的最终关键帧,中间的关键帧没有计算(什么构成的值之间的隐藏/可见?不透明?维度?因为它不是显式的,所以它们不是计算出来的)。

opacity是一个值设置(0-1) ,因此可以在提供的持续时间内计算关键帧。

可转换(可动画)属性的列表可以找到 这里

可见性是可动画的。请查看这篇关于它的博客文章: http://www.greywyvern.com/?post=337

你也可以在这里看到: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

假设您有一个菜单,希望在鼠标悬停时淡入和淡出。如果你只使用 opacity:0,你的透明菜单仍然会在那里,它会动画当你悬停在看不见的区域。但是如果你添加 visibility:hidden,你可以消除这个问题:

div {
width:100px;
height:20px;
}
.menu {
visibility:hidden;
opacity:0;
transition:visibility 0.3s linear,opacity 0.3s linear;
    

background:#eee;
width:100px;
margin:0;
padding:5px;
list-style:none;
}
div:hover > .menu {
visibility:visible;
opacity:1;
}
<div>
<a href="#">Open Menu</a>
<ul class="menu">
<li><a href="#">Item</a></li>
<li><a href="#">Item</a></li>
<li><a href="#">Item</a></li>
</ul>
</div>

根据规范,可见性是一个可动画的属性,但是可见性的转换并不像人们可能期望的那样逐渐工作。取而代之的是隐藏元素的可见性转换延迟。另一方面,使元素可见立即起作用。这是 由 spec 定义(在默认计时函数的情况下) ,因为它是在浏览器中实现的。

这也是一个有用的行为,因为事实上,人们可以想象各种各样的视觉效果来隐藏一个元素。淡出元素只是使用不透明度指定的一种视觉效果。其他的视觉效果可以使用例如转换属性移开元素,也可以参见 http://taccgl.org/blog/css-transition-visibility.html

将不透明性转换与可见性转换结合起来通常很有用!虽然不透明度看起来做正确的事情,完全透明的元素(不透明度: 0)仍然接收鼠标事件。因此,例如,单独使用不透明转换淡出的元素上的链接,仍然响应单击(尽管不可见) ,淡出元素后面的链接不起作用(尽管通过淡出元素可见)。参见 http://taccgl.org/blog/css-transition-opacity-for-fade-effects.html

这种奇怪的行为可以通过同时使用转换、可见性转换和不透明性转换来避免。因此,可见性属性用于禁用元素的鼠标事件,而不透明性用于视觉效果。但是,在播放视觉效果时,必须注意不要隐藏元素,否则视觉效果将不可见。在这里,可见性转换的特殊语义变得很方便。当隐藏一个元素时,该元素在播放视觉效果时保持可见,并在之后隐藏。另一方面,当显示一个元素时,可见性转换使元素立即可见,即在播放视觉效果之前。

如果您想延迟可见性,那么下面的代码片段可能是一个解决方案。
因为“可见性”属性是打开/关闭的,所以您可以使用 transition-delay属性来控制对象应该可见的时间。

div {
width:100px;
height:20px;
}
.menu {
transition-delay: 0s;
transition-duration: 0s;
transition-property: opacity;
background:#eee;
width:100px;
margin:0;
height: 0px;
opacity: 0;
list-style:none;
overflow: hidden;
}


div:hover > .menu {
height: initial;
transition-delay: 1s;
opacity: 1;
}
<div>
<a href="#">Open Menu</a>
<ul class="menu">
<li><a href="#">Item</a></li>
<li><a href="#">Item</a></li>
<li><a href="#">Item</a></li>
</ul>
</div>