Foundation-Icons and Google Fonts

In the last post I outlined what the Asset Pipeline is, how it works, and why it’s important. This post I’ll explain web-fonts, icon-fonts, and how to get both to play nice on Heroku in your asset pipeline. I’m going to assume that you use Sass for your stylesheets and every one of those stylesheets have the .scss extension. So make sure you have the sass-rails gem in your Gemfile. Since Rails 3.1, new Rails projects will be already configured to use Sass. Let’s rock!

What are Web-Fonts?

Web-Fonts are fonts that don’t exist on your system, they exist on some server somewhere. They’re downloaded by a user’s browser while rendering a web-page, kinda like linking to a remote image that you don’t have saved in your local environment. Web-Fonts can slow your sites load time because they have to be requested from somewhere. Optionally you can usually download a web-font and add it to your project, if you want to maximize performance.

Integrate Web-Fonts into my app please

Google recently released this sweet Web-Font: Lily Script One. And I wanted to take it for a test drive. @import allows stylesheets to import other stylesheets, it’s basically a link. So google provides this link: @import url(http://fonts.googleapis.com/css?family=Lily+Script+One); The classic newbie(myself) mistake is to throw that to the top of the stylesheet you happen to be using for styling these icons, wrong! You want to throw that @import link into your scss manifest(applications.scss).

What are Icon-Fonts?

Icon-Fonts are just fonts! However, instead of containing letters or numbers, they contain symbols and glyphs. You can style them with CSS in the same way you style your regular text which has made them very popular on the web. Icon-Fonts have so many awesome features like easy size, color, and shadow manipulation. You basically style these icons the same way you would style Text-Fonts. I’m going to show you how to add foundation-icon-fonts-3 to your asset pipeline, but will a little shimmy-ing this technique will work for any icon-font set.

First visit the foundation-icons link above and download the whole set. You’ll get a foundation-icons folder with a bunch of files and an svg sub-folder. Copy the whole foundation-icons folder and paste it inside the assets folder of your Rails project. Change the name of the folder to “Fonts”, Rails convention. Inside your Fonts folder add .scss to your foundation-icons.css. In fact, all of your .css files should have a .scss extension. This allows you to use both css and scss syntax(like nesting) inside your stylesheet and the Sass pre-compiler works its magic.

Next, open your fondation-icons.css.scss and notice how it’s @importing a bunch of other files with funky extensions (.eot .woff .ttf). For development this will work fine but for production this will not compile properly. We need to tweak the paths to look like this:

Don’t hold me to this, but what I believe is happening is this is creating relative-path url’s for each of the files. E.g. url(/assets/fonts/foundation-icons.eot). Last thing left to do is require this file in our stylesheet manifest(application.css.scss) like so:

Honestly, I figured this last part(*=require) wasn’t necessary. The Fonts folder is in the right place and the foundation-icons.css.scss file is importing everything it needs. I tried many many different ways to make these font-icons work both on my local server in development and in production. Foundation docs discuss nothing about integrating font-icons into your asset pipeline, even though they tout how compatible their framework is with Rails. What I’m doing works both locally and on Heroku, and I really don’t feel like digging deeper into the abyss.

Enter Font-Awesome!

In Rails projects the awesomeness of font-awesome is unmatched. All you need to do is add their gem, yeah they have a gem!, to your Rails gemfile and import their icons like so:

That’s it! That simple

Asset Pipeline

I once spent roughly 3.5 hours trying to figure out why my custom google font and foundation-icons-3 would not render in production on Heroku, and you know what? I learned a lot! Turns out there’s this thing called the asset pipeline, not the kind you’re offered at a rave or the world class Hawaiian reef break, and it determines whether your Rails app is worthy of style when you push it to your production server.

Turns out, the asset pipeline is one of the simplest and least understood rails features for developers. Instead of me just telling you how to make your custom web-font and font-icons work on Heroku, which I will in part-II, I rather compress the brain-drain I just experienced into something of value. Keep in mind this is just a high to mid-level overview, we’ll get into more tricky aspects in part-II.

What is the asset-pipeline?

Your Rails application has a folder called “assets”, assets are just all of your css, javascript, and image files. Think of it as everything that’s going to turn your plain ol HTML page into a stylish, interactive beauty. The asset pipeline serves 3 very important purposed: precompiling higher level languages, concatenating assets, and minifying files.

Precompiling

The only native language to most browsers is JavaScript, but browsers also have HTML and CSS parsers. These are lower level languages for the browser. Your stylesheets written in Sass and scripts written in CoffeeScript have to be pre-compiled(translated) into these lower level languages for the browser to properly render your pages.

preprocessor

Concatenating

Any file you create inside the assets folder essentially becomes part of the asset-pipeline, but you should stick to convention and add CSS files to the stylesheets folder and JS files to the javascripts folder. There’s 2 dominant files you need to pay attention to: application.js and application.css. These files are called Manifests, no relationship and not nearly as destructive as the Manifest Destiny. Essentially each of these files pull in(concatenate) all other files with like extensions. It’s actually the Sprockets Gem that’s doing this magic. For example, if you have 5 custom CSS files inside of Assets, the application.css is going to pull in all of those files and create one big file. How? The require_tree . directive, inside the Manifests is a command that says “get over here all you like files.” The require_self directive just says: “every bit of code inside this Manifest file is gonna join the party as well.” Why? Because concatenating things into one file for the server to hand to the client(browser) improves Performance! In the JS Manifest the directives begin with //= and in CSS with *= , they essentially do the same thing.

Concatenating-Puzzle

Minifying

Lastly, the asset-pipeline is responsible for minifying these Manifest files. Think of how much extra space and comments each one of your stylesheets and JavaScript files contain, and picture removing all of that, that’s what a minified file looks like. Long variable names are also chopped down. The functionality ends up unchanged, the code is just smooshed together like that house party I was at last week. Why minify? Performance!

minify-js-before-after

Awesome, but how does your application actually find these Manifest files? Magic! Along with link_tags inside your application layout: app/views/layouts/application.html.erb. Consider this file a universal default master file for all the views. It’s sorta like a Manifest file in the sense that it pulls all of the HTML from each one of your view files into itself by way of <%= yield %> (if you’re using erb as your templating language). We link stylesheets and scripts in the <head> of this file like this: <%= stylesheet_link_tag “application” %>. This points to the Manifest CSS file.

Sometimes just the order in which you require files might be incorrect, which causes certain files to override others. This is quite possibly the most important and overlooked section in Rails docs:

Directives are processed top to bottom, but the order in which files are included by require_tree is unspecified. You should not rely on any particular order among those. If you need to ensure some particular JavaScript ends up above some other in the concatenated file, require the prerequisite file first in the manifest. Note that the family of require directives prevents files from being included twice in the output.

 

In conclusion, you’re application layout file has a link pointing to your Manifest files. These Manifests should already be requiring all of your assets in the order in which you intend. Roughly 90% of problems I’ve seen people have with the asset pipeline come from improperly requiring files or frameworks from within their Manifests.