Using Font-Icons in Place of SVG for CSS3 Animations

NOTE: this is an older post. As support climbed has for SVGs, and IE7 is no longer a great concern for backwards compatibility, I have shifted towards using SVGs. In particular, positioning SVGs is far superior. I’ve kept this post for posterity.

SVGs are truly fantastic. Size something as much as you like, modify that to the viewport? Yes, please. They are also perfectly fit for animation tasks, particularly with flat design. There is an alternative to SVGs for cases when you would like the fallback for the animation that has great support back to IE7 and it works with animations: font-icons.

Why use font-icon?

SVG is still unsupported in most older browsers, some mobile devices don’t play well with them, and they come with performance problems. Injecting them directly into the page causes a bloat of the html source, in some browsers the rendering causes a strange scrolling effect. Some people solve this problem with an iframe. This, for me, was a abysmal compromise. Using font-icon for a job that should be done with SVG might seem like a hack, but arguably, requiring an iframe to keep a SVG stable is similarly bad.  (Ray Blackburn talks about iframe best practices here). Even if you call upon them through import from another file, backwards compatibility can become a problem. The use of font-icons solves both of these issues and is supported back to IE7. There is only one HTTP request. No code bloat. It renders beautifully on mobile and they are so easy to use and scale because everyone already knows how to work with fonts- the same rules apply.

The cool thing about font-icons is that you are still using SVGs. Fonts are simply a collection of SVGs that you are asking your browser to designate as letters. Fonts are widely supported, very stable and easy to scale and manipulate. Every front-end developer already knows how to work with fonts, and, best of all, you can do all this without taking on a whole library for support

Is this a solution forever? No. It’s a pragmatic solution until support for SVG climbs, and hopefully becomes less complex and bulky.

Getting set up

There are some things you will want to do to make this technique most effective:

1) Leverage modernizr. This will help generate a hook for browsers that don’t support the animation, so that you can let them know what they are not seeing. Preferably with a modal and overlay that give them a link to newer browsers, such as chrome, firefox or opera.

The JavaScript to hook to that modal would look like this:

window.onload = setup;
      function setup() {
        var dismiss = document.getElementById("close");
        dismiss.onclick = hide;
      function hide() {
        document.getElementById("warning").className = "hide";

2) Remove prefixes. There are now many ways of accomplishing this. Lea Verou created a very simplified Javascript version called prefixfree that is only 2kb minified. Many IDEs are now including this functionality; Codekit now has autoprefixr and Grunt has a nice auto prefixer that you can add to your build. Removing prefixes is essential, not just a luxury. I did an experiment where I made a 15 second animation, and then stripped it of its prefixes. It was 75% smaller! If you have a multi-part series, animation code bloats very quickly if all prefixes are not removed.

3) Create storyboards for the animations. This is vital as it helps you figure out what and when each step will happen. Once you start chaining events, if you don’t know your delays on certain pieces of the animation, you make a lot of work for yourself unless you have a solid plan to work off. There are also places where you may need to plan user interaction and build Javascript, so knowing what and where these events happen is critical.

How to use them

First, we create the image, or character we would like to work with:

Then we save off a folder of layers by color, as SVG. In Illustrator, select the color. The go to Select> Same> Fill Color:

If you work in Photoshop you might consider using the Zeick tool, which takes any layer and automatically makes it an SVG.
Either way, keep the layers a consistent size in your canvas — this is critical!

Then you can bring the SVG into Icomoon or Fontographer5:

You create a custom font from the SVGs by selecting them, and then load the fonts as you would with any self-hosted webfont with @fontface (icomoon even comes with a demo build so using it is just a matter of changing the directories)

By keeping them a consistent size, you can now put all of them in a div,  z-index them for order and add color values. You can then use them independently or move the entire div around as well. Keep in mind that the default animation origin is center, and if you want to move that icon from a particular side, you will have to specify this in your parameters.

.lt-yellow [class^="icon-"] { 
	color: #fcc589; 
	z-index: 5;
	position: relative; 
.periscope [class^="icon-"] {
	color: #bacad3; 
	z-index: 3; 
	position: absolute;
  top: 25px;
	animation: periscope 5s ease-in-out 7s 2;

.propellor [class^="icon-"] { 
	color: #bacad3; 
	z-index: 20; 
	position: absolute;
	animation: propellorMove 2s linear infinite;
	font-size: 9rem;
	top: 390px;
	left: 413px;

In this small piece of the css markup I chose three divs to look at more closely: the light yellow body, the periscope and the propellor. Here you can see that the light yellow is positioned relatively to the other pieces of the submarine body and then just z-indexed in place and given a color like you would a font. the propellor, on the other hand, and the periscope, are absolutely positioned. This is done because they have to move independently of the submarine, and their transform origins have to be centered based on themselves and no other objects.

Then, all you need to do is call on the icons in your css and move them around with css animations and keyframes. It’s super simple and the code is very light. Check out the full animation on codepen to see it all put together.

See the Pen Submarine by Sarah Drasner (@sdras) on CodePen.

Responsive is also a breeze if you use Relative Ems (rems) for font-sizing and adjust to the container. All of this is supported on mobile browsers.

You can also specify 3 icons per div using the :before and :after pseudo classes (for those of you scared of animating that in chrome, this bug was fixed last year).

To Illustrate what exactly is happening in this tutorial, I broke the @font-facing to show what’s happening:

See the Pen Submarine- Broken by Sarah Drasner (@sdras) on CodePen.

Benefits and limitations

If you are working with flat design, or objects that you would normally build with CSS, font-icons can work really well. In particular, they can provide much better CSS animation performance than something like HTML5 Canvas, especially when you need to move animations around. Canvas redraws the whole surface when an animation is moved and thus has much poorer performance. (There are some good comparison numbers available on Stack Overflow.)

On the other hand, if you need heavy gradients, this might not work for you as the only option is clipping masks — a webkit specific feature. If you are making a very detailed illustration, Canvas is a much better tool as it can create highly rendered objects, although the code is bulkier for a simple animation.

This post was part of a larger talk for Html5DevConf and DevCon5, for which you can view the Slides.

« Previous Post
Next Post »

ONE COMMENT ON THIS POST To “Using Font-Icons in Place of SVG for CSS3 Animations”

  1. Stefan Bauer July 22, 2016 at 3:15 pm

    Pretty exiting work you did by just using fonts.

    Personally I tend more to use SVG for the most common scenarios. If someone for example have choosen to render only a specific font on his/her device this animation will propably break because it contains elements not included in a regular font.

    On the other hand for SVG i just use symbols sets everywhere and with SVG4Everybody there is a good support for mobile device browser too. In addition the original HTML will not bloat.

    Overall really well done. I wasn’t aware to create such smooth animation with a font. ;)


Leave a Reply

Latest Tweets