Cross Browser font-face Mixin

Cross Browser font-face Mixin

When self hosting your own fonts, we all know that the current "best practice" isn't necessarily in the most stable state. There are all the different font files you must keep up with (.svg, .eot, .ttf, .woff) and the different syntax's you have to get just right. It's not the worst, but if you are writing sass already, it's a prime time candidate for abstracting away so that you can use it over and over as needed for different fonts within your application. Not only that but as updates are made to required syntax, you can make it in a single place. Any way let's cut to the chase, here is the plane jane css syntax.

font-face css directive

@font-face {
	font-family: "OpenSans";
	font-weight: bold;
	font-style: normal;
	src: url("../fonts/OpenSans-Semibold.eot"); 
	src: url("../fonts/OpenSans-Semibold.eot?#iefix") format("embedded-opentype"),
             url('../fonts/OpenSans-Semibold.woff2') format('woff2'),
		 url("../fonts/OpenSans-Semibold.woff") format("woff"),
		 url("../fonts/OpenSans-Semibold.ttf") format("truetype"),
		 url("../fonts/OpenSans-Semibold.svg#OpenSans-Semibold") format("svg");
}


That's nice, and it works like we want, but it's complicated and error prone to update when you have lots of different font weights/style/family in the same document. If you need explanation on this syntax, check out Paul Irish's post on Bulletproof font-face Now, what we want to do is create a mixin, which is basically a function, and pass the font specific values to so that the vendor specific parts of these statements are abstracted away and out of our reach when we are building the front end. Take a look at our sass mixin, basically the same except it's wrapped in a function call and the font-specific values are swapped out with calls to the parameters that were passed in.

@mixin includeFont($fontFamilyName, $fileName, $weight: normal, $style: normal) {
@font-face {
    font-family: $fontFamilyName;
    font-weight: $weight;
    font-style: $style;
        //IE9 Compatibility Mode
        src: url('../fonts/#{$fileName}.eot');
        //IE6-IE8
        src: url('../fonts/#{$fileName}.eot?#iefix') format('embedded-opentype'),
             //Super Modern Browsers
             url('../fonts/#{$fileName}.woff2') format('woff2'),
             //Majority of Modern Browsers
             url('../fonts/#{$fileName}.woff') format('woff'),
             //Safari, Android, iOS
             url('../fonts/#{$fileName}.ttf') format('truetype'),
             //Legacy iOS
             url('../fonts/#{$fileName}.svg##{$fileName}') format('svg');
    }
}

So we see this mixin expects you to pass in the font-family name, the name of the font file (not including the extension), and optionally the font weight and style. You should place this includeFont function in a sass library file so it's available to other stylesheets as well. Here is an example of how you would call this function.

@include includeFont("OpenSans", "OpenSans-Regular", 600);
@include includeFont("OpenSans", "OpenSans-Light", 400);
@include includeFont("OpenSans", "OpenSans-Semibold", 700);


That's basically it! You could go back and add the path to the font file as part of the function call if you needed that configurable, but that's up to you.

Debugging

To really see what's going on you should open up the network traffic log in your developer tools. If things are working you'll see the font files listed with a request method of GET, and some type of successful status code like 304 Not Modified, 200 OK or 206 Partial Content. If you are getting a 404 or other type of fatal code it's obviously having some trouble either finding or accessing the font files so you'll have to double back around to ensure you have specified the correct path to your font files, make sure the actually exist on the server, and make sure they have the correct permissions (0644 should do fine).

You may need to add the woff2 mimetype to your Apache configuration. The easiest way to do this is to edit the .htaccess file that lives in your web root.

AddType  application/font-woff2  .woff2