Font icons like a boss with Sass & Font Custom
⚠️ This article is outdated: First I moved on to a custom Gulp workflow, then for a while I used SVG symbols and external references with a polyfill. Now I use inline SVG React components, and occasionally plain old .svg
files in img
tags.
Here we take “Fun with Sass & font icons” to the next level by automating the tedious stuff, including the actual font generation.
Manage all your project’s font icons in one folder as nicely named SVG files. Add icons to this folder to have your fonts magically rebuilt and your Sass automatically set up for you to start using the icons via their nice names; without touching your markup or dealing with non-semantic class names.
What are the perks?
- Manage your icon font entirely offline. Save yourself trouble manually configuring, downloading and integrating fonts every time you want to make a change.
- Easily add only the icons you need as you go; keep those font files speedy!
- Use your favorite SVG editor (Sketch, Illustrator, etc.) to create or tweak icons.
- Much better Git versioning and collaboration. Merge in new icons others have added and track all changes clearly.
Setup
1. Requirements
You will need to install:
- Font Custom ruby gem. A couple of dependencies including FontForge will also be installed.
- Sass ruby gem version 3.3+, we need the SassScript maps feature.
2. File structure
Create the following folders and files:
├── fontcustom/
│ ├── fontcustom.yml
│ ├── templates/
│ │ ├── _font-icons.scss
│ │ └── _icon-font.scss
│ └── vectors/
└── scss/
└── styles.scss
3. Prepare the fontcustom.yml config file
This file contains:
# Font Custom config: https://jaydenseric.com/blog/font-icons-like-a-boss-with-sass-and-font-custom
font_name: icons
no_hash: true
input:
vectors: vectors
templates: templates
templates: [_font-icons.scss, _icon-font.scss]
output:
fonts: fonts
_font-icons.scss: ../scss
_icon-font.scss: ../scss
The paths are relative to the config file’s location. Tweaking this structure may give you headaches until a particular bug is fixed.
4. Prepare the _font-icons.scss template
/fontcustom/_font-icons.scss is not a Sass file. Font Custom will use this template to create a Sass file in the location configured (/scss/_font-icons.scss) each compile.
$font-icons: (<% @glyphs.each do |name, value| %>
<%= name.to_s %>: "\<%= value[:codepoint].to_s(16) %>",<% end %>
);
5. Prepare the _icon-font.scss template
Again, this is a template; not yet an actual Sass file.
@font-face {
font-family: Icons;
src: url("data:application/x-font-woff;charset=utf-8;base64,<%= woff_base64 %>") format("woff");
font-weight: normal;
font-style: normal;
}
6. Prepare your main Sass file
In /scss/styles.scss
, allow easy use of font icons in your main stylesheet by importing the two Sass partials, along with a nifty mixin:
@import "font-icons";
@import "icon-font";
@mixin icon($position: before, $icon: false, $styles: true) {
@if $position == both {
$position: "before, &:after";
}
&:#{$position} {
@if $icon {
content: "#{map-get($font-icons, $icon)}";
}
@if $styles {
speak: none;
font-style: normal;
font-weight: normal;
font-family: Icons;
}
@content;
}
}
// The rest of your sexy styles here...
Usage
1. Add new icons to the project
To add a new icon, save it to /fontcustom/vectors as an SVG named what you want to call it by in your Sass.
I highly recommend square 32 × 32px SVGs with an accuracy of at least 3 decimal places.
The IcoMoon web app is the most convenient way to get new icons. Search from a huge range of great collections, select the ones you like and click the SVG download button. This will give you a nice zip of SVG files ready for you to drop into your project.
It’s always a good idea to optimize SVG with a tool like SVGO before use.
Here is what the project looks like with a few new icon SVGs:
├── fontcustom/
│ ├── fontcustom.yml
│ ├── templates/
│ │ ├── _font-icons.scss
│ │ └── _icon-font.scss
│ └── vectors/
│ ├── facebook.svg
│ ├── twitter.svg
│ └── heart.svg
└── scss/
└── styles.scss
2. Run Font Custom
You must run Font Custom whenever you update your icons. In Terminal, navigate to the /fontcustom folder and run fontcustom compile
. If you are doing a lot of work on your icons use fontcustom watch
instead to automatically recompile any time a change is detected within the /fontcustom folder. watch
seems to be a bit broken these days, so I tend not to use it much.
Our project now, with compiled files and folders:
├── fontcustom/
│ ├── fontcustom.yml
│ ├── fonts/
│ │ ├── icons.eot
│ │ ├── icons.svg
│ │ ├── icons.ttf
│ │ └── icons.woff
│ ├── templates/
│ │ ├── _font-icons.scss
│ │ └── _icon-font.scss
│ └── vectors/
│ ├── facebook.svg
│ ├── twitter.svg
│ └── heart.svg
└── scss/
├── _font-icons.scss
├── _icon-font.scss
└── styles.scss
Note the new /fontcustom/fonts folder. We don’t need it since we are embedding the font in the CSS as base64 WOFF. Unfortunately, Font Custom always creates these files. You can safely delete the folder, or if you use Git just add it to your .gitignore file like I do:
fontcustom/fonts
.fontcustom-manifest.json # Ignore this temporary file too
3. Use the icons in the Sass
You are now ready to use the new icons throughout your Sass. Please refer to the Usage section of my detailed article about the icon
Sass mixin for code examples.
IE8 support
To tailor the same workflow for IE8 support, skip the _icon-font.scss
template and use a standard @font-face
declaration referencing the actual font files Font Custom generates instead.