Many projects require custom icons at some point, and icon fonts are great for a lot of reasons. However, usually we don’t have the luxury of starting our projects with a complete design. Because of this, it can be helpful to start out with an existing, free icon set like Font Awesome.
In this post, I’ll show how I recently transitioned a project from using Font Awesome to a custom icon font using Font Custom.
Adding the SVGs to the repository
I prefer to store the SVGs in the project repository, that way the font can be updated and rebuilt at anytime. To do this, I created a directory
called app/assets/icon_svgs
. I added all of the icons to this directory, and renamed any SVGs that may have had spaces in the name (designers!).
As an example, I’m going to create a diamond icon font, so I’ve added the following files:
app/assets/icon_svgs/diamond-1.svg
app/assets/icon_svgs/diamond-2.svg
app/assets/icon_svgs/diamond-3.svg
For this example, I used SVGs from iconmonstr. (Thanks!)
Install and Configure Font Custom
Start by following the Font Custom installation instructions on their website.
Because we want anyone to be able to rebuild the icon font at any time, we’re going to create a fontcustom.yml
file
within the app/assets/icon_svgs
folder that we created above.
There are a ton of options, but here are the main details:
font_name: diamond-icons
# Format of CSS selectors. {{glyph}} is substituted for the glyph name.
css_selector: .diamond-i-{{glyph}}
# Generate fonts without asset-busting hashes.
no_hash: true
# Forces compilation, even if inputs have not changed
force: true
input:
vectors: app/assets/icon_svgs
output:
fonts: app/assets/fonts
css: app/assets/stylesheets
templates:
- scss-rails
preprocessor_path: ''
I’m specifying a custom css selector for our font, beginning with .diamond
.
I’m pointing the input to our SVG folder, and the output to the fonts folder. Finally, I’m using a built-in Font Custom template for Rails scss, since I’m using Sass.
You can see the full config file in this Gist.
Building the Font
At this point, from the project root, we can call fontcustom compile -c app/assets/icon_svgs/
to build the icon font. Notably, this
results in the creation of our font files, as well as our stylesheet.
create app/assets/fonts/diamond-icons.ttf
app/assets/fonts/diamond-icons.svg
app/assets/fonts/diamond-icons.woff
app/assets/fonts/diamond-icons.eot
create app/assets/stylesheets/_diamond-icons-rails.scss
Import the generated stylesheet
Next, we’ll simply need to import the generated stylesheet. Ideally, we should never need to edit the generated stylesheet (which makes it easier to rebuild as necessary).
@import '_diamond-icons-rails';
Add a helper method
We can take a look at Font Awesome’s source to see how they’ve implemented their icon helper. We’ll make a few customizations!
module IconHelper
def diamond_icon(names, options = {}) # changed helper name
classes = []
classes.concat Private.icon_names(names)
classes.concat Array(options.delete(:class))
text = options.delete(:text)
right_icon = options.delete(:right)
icon = content_tag(:i, nil, options.merge(:class => classes))
Private.icon_join(icon, text, right_icon)
end
module Private
extend ActionView::Helpers::OutputSafetyHelper
def self.icon_join(icon, text, reverse_order = false)
return icon if text.blank?
elements = [icon, ERB::Util.html_escape(text)]
elements.reverse! if reverse_order
safe_join(elements, " ")
end
def self.icon_names(names = [])
array_value(names).map { |n| "diamond-i-#{n}" } # changed class name here
end
def self.array_value(value = [])
value.is_a?(Array) ? value : value.to_s.split(/\s+/)
end
end
end
Update the README, so your team can rebuild the font
# Icon font
1. Install Font Custom http://fontcustom.com/
1. Add or update SVGs in `app/assets/icon_svgs/`
1. If any SVGs have spaces in their name, they MUST BE CHANGED TO `-`.
1. From the application root, run `fontcustom compile -c app/assets/icon_svgs/`
1. Remove the `.fontcustom-manifest.json` if it has been created
1. DO NOT edit the `app/assets/stylesheets/_diamond-icons-rails.scss` file.
All done!
Now you can use your new icon instead of, or alongside Font Awesome!
.icons
= diamond_icon "diamond-1"
= diamond_icon "diamond-2"
= diamond_icon "diamond-3"
= fa_icon "calendar"
If you enjoyed this post, please let me know on twitter @bolandrm, and/or use the form below to subscribe to my mailing list! Thanks for reading!