Add new comment

CSS: Website Font Customization

Because I have a pathological problem with leaving well enough alone, I was looking for yet another way to tweak my blog and hit on font customization. Web standards organizations and browser distributors are slowly converging on something approximating an agreement on how this is going to work. While we aren't really "there" yet, we're closer than ever before. Close enough, anyway.

Web designers have long been stuck with the unholy trinity of "Arial, Helvetica, sans-serif" because that was the only option they had. Since the dawning of the Internet, there have only been a handful of "web-safe" fonts and, as a consequence, most web pages look like, well, other web pages. Fonts needed to be installed on the desktop to be viewed by the reader, and the differences between operating systems and browsers ensured that there was no more customized method of type setting that would consistently work. But advances in the CSS specification, improvements in browsers, new APIs, and good old fashioned research has finally found a way to turn your web site into it's own special snow-flake.

The Easy Way

First, let's take a look at the new Font API Google has released. Or is releasing since, at this writing, it's still in Beta. But then we know what that means with Google.

Now, note that this is a bit of an experiment, so don't send me a nasty gram if you're missing Arial, but this site is currently sporting a Google supplied font called "Nobile". As you can see, it's a somewhat taller Serif font that looks just different enough to keep my site from looking exactly like every other site on the planet, while still remaining legible. (Now I just look like all the sites using the Google Font API).

Scoot over to Google's Font Directory and you can find the handful of fonts they've released so far. (See blogging.com for more on this.) Google hosts the fonts on their site so you need to insert a line of code somewhere on yours to make it available to your style sheet. On my Drupal site, I inserted this in my page.tpl.php file, called with every page render:

<link href='<a href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic'">http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,boldit...</a> rel='stylesheet' type='text/css'>

Just place it somewhere near the top, prior to body rendering. After that, I added it to my primary style sheet:

body {
color:#444;
font:12px 'Nobile', Tahoma, Arial, Helvetica, sans-serif;
margin:0
}

... and I was done. Doesn't get much easier. And because it's Google, the font probably downloads faster than if it was on my own server. But there are limitations.

Some people don't like to trust a third party to provide a piece of their site. More significantly, most people want more to choose from than the 18-or-so fonts currently available from Google. Fear not! There's another way.

The Not-As-Easy Way

If you really want control of your site's look and feel, you can upload a font, really any font, directly to your web server. But there are caveats to this method, too. For starters, most fonts, such as the ones the came with your Windows desktop or any of the applications you've installed, are "encumbered". They are copyright protected, and very few font publishers have authorized their fonts to be distributed by unaffiliated third parties on the Internet. As such, when installing a font for web use, your best bet is to go with open source fonts. Or pay for commercial ones with the appropriate distribution rights. You might guess my preference between the two options.

To make the font available for use, you have upload the font to your web server. Any web-accessible location should work, but for simplicity's sake, let's assume you put the font in the same directory as the style sheet calling it.

Next, the font family must be "declared" using the "@font-face" mechanism. Now, browser and OS rendering of this declaration is idiosyncratic, at best. Most mobiles probably wont see the fonts at all, older browsers don't agree with their younger progeny, and Microsoft is completely off on it's own on how to handle it. As such, anyone wanting to use the mechanism is advised to use the "bullet-proof smiley" syntax arrived at by the very clever Paul Irish after much trial and almost as much error.

e.g.

@font-face {
  font-family: 'Parchment';
  src: url('Parchment_MF.eot');
  src: local('☺'),
         url('Parchment MF.ttf') format('truetype');
}

There are a lot of syntactically correct ways to declare a custom font family, but all of them will fail in some way or other because of the aforementioned browser idiosyncrasies. This syntax, and it is rather specific in its implementation, is designed to fail in the fewest circumstances.

Microsoft, alone in the world of browser makers, insists that any custom fonts be in the "Embedded OpenType" (eot) format. If you want your font to work in MSIE, and you probably do, you'll want a version of it in ".eot" format. Since nothing else uses eot, the second source is required. The most common font types for The Rest Of The World are TrueType (ttf) and OpenType (otf). There are others that work in specific scenarios, and still others that are emerging, but these types will cover just about all of your audience, usually.

