CSS 动画完成后应该 :hover 伪状态样式更改工作

Posted

技术标签:

【中文标题】CSS 动画完成后应该 :hover 伪状态样式更改工作【英文标题】:Should :hover pseudo state style change work after CSS animation completes 【发布时间】:2015-01-02 21:33:41 【问题描述】:

在 CSS 动画在元素上完成运行后,是否应该在 :hover 等伪状态上指定样式更改?

编辑:也许更相关的是,我应该问:为什么在动画上应用“向前”会阻止更具体的样式更改被覆盖?

编辑 2:原来这实际上是一个跨浏览器问题。例如。 Chrome(我运行的是版本 38.0.2125.111)行为不正确,但 Firefox 会按照规范处理它。

长话短说:根据规范(由下面的 chrona 引用),将 !important 添加到覆盖应该呈现样式。但是,目前只有 Firefox 能正确处理这个问题。

这是一个简化:

@keyframes go 
  0% 
    background: green;
  
  100% 
    background: pink;
  


@-webkit-keyframes go 
  0% 
    background: green;
  
  100% 
    background: pink;
  


.box 
  animation: go 3s forwards;
  -webkit-animation: go 3s forwards;
  


.box:hover 
    background: orange!important;
  cursor: pointer;
 
<div class="box">Hover states don't work after animation</div>

我无法找到与此相关的信息,规范中也没有任何内容:http://www.w3.org/TR/css3-animations/

有人知道a) 这应该是可能的吗? b) 动画结束后如何使悬停状态在元素上起作用?

【问题讨论】:

【参考方案1】: a)

关于为什么会发生,我不能肯定地说。但这显然与您设置为forwardsanimation-fill-mode 属性有关。根据定义,将元素的视觉样式设置为动画的最后一个关键帧:

转发 动画结束后(由其动画迭代计数确定),动画将应用动画结束时间的属性值。

MDN's definition 更清楚一点:

转发 目标将保留执行期间遇到的最后一个关键帧设置的计算值。最后遇到的关键帧取决于animation-direction和animation-iteration-count的值:

但我不知道为什么它不允许:hover 状态覆盖样式。

b)

现在,关于如何使其工作,您可以从动画中删除 forwards 属性。在这种情况下,您需要反转动画,因此元素的原始状态(当动画结束并移除视觉效果时)是您希望它被固定的颜色:

@keyframes go 
  0% 
    background: pink;
  
  100% 
    background: green;
  


@-webkit-keyframes go 
  0% 
    background: pink;
  
  100% 
    background: green;
  


.box 
  animation: go 2s;
  -webkit-animation: go 2s;
  -webkit-animation-direction: reverse;
  animation-direction: reverse;
  background: pink;


.box:hover 
    background: orange;
  cursor: pointer;
 
<div class="box">Hover states don't work after animation</div>

【讨论】:

是的,:hover 无法覆盖 forward 设置的值是我最好奇的部分。 我将暂时保留标记作为答案,以防万一有人能找到任何官方信息,说明为什么 forward 值会阻止通过 hover 工作进行更改。 旁白:您修改后的 sn-p 在 Firefox 上的行为与问题中的行为略有不同。背景颜色悬停效果在问题版本中的动画期间有效,但直到动画在此版本中结束时才有效。 编辑: 这是由 chrona 的答案中的引用解决的,它应该是如何工作的【参考方案2】:

其实我不太明白你的问题,可能你需要这样的效果吗? http://jsfiddle.net/abruzzi/5td8w6jx/

@keyframes go 
    0% 
        background: green;
    
    100% 
        background: pink;
    

@-webkit-keyframes go 
    0% 
        background: green;
    
    100% 
        background: pink;
    



.box 
    animation: go 3s forwards;
    -webkit-animation: go 3s forwards;

.box:hover 
    -webkit-animation: none;
    background: orange;
    cursor: pointer;

但是,使用这些代码,当您将鼠标移出文本时,动画将被重播。

【讨论】:

【参考方案3】:

引自CSS Animations Working Draft

CSS 动画影响计算的属性值。在动画执行期间,属性的计算值由动画控制。这会覆盖在正常样式系统中指定的值。 动画会覆盖所有常规规则,但会被 !important 规则覆盖

再往下一点(Animation Duration):

[...] 和向前填充的动画将保留在 100% 关键帧处指定的值,即使动画是瞬时的。此外,仍然会触发动画事件。

当您为background 设置动画时,默认情况下不能覆盖它(!important 规则除外)。如果你不想使用!important,你应该去LcSalazar's answer。 (目前只有 Firefox 会按照规范 [2014 年 11 月 6 日] 中的描述做出反应)

@keyframes go 
  0% 
    background: green;
  
  100% 
    background: pink;
  


@-webkit-keyframes go 
  0% 
    background: green;
  
  100% 
    background: pink;
  


.box 
  animation: go 3s forwards;
  -webkit-animation: go 3s forwards;
  


.box:hover 
    background: orange !important;
  cursor: pointer;
 
<div class="box">Hover states don't work after animation</div>

【讨论】:

但这是我的问题——即使我将!important 应用于悬停状态,它也不起作用(例如,就像你的例子)。但是,我现在意识到这是一个 Chrome 错误(我正在运行版本 38.0.2125.111)。当我在 Firefox Aurora 中尝试时,它按预期工作(按照规范) 刚刚注意到了,它在 Firefox 中有效,但目前在 IE、Chrome 或 Opera 中无效,我将把它添加到我的 anwser

以上是关于CSS 动画完成后应该 :hover 伪状态样式更改工作的主要内容,如果未能解决你的问题,请参考以下文章

CSS动态伪类

jQuery动画CSS,设置回悬停状态

CSS3:动画之间的平滑过渡:hover

关于css伪类,伪元素详解总结

CSS 六边形边框hover闭合动画效果

css中伪类/伪元素详解