Did you know that you can animate the content
property of pseudo elements? According the list of animatable properties in the spec, you shouldn’t be able to, but in the latest version of desktop Chrome you can. The demo below should animate from “A” to “B” by changing the content
property inside a @keyframes
animation:
The code
To make a letter-switching demo like above, we make an empty <div>
that we’ll fill with the content
of its pseudo element, like so:
<div class="letter-changer"></div>
And then we set the content
of its pseudo element to change as we might any other CSS property, by making a new @keyframes
animation and setting it up with the animation
property:
@keyframes changeLetter {
0% {
content: "A";
}
50% {
color: white;
}
100% {
content: "B";
}
}
.letter-changer::after {
animation: changeLetter 3s linear infinite alternate;
}
Could this be useful?
The fact that it doesn’t work in most browsers and is non-standard makes it a bit risky to use. But there is that whole paving-cowpaths thing (i.e. if it’s clearly useful it could be standardized).
In a post last week I described a method for incrementing the numbers inside a loading bar. It used this very concept to increment the numbers. Here’s another example in that vein: a countdown!
Browser support
In my own testing animating content
has only worked in stable desktop Chrome (v46 at time of writing). No support anywhere else. No Safari on desktop or iOS. No Firefox. No IE. Each of these browsers will ignore the animation, showing only the original content
in the pseudo element.
It might be a handy trick in some distant future or it might never be supported by anything. Non-standard features are always at least at some risk of being deprecated, so this Chrome support may not last forever.
Peaking at browser support for this again in September 2017: Works in Chrome/Mobile, Firefox, and Opera, but not in IE, Edge, or iOS.
Peaking at browser support for this again in October 2020: Edge went Chrome, so that’s solved. IE support is getting rarer and rarer. Still no iOS support.
If you need to change content in a cross-browser friendly way
Use JavaScript.
I feel that even having a content attr. in css is very wrong!
Why? It comes in handy in a bunch of different situations like clearfix , creating borders of different widths, etc.
+1 Adrian
I feel the same, css should deal with styling not the content
The animation is coming through loud and clear on mobile Chrome for Android. I’m sort of with Kino on this though, while I could see this being fun to mess around with conceptually, it freaks me out to think of having content generated, and not just styled, by CSS. I’d prefer to program countdowns, loading percent labels, etc. wherever the rest of my content is, rather than relinquish control to my CSS file.
About the only case where I don’t frown upon the content attribute is when it’s used for font icons, and I think this feature could be handy for animating icons.
Well done Robin and Chrome – bring on cross-over code! Sacrificing utility for a set of demarcations decades old (and meant to deliver research papers) just doesn’t make sense anymore. If it works, go for it!
On the subject of “No
content
whatsoever! D:<”content
is extremely useful for instances where touching the HTML is undesirable or difficult. Consider poorly-made Tumblr or probably WordPress styles you want to modify, or browser extensions which allow you to inject CSS. It’s also useful for information that would make the page somehow less accessible than if it were added throughcontent
such as a little flavor text or, as Herman mentioned, Icon Fonts.As for the article’s content, I don’t think I like this. Not only is it not-to-spec, but it’s rather limited in what it can be used for properly. I say mark it as a clever quirk and let it be.
Regarding the level of standardization of this feature:
The CSS Transitions draft spec, linked above, was last re-published two years ago (November 2013). A number of changes have been incorporated into the Editor’s draft since then, including a new approach to “animatable properties”.
While the old spec only supported animation on properties which could be continuously interpolated (numbers, colors, etc), the new draft allows pretty much any property to be animated, by applying discrete (stepped) transitions. The only properties that cannot be animated are those that would cause logical implementation issues with transitions or animations. This is essentially the approach used to define animatable properties in SVG/SMIL.
In other words, if there are not major problems with test implementations such as Chrome’s, this is likely to become standardized in future.
The
content
property is only one of many properties which are affected by this change. That said, the concerns of other commentators regarding usingcontent
for substantive text content are valid. Non-essential, decorative effects only, please!Great comment.
Useful, informative, nuanced, and well researched.
Thank you.
To Kino and Matt’s point, I feel that content within CSS does have its place. For instance I often use it to separate inline list items. IMO whether items are separated by |, commas, parentheses, that’s a design concern. Being able to animate it seems fair.
It seems to be working on Chrome for Android.
This is a very useful — and simple — new possibility for us web designers with CSS. :)
Robin, thank you for your discovery and demo.
Regarding the “CSS-is-just-for-styles” dogma — That’s theory over practicability — Makes no sense.
And, great to know from Amelia that this is being standardized.