A Guide to: Better and Sharper UI Icons with Web Fonts
Note: This post was first published on the 5th od Dec, 2012.
If you are familiar with using bitmap image formats (like PNG and GIF) to display icons on a website, then you would also be familiar with its shortcomings. First of all, depending on the dimension and how much color information the icon has, an icon file size could be very large.
If we have too many icons to put in a website, it will also potentially slow down website performance as many HTTP requests have to be conducted by the browser. Although this problem can be solved with CSS sprite, the file size is still large.
Bitmap icon also has shortcomings in flexibility and scalability; let’s say we need to enlarge or zoom the icon to a certain level, or view it through a very high screen resolution such as on the retina display; the icon will definitely turn out looking blurry.
Well, if you consider some of those matters above, you probably need to use icon fonts.
Using Icon Fonts
An icon font is a set of icons packed in a web font that can later be embedded on a website using @font-face
. As Chris at CSS-trick has pointed out, there are many benefits of using font over image to deliver icons;
- Font is a vector-based object that, by its nature, is resolution-independent, so the icon will remain as crisp in various screen resolutions including very high screen resolutions (like retina-level).
- It is also scalable, allowing it to be enlarged at many levels without losing quality and precision.
- Since the icon is basically a font, we can also control the color, transparency, text-shadow and even resize it through the style sheet
- We can also animate the icon with CSS3.
- The icon is called with the
@font-face
rule which has been supported from as early as Internet Explorer 4 (with .eot). - Lesser HTTP request and Lower file size.
Here are some of the best free icon fonts we can find:
Make sure you’ve checked and followed the license before embedding it in your website to honor the author’s time and hard work.
@font-face Rule
As we have mentioned, the icons are embedded using @font-face
rule through the style sheet that define new font-family
. In the following example we will use the Web Symbols;
@font-face{ 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'); }
Then, in the HTML document, we only need to add the characters that represent the icon, and rather than apply the new font-family
widely in the document, we can do more specifically by adding an extra class to certain elements that the icon need to be rendered into, like so;
<ul class="icon-font"> <li>h</li> <li>i</li> <li>j</li> <li>A</li> <li>I</li> </ul>
Back to the style sheet, we define the new font-family
for that class that we’ve just added:
.icon-font { font-family: WebSymbolsRegular; font-size: 12pt; }
Recommended Reading: A Look Into: Better Typography For Modern Websites
Using Pseudo-elements
If the icon is treated as the side element we can also deliver the icon through pseudo-element. Assuming that our HTML markup is as follows:
<ul class="icon-font pseudo"> <li>Reply</li> <li>Reply All</li> <li>Forward</li> <li>Attachment</li> <li>Image</li> </ul>
We can do it this way in the style sheet:
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"; }
Recommended Reading: Understanding Pseudo-Element :Before and :After
Private Use Unicode
There is a circumstance where the icons were not embedded in letters (A, B, C, D, etc.), but were embedded in Unicode Private Use to minimize clashing among the characters. Like in FontAwesome, the author has luckily added all the characters code in the style sheet, which looks like this;
.icon-glass:before { content: "\f0c6"; }
But when we need to embed the icon directly into the HTML, something like the following code \f0c6
will not render the pointed icon, as it is not a valid character encoded in HTML.
HTML needs a numerical reference markup to render special characters. We have covered about it a bit in our previous tutorial on CSS3 Buttons; this character is prefixed with a combination of an ampersand sign (&
), a hash sign (#
) and an x
then followed by the hexadecimal number that represents the character.
For instance, the f0c6
is a hexadecimal number, so the numeric character reference in HTML will be
, in FontAwesome that code will display the paper clip icon, like so;
Further Reading: Characters Encoding in HTML
Font Subsetting
The icons in the collection might not all be needed. In that case, we can drop the unused characters by subsetting the font that will also result in lower font file sizes. Fortunately, there is a handy tool from FontSquirrel to do this job easily, @font-face generator.
After you go to that page and added the font, select Expert. You will see some more options; select Custom Subsetting.
In this example, we use the Sociolico font to display social media icons in our website, but the icons that we will need are only Dribble, Facebook and Twitter which respectively are represented by these characters; d, f and t. So, put those characters in the Single Characters input field as follows:
And we are done. Now we can download the font and in my case the font size has turned out to be only 3Kb to 5Kb. Also remember that the only characters that will be rendered into an icon are only d, f and t, while the other characters will render to only be a regular letter.
Further Reading: How to Optimize Web Fonts for Saving Bandwidth
Final Thought
One thing that we can’t do upon this practice is add highly detailed effects like this to the icon.
However, if our overall design does not require detail at that level, this approach could be a better way to serve icons in websites. It has flexibility, scalability, is retina-ready with a very small file size, what else can we ask for?
Lastly, if you want to dive deeper into this topic, below we have put together a few useful references, as well as our demo and source code for download.
- How to Make Your Own Icon Webfont – WebDesignerDepot.com
- Displaying Fonts and Data Attributes – 24Ways
- Private Use Unicode – Wikipedia