The problem I am running into occurs when trying to animate a web font. Specifically, if the HTML element has a class that defines the font-family
and other needed CSS attributes on the :before
element as opposed to the element itself, the pseudo content will not get animated.
Here is some sample 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);
}
}
Now the key part is my fa
and fa-before:before
selectors.
If I use the fa-before
class, that works fine to set the correct font-family
of my :before
content. Additionally, plain fa
also works fine for the :before
content (and I think any other content too).
The problem is, if an element has fa-before
, it doesn't animate (at least, not all browsers animate it).
<!-- 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:
Here is a JSFiddle so you can test in your own browser: https://jsfiddle.net/b3gojahs/1/
Here are all the browsers I've been able to test:
- Works in:
- Mac OS X 10.10.5
- Chrome 47.0.2526.111
- Windows 10.0.10240
- IE 11.0.10240.16644
- Edge 10.10240.16384.0
- Mac OS X 10.10.5
- Doesn't work in:
- Mac OS X 10.10.5
- Chrome Canary 50.0.2639.0 (!!)
- Safari 9.0.3 (10601.4.4)
- Firefox 44.0
- Windows 10.0.10240
- Chrome 48.0.2564.97
- Firefox 44.0
- Mac OS X 10.10.5
Anyone know why this is occurring? I can't seem to find any articles on this issue.
The issue seems to be setting the
Is you just make this
It works just fine - JSFiddle
Why does the animation not work when fa-before class is applied?
The problem is because
i
element is an inline element by default and CSS transforms don't work on inline elements. Inline elements are not transformable elements.When the
fa
class is applied on the element, the element's display is changed toinline-block
via the CSS and so the animation that is applied through.spinning-loader
selector works as expected.However when the
fa-before
class is applied on the element, only the:before
pseudo-element of thei
gets the display changed toinline-block
. The display setting of thei
itself doesn't change and it remains as the defaultinline
setting. Because of this, the animation on thei
has no effect.What is the solution?
Solution is exactly the same that is mentioned in Paulie_D's answer. The parent
i
element on which the transform animation is applied should be made as a block or an inline-block element.Note: The behavior in Chrome is a bit erratic (atleast on my PC - v43 + Win 7). It starts working automatically when I make any change to the fiddle, close and then reopen it. I have no explanation for this but Firefox is perfect.
Why does it work on some browsers?
This is something to which I don't have an answer at present. The only reason could be that they treat the
i
element differently and set its default display setting as block or inline-block.