Inline SVG vs Icon Fonts [CAGEMATCH]

If you're building an icon system for a site, you have some options. If you know the icons need to be raster images, then you'll likely be using CSS sprites. If the icons will be vector images (much more common these days), you have some options. Two of those options are using inline SVG and using icon fonts.

Let's compare.

Icons are Vector

There are big advantages to vector icons: resizable up and down without losing quality, extra sharp on retina displays, and small file size among them.

Icon Font

Inline SVG

Browsers consider it text, so the icons are anti-aliased as such. Can lead to icons not being as sharp as you might expect.

Straight up vector

In a recent personal example, while converting some icons from fonts to SVG on CodePen, some of the font icons were noticeably less sharp than the ones I converted over.

CSS Control

Icon Font

Inline SVG

You can control the size (via font-size), color, shadows, rotation, etc. via CSS.

You have all the same CSS control as with a font, but better, because you can 1) control individual parts of a multi-part icon and 2) use SVG-specific CSS like stroke properties.

The big win for inline SVG here is probably multi-color icons.

Positioning

Icon Font

Inline SVG

It can be frustrating to position a font icon. The icons are inserted via pseudo element, and it depends on line-height, vertical-align, letter-spacing, word-spacing, how the font glyph is designed (does it naturally have space around it? does it have kerning information?). Then the pseudo elements display type affects if those properties have an effect or not.

SVG just is the size that it is.

See how the pseudo element box isn't quite where the glyph actually is.The SVG box is the size of the SVG.

Weird Failures

Icon Font

Inline SVG

An icon font might fail because 1) it's being loaded cross-domain without the proper CORS headers and Firefox doesn't like that 2) for any reason, the font file fails to load (network hiccup, server failure, etc) 3) There is some weird Chrome bug that dumps the @font-face and shows a fallback font instead 4) Surprising browser doesn't support @font-face.

Font failures are pretty common for a variety of reasons. Plus, if you try and do something clever like map icons to "Private Use Area" of unicode and the font fails, it may do something really weird like show an unexpected emoji, because the environment you're in uses that same area for emoji. Or that emoji might even overrule your glyphs!

Inline SVG is right in the document. If the browser supports it, it displays it.

Forced Failures

Icon Font

Inline SVG

Proxy browsers like Opera Mini or UC Browser don't support @font-face at all, even though they sometimes report that they do. So even if you try to feature detect, it may fail.

Semantics

Icons are little images. The semantics of <svg> says "I'm an image." Seems better to me.

Accessibility

Icon Font

Inline SVG

You have to be quite careful with icon fonts to make sure you do it in an accessible way. You should basically do everything in this article. You're always fighting to make sure that the icon itself isn't read (but something else is) and that hard-to-detect fail states are handled.

I'm no expert, but research suggests using the proper combination of elements and attributes (<title>, <desc>, and aria-labelledby) you can convey good information across the browser specturm. Plus no weird fail states.

Ease of Use

Icon Font

Inline SVG

Using a pre-created icon font was never particularly responsible (too many unused icons). Creating your own icon font was never overly comfortable. I think the best were Pictos Server (limited to Pictos icons) and IcoMoon (free login to save projects). Fontello has an API I didn't see it used to make a good build tool.

The inline SVG system is easier because you can do it all by hand if needed. Or use a tool like IcoMoon (exports either way). Or use a build tool.

Browser Support

Icon Font

Inline SVG

Very deep. Even IE 6.

Decent, but problems are IE 8- and Android 2.3-. Fallbacks doable but not wonderful.

Winner

