Skip to main content
Finished icon set

Font Icons Workflow with Sketch and Grunt

Published on Nov 25, 2014

Font icons, a scalable and flexible way of displaying flat monochromatic glyphs, is commonly leveraged by developers in websites and web apps. However, creating one can be quite a hassle since this technique started out as a hack and there are no official ways of doing it. There are several powerful tools like IcoMoon and Fontello which make it easier to manage and convert your vector icons into web fonts. But, they require you to be in the app and do some manual work such as uploading your SVGs and downloading the compiled assets into your project folder every time you make a change.

Because of this friction, I wanted to streamline the process without depending on a separate tool to manage the icons. By using Sketch, SketchTool and Grunt, I’ve devised a way of being able to curate and design the icons in Sketch, and then conveniently transforming them into usable web fonts in one swoop of a build script. This article will show you my workflow in creating a simple icon set for the web as well as how to automate the generation of font icons for your front-end project.

Note: You can download the final source project that demonstrates the front-end setup as you follow along.

Icon Metrics

Example icon set

Before creating an icon set document in Sketch, it’s important to consider the grid size of the icons you’re planning to use on your site. Try to tackle the worst-case scenario by choosing the smallest intended size in order to account for low-resolution screens.

Comparison of scaled vs. optimized icons

In addition, the size should depend on the body text size as most icons are placed inline with the text such as inside a button or as part of a navigation item. Using the same height makes them easier to align on the baseline (e.g. 16x16 for 16px font size).

You can also have multiple starting sizes for your icons. The idea is that when you scale them up, you would use a multiple of the base size to maintain their best qualities (e.g. 16x16 → 32x32 → 48x48 or 24x24 → 48x48 → 72x72).

Finally, be aware of where the ascent and descent lines are in your icons. By default, it will be a 2 pixel margin from above and below for size 16, and a 3 pixel margin for size 24. These metrics can be adjusted in the build script discussed later on.

Icon metrics, showing ascent and descent lines

Layer Arrangement

Below is the typical layer arrangement I use for each of my icons:

Layer arrangement in Sketch

Icon Group – Contains the paths, preferably combined using boolean operations (union, subtract, etc). To ensure minimal issues when it is converted from a SVG to a font glyph, check that all…

  • strokes are vectorized (Layer → Paths → Vectorize Stroke)
  • texts are converted to outline (Type → Convert Text to Outlines)
  • transformed paths (e.g. flipped or rotated) are flattened (Layer → Paths → Flatten).

Bound – A hidden rectangle that defines the boundary of the icon. It exists for the purpose of keeping the icon size intact when pasting the icon into your mock ups.

Slice – The export slice set to 1x SVG. Its name will determine the CSS class name that you will use in your HTML (e.g. .icon-home-24).

Installing Sketchtool

The good people at Bohemian Coding created a super useful command-line utility called SketchTool that lets us export artboards and slices outside of Sketch. Better yet, it doesn’t require Sketch installed in the system, so if the developer’s machine doesn’t have it, the tool will still work.

Sketchtool being installed in Terminal

Download and extract it. Open up Terminal to the folder and run bash Then run sketchtool to confirm that it is installed.

Exporting and Generating the Fonts

With the icons properly setup in a Sketch document and SketchTool installed, it’s time to configure Grunt to generate the fonts for us. Two Grunt tasks will be used: grunt-shell and grunt-webfont (please follow the installation instruction based on your OS).

The code below is the full Gruntfile. Upon running its default task, it will run SketchTool through grunt-shell to export all the icons from the Sketch document as SVGs into a folder. Then it will use grunt-webfont to package the vector files into web-ready fonts as well as generating the required CSS and an HTML preview of the icon set.

module.exports = function(grunt) {
shell: {
exportIcons: {
command: 'sketchtool export slices assets/icons.sketch --output=assets/icons/'
webfont: {
icons: {
src: 'assets/icons/*.svg',
dest: 'src/fonts/',
destCss: 'src/css/',
options: {
font: 'icons',
fontHeight: 96,
normalize: false,
ascent: 84,
descent: 12,
destHtml: 'assets/',
templateOptions: {
classPrefix: 'icon-'
grunt.registerTask('default', [ 'shell:exportIcons', 'webfont:icons' ]);

Let me walk you through some important lines.

The shell:exportIcons task is pretty straightforward. It runs SketchTool in the terminal and exports all the slices from assets/icons.sketch into the assets/icons/ folder based on the export settings of the slices in the document.

The webfont:icons task has some interesting options to be aware of. Under options, the fontHeight is set to 96, which is a common multiple of 16 and 24. This allows the icons we’ve created to co-exist in a single font face without encountering metric-related issues. You’ve probably noticed that it’s not the least common multiple (48) because for whatever reason, a smaller value can cause slight hinting problems. Nevertheless, try to keep it small to shave off the extra bytes in the compiled font files.

The ascent and descent properties must always be positive values, and are measured from the bottom of the glyph boundary.

normalize is set to false here to override a default behaviour with the font engine that makes the glyph width as wide as the paths inside. We want the width to match the height to avoid inconsistency with the icon size.

And that’s it! Run grunt from the Terminal and the whole process is blasted through in seconds. Now you can reference the generated CSS your HTML and apply the icon classes to your elements.

Grunt compile script running in Terminal

Icon output in generated HTML

I’ve created a sample project with a Sketch document and the build script right here. Try it out, modify it, and see if this workflow can help you streamline font icons creation for your projects 🙂


Charlie is a product designer and developer from Vancouver. He writes about design, development and productivity hacks. If you like what you've read, follow his feed or tweets to stay updated 😎

Portrait of Charlie

Want to talk about this article?

Tweet @charliecm