Quick Tip: Ever Thought About Using @Font-face for Icons?

Quick Tip: Ever Thought About Using @Font-face for Icons?

Tutorial Details
  • Technology: CSS
  • Estimated Completion Time: 15 Minutes
  • Difficulty: Beginner
This entry is part 11 of 16 in the CSS3 Mastery Session
« PreviousNext »

The evolution of Internet technologies never ceases to amaze. Seemingly daily, new concepts and techniques are being thought up by creative and talented people. With modern browsers being adopted at a greater rate, systems like CSS3 are becoming more and more viable for use on projects of all sizes. Clearly, this can be seen by looking at new services sprouting on-line like TypeKit. Conceptually, if we deconstruct a font down to it’s basic elements, we can make use of this technology for things other than type, icons.


The Need for Speed

For a short period of time, developers began producing websites with little regard for bandwidth consumption. HTML and CSS where restrictive and Adobe Flash was an open canvas for designers and developers to stuff animations and complex layouts into. This resulted in some extremely bandwidth heavy sites—we all remember a few. Those were the days before the proliferation of mobile smart phones.

With smart phones accessing the Internet more frequently, bandwidth and page load speeds have suddenly returned to the forefront. Thankfully, advances in HTML, CSS, and JavaScript have made that all possible. Central to webpage speed and responsiveness is the number of HTTP requests a page load must make. Modern browsers limit the number of requests to a single server. The W3C HTTP 1.1 specification reads

“A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.”

One technique that has become increasingly popular is the use of CSS sprites. CSS sprites are designed to reduce the number of HTTP requests to the web server by combining many smaller images into a single larger image and defining a block level CSS element to only show a defined portion of the larger image. The technique is simple, but ingenious.


Deconstructing the Font

Fonts at their most basic molecular level are a series of vector glyphs packaged up into a single “glyph archive”.

CSS3 has introduced to the web development world the ability to embed fonts with the @face-face declaration. Without question, this advancement in Internet technologies is one of the most exciting and important stages in our brief history. With developers able to embed fonts of their choice, designers can produce layouts that will render far more consistently from platform to platform bringing the art of interactive layout closer to it’s print cousin.

If we take a closer look at the technology behind a font, we can gain a far better understanding of how they can be used and deployed. Fonts at their most basic molecular level are a series of vector glyphs packaged up into a single “glyph archive”. We can then reference each glyph by its corresponding character code. Theoretically, it’s very similar to the way in which we reference an array in almost any programming language—through a key/value pair.

With this in mind, the glyphs we reference can really be any vector-based single color image. This is nothing new—we’ve all seen Dingbats and Webdings. They are two examples of non-type fonts, that is, a series of vector based images compiled into a single font archive.


Abstracting and Expanding @font-face

With the advent of font embedding and the realization that fonts are essentially a series of simple vector glyphs, I began to experiment on how to use this format to my advantage. Conceptually, if I placed all required icons for a particular site into a custom font, I would then be able to use those icons anywhere on the site with the ability to change size and color, add backgrounds, shadows and rotation, and just about anything else CSS will allow for text. The added advantage being a single CSS sprite-like HTTP request.

To illustrate, I’ve compiled a new font with a few of the great icons from Brightmix.

Sample glyph chart

I’ve used the lower case slots for plain icons, and the uppercase slots for the same icon in a circular treatment.

To use my new Icon Pack, I’ll first have to export my font set as a number of different font files (.eot, .woff, .ttf, .svg) to be compatible with all browsers. The topic of font embedding and file format converting is covered elsewhere, so I will avoid a detailed explanation here. However, the CSS would look something like this.


@font-face {
  font-family: 'IconPack';
  src: url('iconpack.eot');
  src: local('IconPack'), 
    url('iconpack.woff') format('woff'),
    url('iconpack.ttf') format('truetype'),
    url('iconpack.svg#IconPack') format('svg');
}

Once embedded, I now have a complete icon set in vector format to reference. To reference an icon I simply need a style that includes the font-family of “IconPack”.


<style>
.staricon {
  font-family: 'IconPack';
}
</style>

<div class="staricon">a</div>

The above example would render a star and is the most basic use of the Icon Pack concept, however it’s not very intuative from a development perspective, not SEO friendly, nor does it gracefully degrade in the case of non-CSS support.

To remedy the situation, I’m going to include a :before pseudo-element and wrap the content in a span tag.


<style>
.staricon {
  font-family: 'IconPack';
}
.staricon:before {
  content: 'a';
}
.show {
  display:block;
}
.hide {
  display:none;
}
</style>

<div class="staricon">
  <span class="show">star</span>
</div>

Now, the star is added to the display and I can toggle the visiblility of the text by using the show and hide classes. The result is an easy to reference CSS class that degrades gracefully and is optimized for search engines. For my entire set of icons, I can write something like below.


<style>
.show {
  display:block;
}
.hide {
  display:none;
}
.icon {
  font-family: 'IconPack';
}
.star:before {
  content: 'a';
}
.rss:before {
  content: 'b';
}
.screen:before {
  content: 'c';
}
.talkbubble:before {
  content: 'd';
}
<!--
... and so on ...
-->
</style>

<div class="icon screen">
  <span class="hide">screen icon</span>
</div>


Icon Pack Usage

The benefit here is that the icon will scale with the font size. In fact, all icons will scale and maintain perfect clarity.

So far, we’ve only touched the tip of the iceberg, nothing groundbreaking here, although you may start to see the possibilities. A real world scenerio would be the replacement of the list-item-style. As apposed to using an image, we can now use a vector icon from our Icon Pack. The benefit here is that the icon will scale with the font size. In fact, all icons will scale and maintain perfect clarity.

Since the icons are now placed on our page as if they were text, we can apply any valid CSS style to them without downloading any other assets. We could apply color, font-size, text-shadow, etc and make use of the :hover pseudo-element for mouse over effects—all with a single glyph.

As with anything, there are some unfortunate limitations. As of this writing, there is no way to display a single glyph with multiple colors. There has been some CSS trickery to get gradients over live text, however complex shapes with varying colors in a single glyph is a limitation. Having said that, there are ways to approximate multi-colored glyphs by segragating the parts of a vector graphic into individual glyphs then assembling and coloring them on the page through CSS.

Another interesting usage is a simple CAPTCHA validation. By replacing the glyphs for the alphabet with numbers, users will see numbers, but the page code will be letters. Some simple computation to translate between the two, and you have an easy to read CAPTCHA.

To better illustrate these concepts, I’ve assembled a sample page made up of two HTTP requests—the page code and a single Icon Pack. Included as well is the ability to scale the font size of the page to clearly demonstrate the flexibility of embedding vector glyphs. The company logo, navigation, imagery, and CAPTCHA are all using glyphs. Please note, the CAPTCHA included here is for illustration only. To use this on a production site, I would recommend validating on the server side with a dynamic algorithm as apposed to JavaScript.

This sample page also demostrates the use of a glyph as a scalable “repeating” background. I’ll be the first to admit this implementation is hack-ish at best, however I think it demonstrates the flexibility and versatility of the Icon Pack.

Clearly, this opens up some possiblities. Designers can develop Icon Packs for sale, corporate entities can host a single Icon Pack to be used on all corporate media. Template designers can easily distribute multiple color options of the same template all without having to save and export a single extra file. Web designers can easily scale existing sites to be compatible with hand held devices. Furthermore, this technique exposes our icons to the DOM enabling animated Flash-like effects with your favourite JavaScript API.

