Icon fonts vs. svg icons

We can all agree that using png sprites for icons is not the most modern (or best) way to present icons on the web. Png is a rasterized format which means that if you try to make the image (or icon) larger, the quality will become worse. When browsers started properly supporting @font-face and svg some people chose to use icon fonts to serve their icons, others chose svg sprites to do this. These methods share the big benefit of scalability. This matters because our websites get viewed on many devices and you want your icons to be crisp on every device, not just the ones you optimized for by hand. This post is intended to give an overview of these two methods and to explore the benefits and drawbacks of each method. At the end of this post you will hopefully have an understanding of both svg icons and iconfonts and you'll be able to choose one of these icon delivery methods for your own projects.

TL;DR: The comparison is very close, both have their big upsides and no real big downsides. I'd say iconfonts win because they're a bit easier to use. Svg icons are a easier to position and manipulate. The code for this blogpost is on Github.

Getting set up

gulpfile

The first thing I'm going to compare is the set up process for each method. The method you end up choosing should not only work well but it should also be easy to manage. The first method I will set up is the iconfont. I will be using Gulp to automate the asset creation process. I made this decision because I use Gulp on all my projects. Also, Gulp seems like the right tool for this type of job; I don't want to create my assets by hand. The icons I'm going to use were created by Jamison Wieser for The Noun Project.

Icon font

Like I mentioned, I will be using Gulp to generate my assets. The gulp-iconfont plugin seems like a good plugin to generate a font with. I also used the gulp-iconfont-css plugin so I didn't have to create my own css template. With a couple of lines in my gulpfile and two plugins I managed to convert my svg icons into a font. Not bad!

svg icons

To make using the icons easy I will create a spritesheet that contains all my svg icons. I'll be using gulp for this as well, just like I did for the iconfont. I've set up my output in "defs" mode. Which means that I can use the icons like Chris Coyier descrives in this css-tricks.com post. This method only uses one gulp plugin but the fact that this gulp plugin uses svg-sprite which has a ton of options, it does seem a little less straightforward to set up. The output that was produced seems decent on first viewing so that's good.

Easiest to set up

Both methods are actually easy to set up within about 5-10 minutes. Therefor, this section will be a tie. Both methods are easy to set up and there isn't a clear winner.

Filesize

Something we should always take into consideration is the file size of the things we end up using. So, a simple comparison in filesize:

iconfont: 8kb (or 12kb if the svg font is used)
spritesheet: 25kb

Best filesize

The winner in this example is the iconfont. The iconfont is significantly less Kb than the spritesheet is.

Ease of use

Whenever I pick a technique I want to use, it has to be something that's easy to use. Of course it's important that something works well, is fast and lightweight and more but I feel like ease of use should be mentioned right alongside those requirements because in the end you might end up working with the tool or technique you chose for quite some time. So for my own sanity, I like something that's easy to use.

Implementing

To implement the iconfont all you have to do is add the stylesheet to the head  of your document. In order to use the icons you just create span  elements and give them the icon class. The second class you give them is your icon's name. An example:

Up arrow: <span class="icon icon-arrow_top"></span>

Easy enough, right? This results in the following rendered output:

Schermafbeelding 2015-04-16 om 19.51.31

 

To implement the svg spritesheet I needed a polyfill to make everything work. That's because IE doesn't support the <use> method for external svgs and I didn't want to include the whole svg inside of my html body. For more info refer to this css-tricks.com post. The html I ended up using looks like this:

Up arrow: <svg viewBox="5.0 -11.0  100.0 135.0" class="icon"><use xlink:href="assets/icons.svg/defs/svg/sprite.defs.svg#arrow_top"></use></svg>

This is quite a bit more complicated than the iconfont method. I had to figure out the proper viewBox settings for my icon and I have to do a lot more typing.

Positioning

When you want to position your icon with the iconfont method you'll run into some weird and complicated stuff eventually. That's because the iconfont is rendered as text so for example, there's line-height applied to it. This could lead to unpredictable and strange behavior in some cases.

When you use the spritesheet approach you get to decide almost everything. The sizing, positioning, display style, you can all directly manipulate it as if you're manipulating an image. So for positioning, the spritesheet is definitely better.

