html - 为什么动画在悬停时暂停在IE中起作用,但在Chrome或Edge中不能起作用?

标签 html css css3 css-animations

我让HTML和CSS在同一个地方创建一个包含3个图像的滚动幻灯片。我想让动画在我悬停在任何图片上时暂停,然后在我停止悬停时动画停止的地方重新启动。以下代码适用于Internet Explorer,但不适用于Chrome或Edge。我需要它在任何浏览器中工作。有人能告诉我我做错了什么吗?

div.slideshow3 {
  position: relative;
  height: 300px;
  width: 300px;
}
div.slideshow3 figure {
  margin: 0;
  position: absolute;
}
div.slideshow3:hover figure {
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}
div.slideshow3 figure:nth-child(1) {
  -webkit-animation: xfade3 15s 10s infinite;
  animation: xfade3 15s 10s infinite;
}
div.slideshow3 figure:nth-child(2) {
  -webkit-animation: xfade3 15s 5s infinite;
  animation: xfade3 15s 5s infinite;
}
div.slideshow3 figure:nth-child(3) {
  -webkit-animation: xfade3 15s 0s infinite;
  animation: xfade3 15s 0s infinite;
}
@-webkit-keyframes xfade3 {
  0% {
    opacity: 1;
  }
  31.3% {
    opacity: 1;
  }
  33.3% {
    opacity: 0;
  }
  98% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes xfade3 {
  0% {
    opacity: 1;
  }
  31.3% {
    opacity: 1;
  }
  33.3% {
    opacity: 0;
  }
  98% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

<div class="slideshow3">
  <figure>
    <img src="http://lorempixel.com/300/300/nature/1" style="width:300px; height:300px;">
  </figure>
  <figure>
    <img src="http://lorempixel.com/300/300/nature/2" style="width:300px; height:300px;">
  </figure>
  <figure>
    <img src="http://lorempixel.com/300/300/nature/3" style="width:300px; height:300px;">
  </figure>
</div>

最佳答案

首先,Chrome和Edge中的行为是正确的,这可能就是为什么微软在他们最新的浏览器中纠正了这种行为。
它不起作用的原因很简单。悬停选择器(暂停
动画)与设置动画的其他选择器具有相同的特殊性,此外,其他选择器在CSS文件中的悬停选择器之后指定。这使得它们在任何时间点都优先于悬停选择器(即使悬停处于启用状态)。因此,animation-play-state永远不会设置为paused,因此动画继续运行。
让我们逐一了解一下这些选择器的特殊性:
div.slideshow3:hover figure
上面选择器中的ID选择器的数量是0(所以a=0)
其中类/属性/伪类选择器的数目是2(所以b=2)
其中类型/伪元素选择器的数目是2(所以c=2)
所以,它的总特异性是022。
div.slideshow3 figure:nth-child(1)
上面选择器中的ID选择器的数量是0(所以a=0)
其中类/属性/伪类选择器的数目是2(所以b=2)
其中类型/伪元素选择器的数目是2(所以c=2)
因此,这个函数的总体特异度也是022,但稍后在CSS文件中指定。
您可以阅读更多关于CSS选择器特殊性here
您可以通过以下两种方式解决此问题:
hover选择器移到所有动画定义选择器下面。这使得hover选择器优先于其他选择器,因此当容器悬停在上时将暂停动画。这是最简单的解决办法。

div.slideshow3 {
  position: relative;
  height: 300px;
  width: 300px;
}
div.slideshow3 figure {
  margin: 0;
  position: absolute;
}
div.slideshow3 figure:nth-child(1) {
  -webkit-animation: xfade3 15s 10s infinite;
  animation: xfade3 15s 10s infinite;
}
div.slideshow3 figure:nth-child(2) {
  -webkit-animation: xfade3 15s 5s infinite;
  animation: xfade3 15s 5s infinite;
}
div.slideshow3 figure:nth-child(3) {
  -webkit-animation: xfade3 15s 0s infinite;
  animation: xfade3 15s 0s infinite;
}
div.slideshow3:hover figure {
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}
@-webkit-keyframes xfade3 {
  0% {
    opacity: 1;
  }
  31.3% {
    opacity: 1;
  }
  33.3% {
    opacity: 0;
  }
  98% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes xfade3 {
  0% {
    opacity: 1;
  }
  31.3% {
    opacity: 1;
  }
  33.3% {
    opacity: 0;
  }
  98% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

<div class="slideshow3">
  <figure>
    <img src="http://lorempixel.com/300/300/nature/1" style="width:300px; height:300px;">
  </figure>
  <figure>
    <img src="http://lorempixel.com/300/300/nature/2" style="width:300px; height:300px;">
  </figure>
  <figure>
    <img src="http://lorempixel.com/300/300/nature/3" style="width:300px; height:300px;">
  </figure>
</div>

另一种方法是将悬停选择器指定为div.slideshow3:hover figure:nth-child(n)。这意味着选择器中有3个类/伪类选择器,因此特定性变得比其他选择器更高。nth-child(n)基本上是全选,所以这不是问题。
div.slideshow3 {
  position: relative;
  height: 300px;
  width: 300px;
}
div.slideshow3 figure {
  margin: 0;
  position: absolute;
}
div.slideshow3:hover figure:nth-child(n) {
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}
div.slideshow3 figure:nth-child(1) {
  -webkit-animation: xfade3 15s 10s infinite;
  animation: xfade3 15s 10s infinite;
}
div.slideshow3 figure:nth-child(2) {
  -webkit-animation: xfade3 15s 5s infinite;
  animation: xfade3 15s 5s infinite;
}
div.slideshow3 figure:nth-child(3) {
  -webkit-animation: xfade3 15s 0s infinite;
  animation: xfade3 15s 0s infinite;
}
@-webkit-keyframes xfade3 {
  0% {
    opacity: 1;
  }
  31.3% {
    opacity: 1;
  }
  33.3% {
    opacity: 0;
  }
  98% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes xfade3 {
  0% {
    opacity: 1;
  }
  31.3% {
    opacity: 1;
  }
  33.3% {
    opacity: 0;
  }
  98% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

<div class="slideshow3">
  <figure>
    <img src="http://lorempixel.com/300/300/nature/1" style="width:300px; height:300px;">
  </figure>
  <figure>
    <img src="http://lorempixel.com/300/300/nature/2" style="width:300px; height:300px;">
  </figure>
  <figure>
    <img src="http://lorempixel.com/300/300/nature/3" style="width:300px; height:300px;">
  </figure>
</div>

注意:尽管在执行上述更改之一之后,hover选择器优先,但动画仍然不会仅在Edge中暂停。上面提到的更改确实解决了Chrome、Firefox、Safari中的问题,而且它也可以在IE11、IE10中工作。
边缘的行为似乎很不稳定。如果您第一次打开this demo,动画将运行,当您悬停时,它也将在边缘暂停,但如果您对代码进行任何虚拟更改并单击“运行”按钮,它将不再工作。这是无法解释的。我在this chat room中与其他几个用户进行了核对,每个人在Edge中都看到了相同的行为。
不幸的是,似乎没有办法让它发挥作用。我尝试了多种选择器组合(甚至尝试了JS的内联样式),但根本不考虑动画的播放状态变化。但是选择器工作得非常好。在下面的片段中,您可以注意到悬停时border的变化,但是动画没有发生任何变化。
div.slideshow3 {
  position: relative;
  height: 300px;
  width: 300px;
}
div.slideshow3 figure {
  margin: 0;
  position: absolute;
}
div.slideshow3:hover figure:nth-child(n) {
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
  border: 4px solid brown; /* hover border */
}
div.slideshow3 figure:nth-child(1) {
  -webkit-animation: xfade3 15s 10s infinite;
  animation: xfade3 15s 10s infinite;
  border: 4px solid red; /* default border */
}
div.slideshow3 figure:nth-child(2) {
  -webkit-animation: xfade3 15s 5s infinite;
  animation: xfade3 15s 5s infinite;
  border: 4px solid red; /* default border */
}
div.slideshow3 figure:nth-child(3) {
  -webkit-animation: xfade3 15s 0s infinite;
  animation: xfade3 15s 0s infinite;
  border: 4px solid red; /* default border */
}
@-webkit-keyframes xfade3 {
  0% {
    opacity: 1;
  }
  31.3% {
    opacity: 1;
  }
  33.3% {
    opacity: 0;
  }
  98% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes xfade3 {
  0% {
    opacity: 1;
  }
  31.3% {
    opacity: 1;
  }
  33.3% {
    opacity: 0;
  }
  98% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

<div class="slideshow3">
  <figure>
    <img src="http://lorempixel.com/300/300/nature/1" style="width:300px; height:300px;">
  </figure>
  <figure>
    <img src="http://lorempixel.com/300/300/nature/2" style="width:300px; height:300px;">
  </figure>
  <figure>
    <img src="http://lorempixel.com/300/300/nature/3" style="width:300px; height:300px;">
  </figure>
</div>

关于html - 为什么动画在悬停时暂停在IE中起作用,但在Chrome或Edge中不能起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34192358/

相关文章:

javascript - Chrome v51.0.2704.79 上引入的错误 m 无法清空大选择

java - Android html.fromHtml 不工作

html - 如何更改 SharePoint RichHtmlField 中的段落格式

html - 如何使用 CSS HTML 将圆向下移动 15px

html - 仅CSS的砌体布局

php - 页面加载时显示查询结果

javascript - 使用 data-html 和 box2dweb 的 Bootstrap 工具提示

css - 最大高度转换』不起作用?

html - 仅CSS的砌体布局

css - flex-basis和width有什么区别?