It all comes down to browser support. If you can go IE 9+ / Android 3+, inline SVG is better at pretty much everything than icon fonts. If you need the deeper browser support, I feel like an inline SVG fallback would be too big of a pain to be worth it (maintaining a PNG copy, inserting an additional element to display PNG version, hiding SVG element... it's weighty).

Did you know that Microsoft EOLed Windows XP? This means IE8 is going down soon hopefully. You can check out slides from my talk here http://wojtiku.pl/speaking/ie8/ to get some arguments about the drop. It is really worth it!

About that, all you have to do for browsers support is to link your index with a modernizer.js file that you can search for and download easily. Therefore all browsers including ie8 will support html5 and css3 properties.

I have tried following your guides for creating the SVG (sprites). I created them manually but they always mess up. Ie: things like the svg and use elements are different sizes. They don’t seem to listen to edits made in the CSS panels. Only parts of them showing. Do you have any guidelines for how the SVG’s should be saved before being grouped together? I took an SVG from your CodePen and tried it and it’s fine. But my own and ones downloaded from icoMoon all seem to go horribly wrong. Thanks, Neil

What about performance? An icon font is a great way to reduce the number of HTTP requests by combining a huge amount of icons into a single file. You can even embed the font file as base 64 in your main css file.

Also, about “semantics”: I don’t consider an icon a “little image” as in that is not part of the content. An icon is part of the decoration, a visual hint or indication.

Regarding performance/HTTP requests, can’t you have an external SVG document with all of the icon definitions that gets referenced on the page via use tags? This would provide the benefits of caching, with minimal HTTP requests.

It seems like you could have a fallback that would AJAX in the external SVG, insert it in the DOM first thing after the body tag, then the use tags would work correctly, or perhaps need to be updated to take out the external reference and only use the id (from ＜use xlink:href="icon.svg#Menu"＞ to ＜use xlink:href="#Menu"＞).

That seems like a more elegant fallback than switching it out with object tags, and would allow browsers to cache the icons (fallback or not) and prevent the size of the actual HTML from ballooning.

Not disagreeing with your conclusion in general, but I think that fonts could win on semantics in at least some cases. I’m thinking mostly of situations where the icon accompanies the word it’s intended to convey, like: “[hamburger] Menu.”

In the case of SVG: there is semantically an image there, which to me implies that the image conveys more information than is included in the text. Visually it does, by providing a means of quick recognition without needing to read the actual word; semantically, though, it simply repeats.

In the case of the icon font: there’s a span there, which is by convention semantically neutral (in other words, it doesn’t give the appearance of conveying additional information).

It’s a minor quibble, and probably more a matter of perspective than anything. And, obviously, this doesn’t apply to situations where the icon stands alone or actually does convey additional information (like a sparkline or something).

I use and love grunticon (or at least the grumpicon webapp), but I feel like that implementation might be missing some of the benefits Chris mentions, because the SVGs are inserted as a background-image.

Take :hover/:active states, for example. With inline SVG you have the CSS control of stroke, fill, etc with the ability to animate or transition, but with grunticon, you’re forced to swap out the icon with another just to change the color. Each of those states adds to the weight of the CSS include, since you have multiple copies of the same icon.

I’d love to see a grunticon/grumpicon style tool for compiling a folder of SVGs into one document with all of the icons as definitions, accessible via the use tag. Just like grunticon, the tool could also create a PNG background-image (base64 encoded) fallback for IE8 and Android 2.3-, then a external PNG background-image fallback for IE7-.

(Forgive me if that doesn’t display correctly. The preview of it kept not displaying the code at all)

In your CSS, you would size the span and make the svg fit it with width: 100%; height: 100%(a viewbox attribute might be needed, I’m not sure). The fallback CSS would target the span to give it the PNG background-image with background-size: contain

I really don’t understand why to bother with IE 7, not even IE 8. Windows XP are EOL and I really can’t imagine why would anyone use IE 8 on Windows 7.

Number of users using IE 8 is so small that I don’t bother anymore. And yes, I prefer Statcounter statistics, as NetMarket Share has REALLY small statistic group (arond 45 000 websites) mostly from eCommerce and mostly from China. That’s really not something to take into account. Hit is a hit and if I can pick up, I would rather opt for much bigger statistic group from Statcounter (more than 5 millions).

Google Analytics on websites I administer tells me even smaller market share for IE 8 (not much above 5 %). Android 2.3 is already dead, as those devices are very, very old and are mostly used as a dumbphones.

Really guys, we should look forward, not backward and take care about users not being able to update their browser for 10 years. That’s neolithic age in terms of web and IT.

I’d be careful about forgetting about ~5% of traffic on sites you are developing.

What you might argue instead is that this is progressive enhancement (if it is in your case) and that the icons may be a nice to have but not required so can be dropped for IE8.

In general though I expect most of us will have to live with ensuring IE8 is at least usable on sites we develop for a while yet, just because MicroSoft have dropped support for XP doesn’t mean significant numbers of users won’t continue to use XP for a while yet.

Simon, I really don’t care. last 2 version, that’s my policy. Only thing I’m willing to do is to display warning about old browser with option to download another, new one. Allow users to still get to the site, but without any optimalization or fixes.

With policy to support neolithic browsers we would be still developing for IE 6. Really, users are able to buy newer phone, to update their music player app, to update stupid Flash, to update Acrobat, but they are not willing to update browser?

Glad you point that out about IE8- support. My inbox is full of newsletters spouting the latest insights on SVG but I cannot even begin to play with them because IE8 fallbacks are a pain. It’s not quite like doing without text-shadow or border-radius on IE8. SVG’s (and an icon system) would solve so many performance issues for us – my graphics guy just doesn’t understand what I go through to try to compress his bloated files.

My big hope is that with XP support gone, businesses and schools (from where the vast majority of our traffic comes) will soon be upgrading to Win7|8 and skip on up to IE10+. Then a whole new world of possibilities emerges. (Oh my goodness, I need to start learning more about …)

Another feature of SVG that I like is the true vector advantage of being able to resize the same image code. Here: http://maxw3st.us/svgshare/share_reveal.html the icons at the top of the page and those under the “share” panel are the same svg code resized. This can be handy if you want to resize images for RWD without getting into multiple copies of the image. Comments in the CSS code explain how I did it, just “view source”.

For most of them you just open the svg file in a text editor, copy it out, and paste it into the text view in your editor. If that gets ripped out, you’ll either need an extension/plugin that allows it or you’ll need to upload the svgs to your web server and call them like any other image.

I would use an element with SVG in src attribute. AJAX loading it inline for caching and with Modernizr fallback to .png (just to change an extension from svg to .png in img element) in case inline-svg is false.

Yeah, might be a problem if you want to colorize it but in that case I would use also .no-inline-svg class in stylesheet.

For accessibility and semantics, what’s wrong with using a ligature-based icon font and allowing it to be read normally? In case of font-face failure or the like, it just shows text instead, with no need for any markup beyond a simple class="icon".

Managing inline SVG on more complex projects is much less flexible than icon fonts + pseudo elements which can be added anywhere without changing markup.

If you go the inline SVG route and need to use the same icon multiple times on a page (say, share icons on every article), the size of your document will quickly balloon out too.

Agree with Flunch that I’d think icon fonts (much smaller, cacheable, no potential duplication of code) would have the performance upper hand over inline SVG. Anyone know of any test cases around this?

I’m using a SVG icon sprite sheet for a current project… compressed and base64’d into my stylesheet (see Chris’ post ‘Using SVG’ from a year ago and the video at the bottom http://css-tricks.com/using-svg/). I’ll provide a PNG sprite sheet fallback for old sucky browsers using Modernizr.

Icons are crisp as crisp can be, load is minimal, HTTP requests are reduced and it will work for one and all.

Performance: the browser is drawing the entire SVG for each icon, and on older Chrome/Firefox and all IE browsers you can sometimes notice lags when changing the position of a large sprite sheet.
No CSS control/interaction with the icon, it’s just treated as a static image. So you can’t change a colour on hover or have the icon match the surrounding font color without swapping in a different icon in the sheet. (Also no special SVG accessibility elements, but they are apparently not well supported anyway and you should have title/alt text on your spans the same as you would for PNG sprite icons.)

But if neither of those is a problem on your project there’s no reason to stop doing what you’re doing.

From the start I could tell SVG was going to win… until the last part about browser support.

A problem I have with inline SVGs is that you have aaaaaaaall the SVG code in the page making the markup, not necessarily “hard to read”, but making you visually skip all the SVG code to find/edit what you really need.

In my eyes, having icon fonts anti-aliased is really no big deal. At all. Hell, only the trained eye can see how miniscule the anti-aliasing really is, the end users can’t see that and they wouldn’t even care either.

Icon fonts being affected by line-height, vertical-align, letter-spacing, word-spacing, font-size, etc… Why is that a bad thing? Why is that a “big deal”? We deal with all those properties all the time for web fonts anyway, hell, even for system fonts! Honestly, I’ve personally never had to deal with vertical-align, letter-spacing, word-spacing when I’ve used icon fonts, ever.

I prefer not to use SVGs embedded in my markup but simply call an SVG file instead, just like if I’d be calling an image, which if you ask me, is the ideal way to use SVGs. The problem with that, which is a “red box” for me (Chris is using red boxes for the negatives), is that there’s no way to affect the SVG with CSS. Please tell me I’m wrong and that there actually IS a way to do it.

IE8 is still a major player, so dealing with PNG fallbacks and using icon fonts over SVGs is something I don’t plan to change any time soon. I’m sure others, many, are in the same boat with IE8.

Maybe it isn’t for you. There are lots of factors involved here. I find that one a tremendous pain in the ass, personally. It’s “here is a box of this exact size, position it predictably” vs “here is a box of unknown size in which the graphic within it may or may not line up with the edges of that box, good luck positioning me.”

I agree with everything you’ve said, though inline svg does have some drawbacks, mainly related to performance:

You can’t cache them. 10kb of embedded inline SVG has to be downloaded on every page load.
DOM overhead. Inline SVG is part of the DOM tree, the larger and more complex the DOM tree the higher chance of noticeable performance degradation.

The SVG referencing element <use/> can mitigate some of these issues, and as you mention linked CSS can be used to keep the inline SVG as lean as possible.

Great place for learning CSS. Really css is main factor in design sector. The person who knows css more can design so beautifully. For a better & professional site you must be a master in css.animated video maker

You don’t have to inject the icon a empty . That’s how many people do it, but you can use icon font via pseudo elements on regular elements that take part of your semantic document. Seems to me that inline SVG is less semantic since you have definitions of image in your document.

Positioning pseudo elements is not trick. It’s like a regular inline element. If you don’t want to play with it,make it absolute positioned and voila.

SVG: Must be declared multiple times, and if it is an inline icon, size can be very long. Unless it is set as a background image as sprites, but then they will not resizable anymore. Changing the font size will not change the icon size.

Icon Font: Can be included in a HTML class and keep it resizable, the size can be changed easily followed on the text size around it. Changing the font size will change the icon size.

It was meant for directly calling the sprite with the SVG fragment. Like

Using SVG sprite with include at the top and as this will work in IE9 and better:

Last I checked IE is still a major browser player…

You should really not take NetMarket Share stats seriously. Chrome and Firefox combined outperforms IE in a big way. Really. And as far as I see it at least here in Europe, IE 8 share is so small I don’t longer bother to fix for it anymore. Those guys are not worth as a customers anyway. Is such guy going to spend on some e-shop if he/she was not willing to update to newer version of Windows after 12 years anyway, running it on very old computer? I think not.

A site I’ve been building originally used an svg sprite-sheet. Everything looked great and rendering across browsers was nice, but one thing I really noticed was performance.

When scrolling the page the lag was quite noticeable. Each page was using between 20 and up to 50 icons for various elements. It was noticeable enough that the client commented and complained.

I’ve since switched everything over to a custom icon font and now there is no more scroll lag. To me this is a big factor because it is something the user will notice. The pages felt laggy and buggy. No matter how crisp your icons are, if your website or webapp gives the impression of slowness then it reduces the users’ experience.

If there is a way to mitigate this then I would be on board with svg 100%, but for a site that uses more than 4 or 5 icons it simply isn’t workable for me right now.

The base title and description tags have poor browser support so require the use of aria-labelledby. I’m no expert on this either but without knowing for sure the effect on the sites SEO of using svgs over pngs or an icon font I couldn’t bring myself to use them.

I eventually opted to use the svgs as imgs and background images with image replace techniques, which of course lacks the editing capabilities, but means I’m working with data that I can be sure my users will understand.

Also Fallback for ie8 is easy enough to implement with a sass mixin while minification and png conversion is handled with grunt.

If anyone has more info on embedded svg accessibility and SEO implications of such an implementation I be glad to hear about it.

Really like this type of article, especially when it’s challenging an industry norm like icon fonts. Even better that it’s leaning towards SVG, I’ve always liked SVG (in theory) a whole lot more than a hack like a font of icons. Great write up Chris!

I first have to say I like the idea and concept of SVG’s but I don’t agree that they automatically win out over icon fonts…

If you have ever created an SVG of even middle of the road complexity than you know how much mark-up is created. So every time you want to use a simple icon your page has to render out a mini XML document instead of just “” or “”. We are talking about inline SVG not SVGs in an image tag.

Icon fonts can contain tonnes of icons in a single HTTP request, are cache able, scalable, can be written once and used many times, are easier for the none developer to grasp and use (my opinion), and have deeper browser support.

Icon fonts still have their use, I would not advocate getting rid of icon fonts yet, they still have many advantages.

I will use SVG where SVGs make sense, such as logos and data visualization and will continue to use icon fonts for well icons.

Caching can be handled with tag loading SVG as ordinary image, then AJAX including it into DOM. In case like this, you can nicely make a PNG fallback with Modernizr, if SVG is not supported – you just change extension in from .svg to .png. DONE.

Just posting to mention that I think that the first poster is right, for SVGs, every instance the image is displayed it’s probably being rendered again, even if not http-requested. That was just once, but I fail to see how come it is rendered once and yet appears twice or more. Does it get “cached” in a different “format”, more or less as if it were a “variable” resulting from a function (rendering), rather than a “function” that has to be re-run every time? I’d guess that it could even theoretically depend on the browser engine.

There are definitely build tools for fonts. grunt-webfont is one. I use it on a project where I can just drop an svg in an icon folder and boom, my grunt watch task recompiles the font and then updates my .sass to include a class for the icon based on the filename (both real classes and placeholders for ease of use). Very slick, very easy.

I agree with @Mick: it would be interesting to include rendering performance in the comparison as well. It’s been a while since I used inline SVG myself, but back then horrible rendering performance in some browsers made it a showstopper.

I’d have to disagree with the “ease of use” assessment – I learned how to use icon fonts in about an hour but SVG seems to have a much steeper learning curve. I’ve tried following tutorials but so many seem to start with “edit a file in Illustrator” or “get Grunt working” – neither of which I yet know how to do.

No doubt very worth learning and it’s certainly on my list to do, just wanted to point out for a newb like me there’s a lot more support for pre-made icon fonts when all I want to do is include a few social media icons, a magnifying glass and maybe a star or two. :)

I use icon fonts over inline SVGs mostly because it’s too easy to just throw Font Awesome into a project and get a lot of great icons that way. For me, ease of use with icon fonts is much better with icon fonts and Font Awesome (which is free) comes with a bunch of great already made icons which is awesome because I suck with Illustrator.

I tried using inline SVG for a recent project, but the workflow complexity of having look-and-feel aspects being included inside the markup was too much, and in some instances impossible. Icon fonts have the advantage of being able to stay purely in CSS, and when used right maintain semantic markup and classes. (SVG can as well if used as an image, but you lose a lot of the advantages.)

I have started to use SVG in projects and it is certainly versatile medium that adds to a websites appeal but having said that browser support did worry me but more important the performance issues worried me more. It’s considerably slower than icon fonts but I decided to go ahead. I am using a SVG library, and have png fallbacks with modernizer.

A major win for SVG is the ability to use CSS for paths, with CSS3 animations and a good SVG library like snap you would make your SVG’s so much more interactive. I think it is a price worth paying

Wow. SVG’s are great for a lot of tasks, but so are icon fonts. – There is no one fix to icons.

Here’s a little something to balance the article a little.

Icon Fonts
+ Much more lightweight

Stores in cache (so does linked SVG’s)
Less intense to render (sub-pixel rendering for text is much more mature in browsers)
Btw: there is no such screen rendering of vector that’s “just pure vector”. (don’t ask me why Safari on the Mac renders text as clouds.)
Less clutter
Less work, for more gain
Easier to control with less code (given your CSS-skills)
Does not bloat the DOM. Inline SVG’s , are giving the CSS rendering engine and JS engine an unnecessary hard time (to say it carefully).

I think this cage match was stupid, but most of all it was disappointing. I expect more from you.

SVG’s are great, but, so are icon fonts, and so are linked SVG’s. There are use cases where all things shine. Inline SVG’s is by far the poorest “one fix” of the three.

One thing that I’ve recently discovered when working with SVG’s and icon-fonts is that SVG’s don’t handle CSS transitions very well, especially when they’re wrapped in <a> tags that have a http:// protocol. However, what’s weird is that https:// URL’s allow the transitions to work properly. With icon-fonts all you have to worry about is a simple color transition for things like:hover states.

I’ve noticed that CSS-Tricks has transitions on the social links at the bottom of this page, but like every other SVG that’s wrapped in an <a> tag, they don’t work.

i have played a little around with svg – inline and as sprite. well, as sprite it is nice but the disadvantage of colors is a big disadvantage. the only influence you can have to change the “color” would be opacity. but to change from red to green – you have to set different “items” in the sprite.

well inline svg is a complete no go for icons. for a logo… ok but icons? there is no editor who writes an article and has to set a button at the end with an arrow who begins with inline svg – sorry no.

This comment thread is closed. If you have important information to share, please contact us.