Advertisement

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

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

This post is part of a series called CSS3 Mastery.
CSS Fundamentals: CSS3 Transitions
The Intricacy of Simplicity: CSS3

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.

Advertisement