Styling

When you want to style your icons you're going to love the spritesheet approach. because you're working with actual svg icons you can set strokes, fill colors and everything. Just like you might do with any other svg! The iconfont however is flattened in a way. You can set a color for the whole icon bt you can't style individual sections, so the spritesheet is more customizable than the iconfont is.

The easiest to use method

Even though it's a little bit more work to implement, the spritesheet wins. It's easier to position and the more powerful styling options are also a big advantage over an iconfont. So the winner for this section is spritesheet, hands down.

Render quality

Personally I haven't seen the difference yet but there are definitely some potential rendering differences between the spritesheet and an iconfont. Because an iconfont is rendered by the browser as a font, it is also anti aliased. The result of this could be that your icons look less sharp if they're used as a font. Like I said, I haven't had any issues with this in the real world but the potential is there.

The best rendering method

Even though the rendering seems to be nearly identical the spritesheet wins here. That's because an iconfont can potentially suffer from a lack of sharpness due to anti aliasing of the browser.

Browser support

The @font-face method of embedding custom fonts is supported by all major browsers so it's very safe to use. The spritesheet method is supported by all browsers except for IE. However, a polyfill called svg4everybody is available so at the end of the day both methods are available on all major browsers.

The best browser support

Because the spritesheet method requires a polyfill and the iconfont doesn't I declare the iconfont the winner of the browser support section.

And the winner is..

After exploring and comparing both the iconfont and spritesheet approach I can honestly say that the comparison is very close. The iconfont is better at the implementation, more lightweight and it has better browser support. The spritesheet is more flexible, easier to work with and has great browser support if you include a polyfill.

Earlier in the article I mentioned that one of the major factors for me to decide on things like this is ease of use. And because of that I would say that the iconfont wins. The decision is really tough actually because I'm not a fan of how you have to mess around in order to position an icon with this technique. Nor am I a fan of the anti aliasing risks because I like my icons to be sharp and crisp. But iconfonts are lightweight, easy to use and implement in general and I've never come across a situation where I actually had to style parts of an icon rather than change the color of the entire icon. So, yeah, that concludes this post. Iconfonts win. If you beg to differ or have feedback for me, please send me a Tweet. I'd love to your opinions on this.

If you want to have a look at the source files I've used, the repo is on located right here on Github.

Mobile-first is a great workflow

One of the first questions a client might ask you when you start talking about his new website site is "Will it be responsive?". And the answer to that question will more often than not be "Yes, it will". Especially now that Google will penalize websites that aren't mobile friendly it's important that you make sure that your site works well on mobile devices. How do you approach responsive webdesign in a good way? Even though I am not a designer I'd say mobile-first.

Different approaches to responsive web design

When you're doing a responsive webdesign there's a couple of ways to do it. Some people use Photoshop and design three different versions of their website, one for mobile phones, one for tablets and one for the desktop. Others just make one of these three and design the rest during development in the browser.

If you only design one of the three big options, which one should it be? And when you start to build the website, where do you start? Do you do the desktop version first since it's easier for you as a developer? Or do you start with the tablet version because it's in the middle of the spectrum? Or do you let the client decide and start with the one that makes them the happiest?

These are just a few of the options you have when you're doing responsive web design, there isn't a way that is forced upon you by anybody and you're free to choose whatever you feel is most efficient. But in practice there seems to be one approach in the development phase that works every time for me. That approach is mobile-first.

What is mobile-first?

Mobile-first means exactly what you probably think it means, it's when you start your process with the mobile phone. Ideally you will start both the design and the development phase by thinking about mobile straight away. My experience is, however, that clients prefer to see designs for how the website will look on a big screen with all the bells and whistles you might add. So designers tend to not really work from a mobile first perspective because they focus on what the client likes to see. This probably doesn't apply to every designer and every client but it does apply to most designers and clients I've worked with.

When you enter the development phase, the approach you take is in your hands, you can decide where to start. And deciding to start mobile first isn't just a matter of preference. There are very valid reasons to approach the development phase from a mobile-first perspective.

Why mobile-first?

When you are building a responsive website there's a lot of things to consider, how does this look on a screen that is X wide? Should module Y be visible on that screen? Thinking about everything for every screen is overwhelming, there's so much going on and you get so little for free when you're building a website. So you're going to have to start somewhere and I prefer that somewhere to be the smallest screen I will develop for.

Constraints

A mobile phone is not only the smallest, but also the most constraint and possibly even the most used device that people use to browse your website with. Obviously this doesn't apply to every website in the world but do not underestimate the amount of mobile browsing people do. Because of these factors it makes sense to first perfect the browsing experience on the small screens.

And since it's also the most constrained browsing experience you will have to focus on the parts of your app that really matter to your users. This will make sure that you don't just add a lot of noise because it might look cool or pretty.

Development speed

If you've made a responsive website before from a desktop first approach you probably noticed that you had to 'undo' a lot of your styling and scripting. I'd like to illustrate this with a little bit of code. The code will take an unsorted list and turn it into a nice navigation bar for the desktop view. On mobile the list will be shown as a list.

.nav-list {
    list-style: none;
    margin: 0;
}

.nav-list li {
    padding: 0;
    display: inline-block;
}

@media (max-width: 600px) {
    .nav-list li {
        display: list-item;
    }
}

Do you notice how we first set .nav-list li  to a non-default value, inline-block  and then on screens smaller than 600 pixels we set .nav-list li  back to it's default value. Let's rewrite this from a mobile-first perspective.

.nav-list {
    list-style: none;
    margin: 0;
}

.nav-list li {
    padding: 0;
}

@media (min-width: 600px) {
    .nav-list li {
        display: inline-block;
    }
}

This is a small example so the difference isn't dramatic but the implications are significant. Instead of adding and removing styles we are simply adding more styles when the screen is at least 600 pixels wide. By taking this approach it's much more clear what's going on and it's also harder to make mistakes.

With the navigation list example in mind, imagine that we want to add a border and some padding to the list items, but only for the desktop view. Let's compare both approaches again, shall we?

desktop first

.nav-list {
    list-style: none;
    margin: 0;
}

.nav-list li {
    padding: 1em;
    border: 1px solid #333;
    border-radius: .5em;
    display: inline-block;
}

@media (max-width: 600px) {
    .nav-list li {
        display: list-item;
        padding: 0;
        border: none;
        border-radius: 0;
    }
}

mobile first

.nav-list {
    list-style: none;
    margin: 0;
}

.nav-list li {
    padding: 0;
}

@media (min-width: 600px) {
    .nav-list li {
        display: inline-block;
        padding: 1em;
        border: 1px solid #333;
        border-radius: .5em;
    }
}

As you can see the mobile first approach is a lot cleaner. Not only is it cleaner, it's also safer. We don't have to worry about resetting certain styles back to their defaults like we have to in our desktop-first approach.

Of course you still have to keep an eye out for cascading accidents because sometimes you set something for mobile that will have to be reset for your desktop view. But in my experience this happens a lot less often with mobile-first than it does with desktop-first.

Adding javascript is easier than removing it

I just showed you that when it comes to css it's a lot easier to stack on more styles than it is to reset them to defaults for mobile. The same applies for javascript. I usually find myself initializing a lot less (complex) modules for mobile. When you take a mobile-first approach with this you will not initialize certain things at first. Once you know that you're on a large screen machine you can start initializing your larger, more complex modules that are intended for desktop use.

Not only is it easier to initialize things when you know you need them, it's also a lot faster. Imagine executing some heavy javascript on a mobile phone only to find out that the module won't even be used because the target elements are hidden. That's a waste of precious resources that you might have used to get your page up and running on the device really quick.

Conclusion

In this post I explained to you what a mobile-first approach is from the perspective of a developer. I also showed you how this impacts the process of writing code. Going in mobile-first will prevent you from having to write a lot of 'reset this to default' css. It's also easier for the javascript part of your application. You won't initialize thing that you don't need and this generally makes your pages render faster as well.

I'm not saying that a desktop-first approach is worst in every case or scenario, I'm also not saying that the design process has to be mobile first. But thinking about the smallest most constrained devices does seem to result in faster and more focused websites. It also seems to lead to a more solid code base and happier developers.