As usage and browser support for CSS3 penetrates further, Icon Packs will soon have a large impact on content delivery furthering the light weight, scalable, multi-device trends that are starting to become a necessity.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://bennthewolfe.blogspot.com Benn Wolfe

    What an awesome article. This is very clever and could really make a big difference in my projects. Thank you.

    • http://xpressabhi.com abhishek

      Hi,
      I am trying to make a theme for my blog with zero image. I am sure this is gonna help me for social media icons and othr icons.
      Thanks for this article..

  • http://blog.insicdesigns.com insic

    Brilliant Idea!

  • Arik

    I prefer using Base64 images when it comes to very small iconography. Of course given that it’s consistent. The base64 is simply added to the css and that’s it.

  • Adri

    Nice!

    Thanks!

    I will look it ;)!

  • Robert

    Nice idea! I’ll try that out right now :)

  • http://www.smashingshare.com Smashing Share

    Great approach with @font-face. Excellent example and tutorial. Really love it!

  • Shaun

    I’m impressed…

  • Huckleberry

    Great tut. I work alot in both print & web, and this idea is certainly born from print. Excellent idea on executing it on the web.

    However, how will search engines react to this?
    Say I have a logo as that’s a font glyph from Zapf Dingbats, will search engines display the glyph, the key used to make the glyph—such as K—or an annoying question mark in a diamond?

    That’s the only downside I can think to this method currently.
    Huck.

    • http://azzcatdesign.com Catherine Azzarello

      Yes! Great article. Have same question as Huck…does a screenreader ‘read’ the icon as a letter?

      • http://nike1.se/ Nike

        Oh yea, +1 on that question. Other than that, awesome tut! :)

      • Anna

        No, it doesn’t. This method is using an empty tag, and the letter is placed into it through the css ‘content’ rule. The DOM doesn’t see it at all.

  • Marcy

    Fascinating idea.

    How do you “compile a new font”?

    • http://matt-bridges.com Matt Bridges

      I second the motion. How do you make a font like this fairly readily?

  • http://designinformer.com Design Informer

    Excellent idea Wayne. I never even thought of doing that. I see this idea being further developed in the future. Nettuts is awesome!

  • Dave

    Very creative! With the impetus of your recent font-face tutorials egging me on, I’ve already implemented font-face for text on two client sites.

    I never would have thought of this, though. Obviously we’re all used to using images for icons, but the idea of resizing and recoloring them is very cool. I hope to use this sometime!

    Thanks.

  • http://www.sean-o.com Sean O

    Interesting effect, but yet another not-ready-for-production “technology preview” if you’re simply ignoring IE.

    • http://www.kieru.com Rob

      @font-face was originally introduced in CSS2; and has been supported by Internet Explorer since version 4. The only catch is that IE only supports EOT (Embedded OpenType). I’m not sure if this has changed in any recent version of IE.

      • xeos

        Nope, still just EOT.

    • http://paulirish.com Paul Irish

      Um? Like Rob said, this has been in IE since ie4. The code here works just fine.

      IE4-IE8 support .eot format. It’s likely IE9 will support both eot and WOFF.

    • Anna

      The reason this isn’t ready for IE is because IE6 and 7 don’t support the ‘content’ property in CSS.

      The only way to make it work in IE6-7 is to actually write the letter out in the html, which leaves stray letters all over the place, or use Javascript to document.write everything in, but if Javascript isn’t enabled, your user doesn’t see the ‘images’

      • http://juarezpaf.com Juarez P. A. Filho

        Here… Doesn’t work on IE8 also.

  • http://blog.echoenduring.com/ Matt Ward

    This is a remarkably clever idea, with lot of upside potential. I think of something like this very TUTS+ network, and how a single custom font like you describe could be used to create simple icons that can be applied across an entire network of similar sites. Changing the colour from site to site would be a simple matter of a few lines of CSS, rather than having to create and host different coloured images for each circumstance.

    I really like this idea, and may consider it for an upcoming project!

  • http://enrique-ramirez.com Enrique Ramírez

    Interesting idea, but I’m quite unsure if it’s really practical in the wild. Accessibility, SEO and load times issues come to mind. Is it really better to load a whole font file that might be 30-100kbs in size or just one sprite image file that’s around 15-30kbs? What if the stylesheet, for whatever reason, doesn’t load? What about screenreaders? Search engines? All they’ll read is a letter with no real meaning to them.

    Matter of testing, I guess.

    • http://paulirish.com Paul Irish

      People use hyphens and pipes all the time in their html for purely presentational reasons, but your comment brings up a good point…

      These symbols should be mapped to more appropriate glyphs, instead of basic latin letters.

      This font is probably <10kb and if loaded as a data-uri in the stylesheet is really no additional hit whatsoever.

      • http://twitter.com/c_alb Christian Albrecht

        First this idea is not new see http://new.myfonts.com/fonts/upir-typo/gui-design-icons/
        Second i want to second Paul Irish’s Statement that the symbols should be mapped to appropriate glyphs, plus imho there should be a Unicode Block for Web Symbols like openLink and openLinkNewWindow and so forth, and maybe for Webshop Symbols, so come on Adobe if you steal ideas allready, then care that this is done right.

      • http://twitter.com/c_alb Christian Albrecht

        First this idea is not new see http://new.myfonts.com/fonts/upir-typo/gui-design-icons/
        Second i want to second Paul Irish’s Statement that the symbols should be mapped to appropriate glyphs,
        Third imho there should be a Unicode Block for Web Symbols for generous tasks like ‘open Link’ and ‘open Link in new Window’ and so on, and maybe for Webshop Symbols, to make Fontsets interchangeable.
        Like this is done for other Symbols http://www.alanwood.net/unicode/ like Dingbats http://www.alanwood.net/unicode/dingbats.html or Miscellaneous Symbols http://www.alanwood.net/unicode/miscellaneous_symbols.html

        (To comment editor: Sorry i got this wrong in my first posting with Adobe, while searching now for the font above which i found a while ago when i had the same idea, many sites about Adobe and iconfonts showed up, and i combined them wrongly with the advertisement)

  • Evert

    Hey, great tip! I didn’t know this was possible at all! Thanks.

  • Patrick

    Ouh damn, you’re right. This is a brilliant idea.

    And you don’t really need CSS3, how about “cufon”?

    http://cufon.shoqolate.com/generate/

  • http://gabri.me Gabri

    I made something like this when i was designing my Portfolio but i made in the 404 page http://www.gabri.me/404 “hover over it ;)” and it`s working everywhere even in IE6 .

    i used http://www.fontsquirrel.com/fontface/generator

    • http://wptricks.net WP Tricks

      Wow.. you 404 Page is awesome…

  • http://john.onolan.org JohnONolan

    That is very clever indeed, a really neat idea :) I do share the concerns of other with regards to search engines and screen readers though, it isn’t very semantic!

  • StoicMania

    Frequent NetTuts/TutsPlus follower and web design hobbyist. I’ve finally found a compelling reason to add a comment!

    I was actually talking about this a few weeks ago with a friend who’s more into computer programming, but who understands the basics and keeps up to date (mostly due to my efforts to pull him in hands-and-feet). Glad to see I’m on the same line of thought as others! I’d like to see how this might be applied and how long it takes for it to catch on, if it does.

  • http://www.fatlizardmedia.com Juan C Rois

    This is very clever, I’ve used dingbats and webdings in my designs before, but never thought of it as part of a Font Face kit.
    I’m impressed and very interested to use this in the real world.
    Thanks

  • http://driftinfo.lv Senichiro

    Wow, i think i’m going to use it. Thanks. :)

  • http://www.studioweber.com Alex Flueras

    Awesome article. Haven’t thought about this possibility… Thanks for sharing!

  • http://www.xcellence-it.com/ Xcellence IT

    Nice Idea… would like to try this….

    Can you please explain what is woff & svg file type? And how can we build a custom font ttf and all?

  • http://www.lvrealty.net Charles

    Very slick indeed. Website owners/devs should be concerned with speed, especially since G announced that they may factor page load times into rankings. Besides, more and more people are using lower bandwidth connections like 3G cell phones to surf.

  • Fynn

    Nice idea & article.. but am I the only one who thinks @font-face rendering is just to awfull to put in your site? I still prefer Cufon.

    • http://davekingsnorth.com DaveKingsnorth

      I agree, I still use cufon rather than @font-face for the same reason. Really clever concept though. What’s the simplest way to compile a new font?

  • http://cmstutorials.org krike

    wow great tip, never thought of using font face like that :D thanks

  • http://www.vimeo.com/4925316 Joe

    Brilliant!

  • http://www.a51integrated.com Wayne Helman
    Author

    In response to the few concerns about SEO and screen readers, the concept here is to remove the glyph designation from the HTML and define it in the CSS with a :before or :after pseudo declaration. This first example is specifically NOT SEO friendly and a solution is presented that eliminates the issue. In fact, I believe SEO could be enhanced.

    Take the example of the logo in the example files. This could easily be written like this:

    The number one thimble manufacturer worldwide
    123 Street Avenue, Toronto Ontario

    1-800-999-9999
    All thumbs? We got you covered.

    Company Ltd.

    • http://www.a51integrated.com Wayne Helman
      Author

      sorry, html got stripped.

      <div id=”logo”>
      <div id=”mark”>
      <ul>
      <li id=”tl”><span class=”hide desc”>The number one thimble manufacturer worldwide</span></li>
      <li id=”tr”><span class=”hide address”>123 Street Avenue, Toronto Ontario</span></li>
      </ul>
      <ul>
      <li id=”bl”><span class=”hide tollfree”>1-800-999-9999</span></li>
      <li id=”br”><span class=”hide byline”>All thumbs? We got you covered.</span></li>
      </ul>
      </div>
      <div id=”wordmark”>Company Ltd.</div>
      </div>

  • Frank

    Great idea. Could you create a custom font for http://www.iconsweets.com/ , please? I would like to use it’s icons for social media services for my current project, and this would be a great chance to enhance performance.

  • http://www.cbesslabs.com Bratu Sebastian

    Execllent idea, I will definitely use it too !

  • Anjum

    Hey

    In demo or theory the idea is very good. Right now i am on firefox 3.6.3 and to be honest with you my browser isn’t rendering it very clear and crispy. after all it has to look nice. for this reason i can’t use such technique on live/clients site I would go with css sprint…

    Thanks

  • http://www.a1media.ca Douglas Helmer

    Excellent article / technique.

    Took me some time to puzzle it all out from the demo because the .content property in the CSS doesn’t show up in Firebug’s style inspector pane (at least not for me … I’m probably doing something wrong, no doubt).

    The .content properties are visible if one clicks on the CSS tab in Firebug, of course.

    Once I figured out that the letters a, b, c, etc., were the letters corresponding to the “lowercase” versions of the icons, and the A, B, C, etc., corresponded to the circular “uppercase” versions of the icons, it all fell into place.

    One of the great advantages of living under a rock is that I frequently get to enjoy these ah-ha moments when reading Nettuts articles :)

  • http://matt-bridges.com Matt Bridges

    This is a fantastic idea! Rather than having to use multiple images (or a sprite) for icon sizes, using a font would make the scaling process a breeze! Well done! I love it!

  • Lukas

    Wow, why didn’t I think of that? :)
    Just too bad there isn’t a way to use multiple colors in the ‘icons’.

  • http://www.webcoursesbangkok.com Carl – Web Courses Bangkok

    Now that is a good idea if I ever saw one!

  • http://twitter.com/c_alb Christian Albrecht

    For the screenreader – beside putting them into :after and :before –
    there are a few Slots in Unicode allready for Symbols and the like
    http://en.wikipedia.org/wiki/Miscellaneous_Symbols and http://en.wikipedia.org/wiki/Dingbat
    There is also an overview http://en.wikipedia.org/wiki/List_of_Unicode_characters

    If that is not sufficient there are private use ranges in Unicode:
    F0000..FFFFF; Supplementary Private Use Area-A
    100000..10FFFF; Supplementary Private Use Area-B
    which means if you put your symbols within this Unicode ranges they simply won’t have a meaning for the sreenreaders.

  • http://www.malegaonline.co.cc Malegaon Online

    Awesome !
    never thought of it earlier
    wil sure try it out in my next project

  • http://www.boraacemi.com BORA

    No, I never thought about that :D
    Interesting approach!
    Thanks!

  • http://www.zensavona.com Zen Savona

    Actually its interesting you wrote an article about this, because ive been using it for a while, not for the kind of icons you are using it for, but for things like arrows and buttons. the only problem is that when converting to a font you lose any color (for non-solid color icons).

    To answer the question posed by alot of people, a newsreader will just show the letter you have used as an alias for the icon. which is less than desirable. but it does not cause any problem if using these icons in your layout, for example RSS icons and such.

    I’m really glad to see someone else thought of this and putting this great idea to good use.

    Zen

  • http://designwithcrackers.blogspot.com/ Thiago Cavalcanti

    Now, here is a novel idea! One might spruce it up though if Javascript is used to add the nonsensical characters to the right spots, working around the hole “what will google think of it?!” problem without resorting to the pseudo-class trick done here. It can be done fairly easily and simplifies the approach to this technique considerably.

    Just think of what would happen if a new designer got hold of a project that used that technique without knowing about it beforehand. He or she would probably screw all of it unknowingly and would be left asking “what did I do wrong?”. If it was a JS clearly labeled “iconpack.js” included at the head that did the trick the odds of that happening would most certainly drop.

    The reason I’m saying all of this is because it’s been my experience that people who assume other persons CSS don’t read comments, ever. They just start to change it all thinking they “know CSS” and end up destroying such little tricks like this because they just didn’t knew better.

  • http://westcoastdesignco.ca Jayson Brown

    Amazing concept Wayne, makes me think about creating my own Fonts!

  • antony

    I’d like to know whether it works for people viewing the website on a Mac or under Linux, thanks.

  • http://www.stefanalexandru.ro/ Stefan Alexandru

    Yes i did think about that, even wanted to build an entire font for that specific idea. Didn’t get to do that tho.

  • cuginoAle

    Awesome!
    “The topic of font embedding and file format converting is covered elsewhere, so I will avoid a detailed explanation here”
    Can you please post a link?
    How do we convert a vector file to ttf?
    Thanks a lot.

  • ScaraX

    Quite bad if the browser supports CSS3, but no @font-face like on android ;)

  • http://www.rizqtech.net rizq

    Btw, it doesn’t work in linux ?

  • http://www.mediacake.net Dan

    Lovely idea!!
    but as a few people of mentioned, search engines and screen readers concerns..

  • http://typefront.com John Grimes

    TypeFront would be ideal for this sort of stuff.

  • Kaeden

    Great idea, However the fact that it doesn’t work in Internet Explorer is sadly the only part that keeps me from using it.

    I took a screenshot of how your demo looked in IE8, http://i40.tinypic.com/2mg1rb9.jpg

    Anyone have any work-arounds that still keeps the page SEO and screenreader friendly without using javascript? would be greatly appreciated.

  • http://blog.esbudellat.net arnau

    *uff* it’s a bizarre idea! What about accessibility? And what about browsers without @font-face support?