As noted, the specific order and syntax of the arguments are quite important. The eot file URL should be declared first, as MSIE will register the last source successfully read, and the smiley face is designed to make sure it will not successfully read the font intended for the other browsers. There's quite a lot more that went into this layout than that, and I encourage you to read Mr. Irish's blog, if only to feel a little of his pain.

There are quite a few unencumbered fonts to be had out there, with several available at "Webfonts.info". More can be had at the very helpful "Font Squirrel" where they also provide font kits including multiple formats and sample code for implementation. They also provide a tool to convert other fonts into kits. There are other tools out there to convert fonts, particularly to the somewhat elusive eot format, at Casey Kirsle's site and the Online Font Converter among others.

Some of these fonts come split out with a separate file for different variations such as italics and bold. These fonts create a special challenge in that each file has to be declared and assigned correctly. To declare multiple files in the same family, you could do something like this:

@font-face {
    font-family: 'Juice';
    src: url('JUICE_Bold-webfont.eot');
    src: local('☺'),
        url("JUICE_Bold-webfont.ttf") format('truetype');
    font-weight: bold;
}
@font-face {
    font-family: 'Juice';
    src: url('JUICE_Italic-webfont.eot');
    src: local('☺'),
        url("JUICE_Italic-webfont.ttf") format('truetype');
    font-style: italic, oblique;
}
@font-face {
    font-family: 'Juice';
    src: url('JUICE_Bold_Italic-webfont.eot');
    src: local('☺'),
        url("JUICE_Bold_Italic-webfont.ttf") format('truetype');
    font-weight: bold;
    font-style: italic, oblique;
}
@font-face {
    font-family: 'Juice';
    src: url('JUICE_Regular-webfont.eot');
    src: local('☺'),
        url("JUICE_Regular-webfont.ttf") format('truetype');
}

With this sort of declaration, you call the font family by the common name, "Juice" in this case, and let the browser work out which version to use.

e.g.

body {
color:#444;
font:12px 'Juice', Helvetica, sans-serif;
margin:0
}

The problem with this is that I encountered different handling of this syntax on different browsers. Apparently, not all rendering engines are yet capable of correctly determining if a block of text is of the "font-style: italic, oblique;" sort or the "font-weight: bold;". Some people swear by it, so you could certainly try that method.

Another way to handle split font styles would be to give each font file it's own family.

e.g.

@font-face {
    font-family: 'Juice-Bold';
    src: url('JUICE_Bold-webfont.eot');
    src: local('☺'),
        url("JUICE_Bold-webfont.ttf") format('truetype');
    font-weight: bold;
}
@font-face {
    font-family: 'Juice-Italic';
    src: url('JUICE_Italic-webfont.eot');
    src: local('☺'),
        url("JUICE_Italic-webfont.ttf") format('truetype');
    font-style: italic, oblique;
}

em i {
   font-family: 'Juice-Italic', Arial, sans-serif;
}

b strong{
   font-family: 'Juice-Bold', Arial, sans-serif;
}

Note that, here, different text decorations and weights have their own font families, so that the appropriate font variations is applied directly to the appropriate tags. While a bit more work, this method would give you a finer control of the rendering. Like most things involving style sheets, you'll have to just see what works for your site.

When trying out new "non-standard" fonts, you'll definitely want to test your site in multiple browsers and operating systems, as always. I found that some fonts that looked great in one environment made my eyes bleed in others. Also, font sizes can vary such that a "just right" 14px for your preferred font might be an eye popping monster on a fail-over font. Pull your custom font out before going live and make sure it still works for the reader. That's who you're trying to make happy, anyway.

And, finally. err on the side of conservatism when applying cool new fonts. Just because something looked good on a movie poster doesn't mean your viewers want to try to read an article marked up with it.

Trust me on that.

Tags: