【问题标题】:CSS3 animations don't always run when 'display' attribute is set on a pseudo element在伪元素上设置“显示”属性时,CSS3 动画并不总是运行
【发布时间】:2016-02-04 14:18:27
【问题描述】:

我遇到的问题是在尝试为网络字体设置动画时发生的。具体来说,如果 HTML 元素有一个类定义 font-family:before 元素上的其他所需 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> 

当它起作用时:

当它不起作用时:

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

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

  1. 适用于:
    • Mac OS X 10.10.5
      • 铬 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 Canary 50.0.2639.0 (!!)
      • Safari 9.0.3 (10601.4.4)
      • 火狐44.0
    • Windows 10.0.10240
      • 铬 48.0.2564.97
      • 火狐44.0

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

【问题讨论】:

    标签: css css-animations css-transforms


    【解决方案1】:

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

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

    根据W3C Spec

    变换适用于可变换的元素。

    可变形元素

    可变形元素是属于以下类别之一的元素: 一个元素,其布局由 CSS 盒模型控制,该模型是块级或原子内联级元素,或者其显示属性计算为 table-row, table -row-group、table-header-group、table-footer-group、table-cell 或 table-caption [CSS21]

    原子内联级元素

    非行内框的行内层框(例如被替换的行内层元素、行内块元素和行内表元素)称为原子行内层框,因为它们作为一个单独的行内格式化上下文参与不透明的盒子。

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

    但是,当 fa-before 类应用于元素时,只有 i:before 伪元素将显示更改为 inline-blocki 本身的显示设置不会改变,它仍然是默认的inline 设置。因此,i 上的动画没有效果。


    解决办法是什么?

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

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

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


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

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

    【讨论】:

    • 太好了,这种洞察力正是我希望有人能够提供的。感谢您的帮助!
    【解决方案2】:

    问题似乎是设置

    .fa-before:before{
      display: inline-block;
    }
    

    这是你自己做的吗

    .fa-before {
      display: inline-block;
    }
    

    效果很好 - JSFiddle

    【讨论】:

    • 谢谢,这确实解决了问题。但是,您是否知道任何详细说明此内容的文档?也就是说,为什么设置可以解决问题?
    • 不是随便我必须做更多的研究。
    猜你喜欢
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多