当在伪元素上设置 'display' 属性时,CSS3 动画并不总是运行

标签 css css-animations css-transforms

我遇到的问题是在尝试对网络字体进行动画处理时发生的。具体来说,如果 HTML 元素有一个类在 :before 元素上定义 font-family 和其他所需的 CSS 属性,而不是元素本身,则伪内容将变得动画。

这里是一些 CSS 示例:

@font-face {
  font-family: 'FontAwesome';
  src: /** src urls here... **/
}

.fa-before:before,
.fa {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-refresh:before {
  content: "\f021";
}

.spinning-loader {
  -webkit-animation: fa-spin 2s infinite linear;
  animation: fa-spin 2s infinite linear;
}

@-webkit-keyframes fa-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(359deg);
    transform: rotate(359deg);
  }
}
@keyframes fa-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(359deg);
    transform: rotate(359deg);
  }
}

现在关键部分是我的 fafa-before:before 选择器。

如果我使用 fa-before 类,可以很好地设置我的 :before 内容的正确 font-family 。此外,普通的 fa 也适用于 :before 内容(我认为任何其他内容也一样)。

问题是,如果一个元素有 fa-before,它就不会产生动画(至少,不是所有浏览器都会产生动画)。

<!-- This doesn't always animate -->
<i class="fa-before icon-refresh spinning-loader"></i>

<!-- This DOES always animate -->
<i class="fa icon-refresh spinning-loader"></i> 

当它起作用时:

When it works

当它不起作用时:

When it doesn't work

这是一个 JSFiddle,因此您可以在自己的浏览器中进行测试:https://jsfiddle.net/b3gojahs/1/

以下是我能够测试的所有浏览器:

  1. 工作地点:
    • Mac OS X 10.10.5
      • Chrome 47.0.2526.111
    • Windows 10.0.10240
      • IE 11.0.10240.16644
      • 边缘10.10240.16384.0
  2. 不适用于:
    • Mac OS X 10.10.5
      • Chrome 金丝雀 50.0.2639.0 (!!)
      • Safari 9.0.3 (10601.4.4)
      • 火狐44.0
    • Windows 10.0.10240
      • Chrome 48.0.2564.97
      • 火狐44.0

有人知道为什么会出现这种情况吗?我似乎找不到任何关于这个问题的文章。

最佳答案

为什么应用 fa-before 类时动画不起作用?

问题是因为i element is an inline element by default CSS 转换不适用于内联元素。内联元素不是可变形元素。

As per W3C Spec:

Transforms apply to transformable elements.

transformable element

A transformable element is an element in one of these categories: an element whose layout is governed by the CSS box model which is either a block-level or atomic inline-level element, or whose display property computes to table-row, table-row-group, table-header-group, table-footer-group, table-cell, or table-caption [CSS21]

atomic inline-level element

Inline-level boxes that are not inline boxes (such as replaced inline-level elements, inline-block elements, and inline-table elements) are called atomic inline-level boxes because they participate in their inline formatting context as a single opaque box.

fa类应用于元素时,元素的显示通过CSS更改为inline-block,因此通过应用的动画.spinning-loader 选择器按预期工作。

但是,当对元素应用 fa-before 类时,只有 i:before 伪元素获得显示更改为内联 block i 本身的显示设置不会更改,并且仍然是默认的 inline 设置。因此,i 上的动画没有效果。


解决方案是什么?

解决方案与 Paulie_D's answer 中提到的完全相同。应用变换动画的父 i 元素应作为 block 或内联 block 元素。

i.spinning-loader {display: inline-block;} /* this setting should solve it */

注意: Chrome 中的行为有点不稳定(至少在我的电脑上 - v43 + Win 7)。当我对 fiddle 进行任何更改时,它会自动开始工作,关闭然后重新打开它。我对此没有任何解释,但 Firefox 是完美的。


为什么它可以在某些浏览器上运行?

这是我目前没有答案的事情。唯一的原因可能是他们以不同方式对待 i 元素并将其默认显示设置设置为 block 或内联 block 。

关于当在伪元素上设置 'display' 属性时,CSS3 动画并不总是运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35183494/

相关文章:

css - 如何使用CSS 3D让子元素垂直于父元素显示?

CSS - 字母后面的阴影

css - 表单 :checkboxes in Spring MVC 的元素属性

php - Bootstrap 样式不影响 Php 生成的菜单

CSS 动画 - 微调器/加载器速度

javascript - 平滑过渡标题导航类

html - css:将颜色混合到现有背景颜色中的类?

html - CSS悬停效果未完全覆盖所有图像

javascript - jQuery 在函数和动画开始/动画结束事件上的问题

html - skew() 函数深入