可见性不起作用的CSS过渡

2fjabf4q  于 2023-05-19  发布在  其他
关注(0)|答案(5)|浏览(169)

在下面的小提琴中,我分别对可见性和不透明性进行了转换。后者有效,但前者无效。此外,在可见性的情况下,过渡时间被解释为悬停时的延迟。在Chrome和Firefox中都有。这是一个bug吗?
http://jsfiddle.net/0r218mdo/3/
案例一:

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

案例二:

#inner1{
    opacity:0;
    transition:opacity 1000ms;
}
#outer1:hover #inner1{
    opacity:1;
}
k5ifujac

k5ifujac1#

这不是一个bug-你只能在序数/可计算的属性上转换(一种简单的思维方式是任何具有数字开始和结束数值的属性..尽管有一些例外)。

这是因为变换通过计算两个 * 值 * 之间的关键帧来工作,并通过外推中间量来生成动画。
visibility在本例中是一个二进制设置(可见/隐藏),因此一旦过渡持续时间过去,该属性就简单地切换状态,您可以将其视为延迟-但实际上可以将其视为过渡动画的最后一个关键帧,中间关键帧尚未计算(隐藏/可见之间的值是什么?不透明?尺寸?由于不明确,因此不计算)。
opacity是一个值设置(0-1),因此可以在提供的持续时间内计算关键帧。
可以在here中找到可转换(可动画)属性的列表

8ftvxx2r

8ftvxx2r2#

可见性可设置动画。看看这篇关于它的博客: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>
xn1cxnb4

xn1cxnb43#

根据规范,可见性是一个可设置动画的属性,但是可见性上的过渡并不像人们所期望的那样逐渐工作。相反,在可见性延迟时过渡隐藏元素。另一方面,使元素可见会立即起作用。这是***,因为它是由规范定义的***(在默认定时函数的情况下),因为它是在浏览器中实现的。
这也是一个有用的行为,因为实际上可以想象各种视觉效果来隐藏元素。淡出元素只是使用不透明度指定的一种视觉效果。其他视觉效果可以使用例如transform属性,另请参见http://taccgl.org/blog/css-transition-visibility.html
将不透明度过渡与可见性过渡结合使用通常很有用!尽管不透明度似乎是正确的,但完全透明的元素(不透明度为0)仍然会接收鼠标事件。因此,例如,仅使用不透明过渡淡出的元素上的链接仍然响应于点击(尽管不可见),并且淡出的元素后面的链接不起作用(尽管通过淡出的元素可见)。参见http://taccgl.org/blog/css-transition-opacity-for-fade-effects.html
这种奇怪的行为可以通过使用两种过渡来避免,即可见性过渡和不透明度过渡。因此,visibility属性用于禁用元素的鼠标事件,而opacity用于视觉效果。然而,必须注意不要在播放视觉效果时隐藏该元素,否则该元素将不可见。在这里,可见性转换的特殊语义变得很方便。隐藏元素时,该元素在播放视觉效果时保持可见,然后隐藏。另一方面,当显示元素时,可见性转变使元素立即可见,即在播放视觉效果之前。

qf9go6mv

qf9go6mv4#

如果你想延迟可见性,那么下面的代码片段可能是一个解决方案。
因为'visibility'属性是开/关的,所以可以使用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>
368yc8dk

368yc8dk5#

兄弟,你只需要在transition中添加延迟属性,然后使用opacity ..
检查一下(我使用的是chakraUI和React,但它与普通CSS的逻辑相同,毕竟,任何东西都可以转换为普通CSS......):

<Box
      display="flex"
      gap="2"
      flexWrap="wrap"
      visibility={shouldBeVisible ? 'visible' : 'hidden'}
      opacity={shouldBeVisible ? '1' : '0'}
      transition={
         shouldBeVisible
            ? 'opacity .3s linear'
            : 'visibility 0s linear .4s, opacity .3s ease-in-out'
        }
>
{YOUR COMPONENTS}
<Box>

注意,我使用visibility 0s linear .4s, opacity .3s ease-in-out this .4s来延迟可见性隐藏,当它等待隐藏时,实际的aim转换将在opacity属性上运行。

相关问题