Generating Custom Font Icons in Rails with Font Custom

If you don’t know it already, icon fonts are super handy. They let you adjust the size and color of your icon graphics with css, so that you don’t have to regenerate rasterized icon images everytime you want to make a change.

Generating icon fonts however, can be repetitive and tedious. Typically, you would use a service like IcoMoon. The workflow looks like this:

  • Create a font icon pack at IcoMoon.
  • Upload your vector icon files.
  • Download the icon bundle to you project directory.

Everytime you need to make a change, you have to:

  • Add or update the vector icon files at IcoMoon.
  • Re-download the generated css and font files.
  • Add them to your project repository.
  • Test and commit.

In Rails, with the asset pipeline, usually a few extra steps are required on every change, like:

  • Fixing the paths to font files to use asset pipeline helpers.

Can’t we automate this?

This kind of repetition is a perfect example of something that should be automated. After a little searching, I found the excellent Font Custom utility, which handles the svg to font compilation.

Using it with Rails takes a few steps, but ultimately we want to be able to just add a vector icon graphic to a folder somewhere and run a rake task.

Here’s how to get it setup:

  1. brew install fontforge ttfautohint
  2. Add gem 'fontcustom' to your project Gemfile.
  3. Run bundle install
  4. Configure fontcustom
  5. Add a rake task
  6. Add 2 or more icon graphics to app/assets/icons
  7. Add imports to application.css
  8. Run rake icons:compile to generate icon font files
  9. Check it.

Configure fontcustom

We run fontcustom config to generate a configuration file in the app’s config folder. Then we can customize it to our preferences. Here is an example config file that we use:

# config/fontcustom.yml

font_name: icons
css_selector: .icon-{{glyph}}
preprocessor_path: ""
autowidth: false
no_hash: true
force: false
debug: false
quiet: false

input:
  vectors: app/assets/icons

output:
  fonts: app/assets/fonts
  css: app/assets/stylesheets

templates:
 - scss

This lets us put our svg icons in app/assets/icons, will output the compiled font files to app/assets/fonts, and uses the scss format, so that asset path helpers are used to correctly reference the fonts in the asset pipeline.

Rake Task

We add a rake task to wrap compilation for convenience and convention so that we can just run rake icons:compile.

# lib/tasks/icons.rake

namespace :icons do
  task :compile do
    puts "Compiling icons..."
    puts %x(fontcustom compile)
  end
end

Import _icons.scss in application.scss

We need to import the generated _icons.scss bundle into our application.scss.

// app/assets/stylesheets/application.scss
// ...
@import 'icons';
// ...

Check it

Per the configuration, fontcustom will generate class names of .icon-{{filename}} for each svg file included. To use an icon, we just need to add this class name to an element. Assuming we had an svg named arrow-up.svg, here’s how we’d use it in HTML:

<span class="icon-arrow-up"></span>

Now, when we need to add a new icon, all we have to do is add the .svg to app/assets/icons and run rake icons:compile. Much easier.

I put up an example app on Github if you’d like to see the code in action.

comments powered by Disqus