A Guide to Better and Sharper UI Icons with Web Fonts

Are you using bitmap images like PNGs and GIFs for icons on your website? If so, you might have noticed they can be quite hefty in size, especially if they’re detailed or numerous. This not only increases the file size but can also slow down your website, as it requires multiple HTTP requests for each icon.

While CSS sprites offer a workaround, they don’t completely solve the issue of large file sizes. Another downside of bitmap icons is their lack of flexibility and scalability. Enlarging these icons or viewing them on high-resolution screens, like Apple’s retina display, often results in a blurry appearance.

If these issues sound familiar, it’s time to consider switching to icon fonts for a more efficient and scalable solution.

Exploring the Advantages of Icon Fonts

An icon font is essentially a collection of icons packaged into a web font, which can be easily incorporated into a website using the @font-face rule. As highlighted by Chris at CSS-Tricks, icon fonts bring several key advantages over traditional image icons:

  • Being vector-based, icon fonts are resolution-independent, ensuring sharp and clear display on various screen resolutions, including high-resolution screens like retina displays.
  • Icon fonts are scalable, allowing for size adjustments without any loss in quality or clarity.
  • As they are fonts, you can easily modify their color, transparency, text-shadow, and size using CSS.
  • They can be animated with CSS3, adding a dynamic element to your website.
  • The use of @font-face for icon fonts is widely supported, even in older browsers like Internet Explorer 4 (with .eot).
  • Using icon fonts results in fewer HTTP requests and a smaller overall file size.

Here’s a list of some top free icon fonts available:

Always ensure to review and adhere to the licensing terms before embedding any icon font in your website, as a sign of respect for the creator’s effort and work.

Implementing the @font-face Rule

As mentioned earlier, icon fonts are embedded in web pages using the @font-face rule within CSS. This rule allows us to define a new font-family. Let’s take the ‘Web Symbols’ font as an example:

 font-family: 'WebSymbolsRegular';
 src: url('fonts/websymbols-regular-webfont.eot');
 src: url('fonts/websymbols-regular-webfont.eot?#iefix') format('embedded-opentype'),
 url('fonts/websymbols-regular-webfont.woff') format('woff'),
 url('fonts/websymbols-regular-webfont.ttf') format('truetype'),
 url('fonts/websymbols-regular-webfont.svg#WebSymbolsRegular') format('svg');

In the HTML document, to display the icons, we simply use characters that correspond to each icon. Rather than applying the font-family globally, we can target specific elements by adding a unique class, like this:

 <ul class="icon-font">

Then, back in the CSS, we define this new font-family for the class we added:

.icon-font {
    font-family: WebSymbolsRegular;
    font-size: 12pt;

Demo @font-face

Integrating Icons with Pseudo-elements

Pseudo-elements offer another creative way to incorporate icons. Consider the following HTML markup as our starting point:

	 <ul class="icon-font pseudo">
	 <li>Reply All</li>

In the CSS, we can enhance this list by using pseudo-elements to display icons before each item:

ul.icon-font.pseudo li:before {
    font-family: WebSymbolsRegular;
    margin-right: 5px;

ul.icon-font.pseudo li:nth-child(1):before {
    content: "h";

ul.icon-font.pseudo li:nth-child(2):before {
    content: "i";

ul.icon-font.pseudo li:nth-child(3):before {
    content: "j";

ul.icon-font.pseudo li:nth-child(4):before {
    content: "A";

ul.icon-font.pseudo li:nth-child(5):before {
    content: "I";

Demo Pseudo-element

Private Use Unicode

There’s a scenario where instead of embedding icons into standard characters (A, B, C, D, etc.), they’re embedded in Unicode Private Use Areas to avoid any clashing among characters. This method is used by tools like FontAwesome, where the character codes are included in the stylesheet like so:

.icon-glass:before {
    content: "\f0c6";

To directly insert the icon into HTML, the code \f0c6 won’t render as it’s not a valid HTML-encoded character.

HTML requires a numerical reference markup to render special characters. It requires prefixing the hexadecimal number (representing the character) with an ampersand (&), a hash (#), and an x. For instance, f0c6 becomes in HTML. In FontAwesome, this code displays a paper clip icon, like this:

paper clip

Demo Unicode

Font Subsetting

When your icon collection includes unused characters, you can eliminate them by subsetting the font, which also reduces the font file size. A convenient tool for this is FontSquirrel’s @font-face generator.

Visit the generator, add your font, and select Expert. Then choose Custom Subsetting for more options.

font subset

For example, using the Sociolico font for social media icons on our website, we only need the icons for Dribble, Facebook, and Twitter, represented by d, f, and t. These characters are entered in the Single Characters field as shown:

font subset

Now, you can download the font, which in this case, has been reduced to a mere 3Kb to 5Kb in size. Note that only the characters d, f,, and t will render as icons; any other characters will appear as regular letters.

Final Thought

While this practice excludes the possibility of adding highly detailed effects like this, it offers a flexible, scalable, retina-ready solution with minimal file size. If your design can bear the absence of high detail, this icon-serving method is highly beneficial.

For those eager to explore further, below are some helpful references, along with our demo and source code available for download.

See demo Download source codes

Note: This post was first published on the 5th of Dec, 2012.