Many animations on the web revolve around directly or indirectly animating text. As long as we optimize for performance by animating the filter,opacity and transform properties, animating text is just as mundane as animating any other element on the page. Well...except for one case: animating the size of our text. It doesn’t matter if we animate our text size by changing the font-size property (😱) or by setting a scale transform, the end result is rarely good. In this article, I’ll explain why animating the text size is a bad idea and some suggestions on what you can do if you have no way around having to implement this bad idea.
Take a look at the following screencapture where we are animating the size of some text by scaling the parent container:
Pay really close attention to the text as it increases in size. What we’ll see is a series of stages where the text goes from being very crisp, to being a bit blurry, jumping to a few pixels in position, and then snapping back to being really crisp again when the animation reaches a stopping point. If we slow the screencapture down, we can see all of this more clearly:
The reasons for this odd behavior have to do with how every device deals with text. Because of how important text is to everything on the web, our browsers and operating systems do a lot of complex optimizations to ensure our text appears as legible as possible. These optimizations all have some really cool names like font smoothing, cleartype, subpixel antialiasing, M. Night Shyamalan, and so on. Much of this happens outside of our control. When we animate the size of text, while the text is animating, many of these optimizations are temporarily toggled on and off. When the text size stops animating, the optimizations are applied again. This constant change from optimized to unoptimized text plays a large role in what causes our text to look really odd when its size is animated.
There will be times when the decision to animate text size will be out of your control, and you will have no choice but to do this. In these situations, the following tips will help reduce the intensity of the problem.
For performance reasons, animating transforms is generally a good idea. This is also true when it comes to animating the size of text. While you can get away with animating the font-size CSS property, you should animate the scale transform instead:
The font-size property isn’t optimized for animations, and the jump between font sizes is not something that animates well. This is especially true when dealing with fonts that are finicky about their font size. One thing to clarify: animating the transform will only make your text scale performantly. It won't solve the weird display issues.
In our two examples above, when the animation was fast, the weird text scaling behavior wasn’t quite as noticeable as the slowed down version. Play with various shorter duration values to see what gives you the best results. If speeding things up works in real-life magic shows to maintain the realism, it is bound to work in our CSS world as well, right?
For reasons that probably fall under the same bucket as complex optimizations our browsers and operating systems perform on text, making the text smaller exhibits fewer issues than making the text larger:
In this variation, I can’t see any weirdness in the text as the animation is progressing, at least in Chrome on macOS. This all could change when previewed on a different device or combination of OS/browser versions. Like I always like to joke around, we are just one OS or browser update away from internal implementation quirks like these from breaking.
This suggestion is probably far more complex than what you may need, but one option is to bypass all of the text rendering by converting your entire text and related elements into a bitmap (via the canvas) prior to animating them.
One can imagine that text scaling is an area of animation that the various browsers will improve at some point in the future. It's not as if animating the size of text is a bizarre and rare thing we are trying to do. It's a common animation pattern. It's just unfortunate that it doesn't work properly in our browsers today.