Archive

Archive for the ‘typography’ Category

Details on the new Google Webfont API

May 19th, 2010

As you might have see, Google now offers a full webfont API. Luckily, they let me dig into the service and code a few weeks back. So let me give you the lowdown on the features and what you can do with it…

Here's adding a @font-face declaration for Tangerine, a nice scripty font:

<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Tangerine">

You'll then reference it font-family:Tangerine and be all set. As for something a bit more complicated:

<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Inconsolata:italic,bolditalic|Droid+Sans">

There's Inconsolata regular, italic and bold-italic and Droid Sans regular.

There is a high-quality curated portfolio of open fonts available (Raph Levien, designer of Inconsolata guided this project). And view the real documentation on the CSS api.

Obviously there are huge caching benefits to using the Google Font API, plus they're very focused on performance and you can expect things to be fast and FOUT to be minimized. But on the topic of FOUT…

The WebFont Loader is also making its debut. This is a javascript library collaboration between the good boys at Typekit and Google. It basically allows a lot of control over the display details of webfonts.

Let's say you want Firefox to not have the FOUT, but rather mimic webkit's behavior of invisible text until the font is loaded:

<script src="http://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
<script>
  WebFont.load({
    google: {
      families: ['Cantarell']
    }
  });
</script>
<style>
  .wf-loading h1 { visibility: hidden; }
  .wf-active h1, .wf-inactive h1 { 
    visibility: visible; font-family: 'Cantarell'; 
  }
</style>

The WebFont Loader API provides some classes on the <html> element (a la Modernizr) and a bunch of javascript callbacks.

Check out all the WebFont demos, showing off all its capabilities. One of my favorite parts is that you can use the events and hooks it provides with your very own hosted fonts (in that demo I load Taggeschrift from paulirish.com).

The webfont loader is now an open-source project on github. Feel free to peek under the covers. Oh and do check the project docs: getting started, webfont loader, technicalities, and faq.

Ask any questions in the comments and I'll do my best to clarify. :)

2010.05.19: The Google webfont previewer tool (with jQuery!) is pretty tight, too.

2010.05.20: Update via Florian to use .wf-loading to hide for FOUT prevention.

Take a look at some of my other (recently updated) webfont stuff:

Paul Irish front-end development, typography

@font-face gotchas

May 5th, 2010

Over the past few months, I've collected a few worthwhile notes on @font-face that are worth reading over if you geek out about this stuff…

  • in Webkit (Chrome/Safari), applying font-weight:bold to faux-bold some @font-face'd text will not succeed. Same applies for font-style:italic. You can fix by adding the following to your @font-face declaration: (via doctype, crbug/31883, crbug/35739webk.it/34147)
      font-weight:normal;
      font-style:normal;
      font-variant:normal;
      /* these values are defaults in FF/Opera/IE but not webkit */
  • FF/Linux cannot serve webfonts from the file:// protocol. (Also, a tome on type quality with linux from Evan Martin)
  • TrueType format renders with a better quality than Opentype CFF. (sez Typekit) (fontsquirrel default)
  • In IE6-8, using createStyleSheet and then setting styleElem.styleSheet.cssText to a text value that includes a @font-face declaration going into will crash IE6-8. (src)
  • font-size-adjust (only supported in Firefox) normalizes x-height and may improve the FOUT.
  • text-transform doesn't play well with @font-face in current implementations. (via snook & Gary Jones)
  • @font-face doesnt play nice with css transitions. (via ethan marcotte)
  • IE6 under High Security settings will pop a security dialog when a site tries to use @font-face. (via Wouter Bos)
  • There have been reports that when a font is segmented into multiple files, a css text-shadow can overlap in a weird way. (pics plz? :)
  • Aaron James Young dug into @font-face on obscure linux-only browsers.
  • If a @font-face declaration is within a media query @media screen { ..., it will fail in Firefox. (Thx Ben Kulbertis) http://bugzil.la/567573
  • Hosting the fonts on a different domain? Firefox requires some extra effort; you'll need to add the Access-Control-Allow-Origin header, whitelisting the domain you're pulling the asset from. Example .htaccess config here. Alternatively, you can use the base64 encoding in CSS (create it with the fontsquirrel generator) to avoid setting headers. details here
  • SVG Fonts - Currently SVG is the only way to get webfonts working on iPhone and iPad. It is the most rudimentary format for fonts on the web.
    • SVG Fonts lack kerning and other complementary information
    • SVGz is a format that bakes compression right in and will save you bandwidth overhead. But you'll need to add this to to your .htaccess for this benefit. AddType image/svg+xml svg svgz AddEncoding gzip svgz (via @fontsquirrel)
    • SVG fonts don't work with a cache manifest. Due to the manifest treating # as comments and Mobile Safari requiring the font ID reference in the URL. [Unverified] (via Tristan Dunn)
    • Using text-overflow: ellipsis; turned the contents into only "…" and nothing else. (via Tristan Dunn)
    • Letter-spacing css doesnt appear to work with SVG fonts.
  • IIS Needs some custom mimetype configuration for serving webfonts. To enable, go to: Default Web Site > Properties > HTTP Headers > File Types > New Type…
    • .otf : font/otf
    • .svg : image/svg+xml

    (thx ProtectedVoid & Tom Nelson) — Test page

@font-face links that might have sneaked past you

And.. regarding @font-face syntax

I now recommend the bulletproof smiley variation over the original bulletproof syntax.

@font-face {
  font-family: 'Graublau Web';
  src: url('GraublauWeb.eot');
  src: local('?'),
         url('GraublauWeb.woff') format('woff'), url('GraublauWeb.ttf') format('truetype');
}

From the bulletproof post:

Yes, it's a smiley face. The OpenType spec indicates any two-byte unicode characters won't work in a font name on Mac at all, so that lessens the likelihood that someone actually released a font with such a name.

There are a few reasons why smiley is a better solution:

  • Webkit+Font Management software can mess up local references, like turning glyphs into A blocks.  (crbug.com/33173)
  • On OS X, Font Management software may alter system settings to show a dialog when trying to access a local() font that's accessible outside of Library/Fonts. More detail on my bulletproof post. (crbug.com/29729) Font Explorer X is also known to mess up other stuff in Firefox: bugzil.la/531771
  • Although it's unlikely, you could reference a local() font which is completely different than what you think it is. (Typophile post on different fonts, same name) At the very least its a risk, and you're ceding control of the type to both the browser and host machine. This risk may not be worth the benefit of avoiding the font download.

These are all pretty edge case issues, but it's worth considering. FontSquirrel has already made the smiley syntax the new default in the Generator, and you should use it going forward as well.

2010.05.10: Added IE6 security issue from Wouter.

2010.05.13: Added segmented font/text-shadow issue.

2010.05.17: Link to linux @font-face research

2010.05.22: Media Queries firefox failure added.

2010.05.29: Cross-domain tricks added. SVGz trick added

2010.07.06: Added a bunch around SVG fonts

Take a look at some of my other (recently updated) webfont stuff:

Paul Irish typography

Updates from all around - Dec 2009

December 19th, 2009

A lot of the work I'm doing doesn't turn into new posts so here's a summary of what's been going on:

yayQuery

Since it was announced here, we've come a long way. We just put out our 7th episode (now in HD!). The show format has tightened up and we're putting a lot of time into making it even better. Follow us on twitter or subscribe to catch all the goodness. We also put out an entire episode devoted to what's coming in jQuery 1.4 (aka 1.MOAR), so peep it if you're curious.

jQuery Singalong plugin

I was a finalist at Boston's Music Hack Day with the jQuery Singalong plugin. It essentially allows you to add timed annotations to the HTML5 audio and video elements. (Also it was the first time I legitimately used javascript's Infinity :) In addition, I put out the (very!) alpha jQuery Bouncing Ball plugin. Check out the demos to get a taste

Modernizr updates

Faruk and I pushed out Modernizr 1.1, which can now detect what audio/video formats your browser supports, all sorts of HTML5 forms goodness, and some other ones like localStorage and applicationCache. We're delighted to be part of Mark Pilgrim's Dive into HTML5 book and pumped to help push the edge of progressive enhancement.

@font-face and webfonts

It's a rapidly changing landscape, so I've been keeping all my font-y posts up to date:

@font-face feature detection

I've updated the existing feature detection script to use a smaller file. (Thanks to the Font Squirrel for the help). You would use this script to detect if support is present or not; perhaps implement a Cufon fallback. These new improvements will make their way into Modernizr 1.2.

I've also added on a isFontFaceSupported browser sniffing alternative. The main benefit here is that you're guaranteed accurate results synchronously. (The true feature detection can't do that, though the new small size is much faster in Firefox.)

Other bits and bobs

The nice guys at that other jQuery Podcast had me on the show in November. I talked about, well.. basically all of the stuff above. :) It's a good show.

I tweeted about a new quick approach to a for loop:

for (var i = -1, len = arr.length; ++i < len; ) // the cool guy loop

The fun part is that the counting expression (the third part) is empty. It's faster than your standard loops, but reverse while() is still quicker. @jdalton beat me to this one, for the record.

Lastly, along with my writers, I've been keeping my mp3 blog Aurgasm fresh with new music you'll love. I've got a lot more things in the pipeline, so right after my Christmas and New Years jaunt around Germany, Denmark, and Scotland, you'll see them soon. Happy December ya'll.

Paul Irish javascript, jquery, typography

Fighting the @font-face FOUT

October 7th, 2009

FOUT is what I'm calling the flash of unstyled text that you get while using @font-face in Firefox and Opera.

In June, Remy Sharp documented the how a browser progressively renders a page using @font-face. Things work differently between browsers natch:

Here's how in Firefox; basically the text is in a default webfont until the custom font is ready:

Webkit takes a very different approach, and very intentionally. They believe it's better to keep the text invisible until the font is ready. This way, there is no moment where the text flashes into its newly upgraded self. (This moment should be familiar to you if you've used sIFR)

I really don't like the text upgrade FOUT, so I personally prefer webkit's technique. But either way, we want the font loaded ASAP, so let's speed it up!

Best practices for serving fonts:

  • Minimize the overall kilobyte size of your font file. You can reduce the size of your font file by subsetting it (more on this later).
  • Heavy caching via a far-future expires header.
  • Gzip? Well, no; you can't gzip a font file, though you can gzip a css file that holds the data-uri representation, but you don't get much gain there. It'd primarily be an obfuscation technique.Stoyan Stefanov has done some excellent research into @font-face and gzip. Summary: It's possible! 40-45% savings. Do It!

When exactly do browsers download the font file?

Garrick at Kernest tipped me off to IE's interesting behavior here.

After some research we can see when the asset download is initiated:

  • IE will download the .eot file immediately when it encounters the @font-face declaration.
  • No browsers download the font file when they find a css rule that references the @font-face font.
  • Gecko, Webkit, and Opera all wait until they encounter HTML that matches a CSS rule with a fontstack including the @font-face font.

I've put up a test page where you can experiment and watch your dev tools to see when the file is grabbed.

In what cases will you get a FOUT
  • Will: Downloading and displaying a remote ttf/otf/woff
  • Will: Displaying a cached ttf/otf/woff
  • Will: Downloading and displaying a data-uri ttf/otf/woff
  • Will: Displaying a cached data-uri ttf/otf/woff
  • Will not: Displaying a font that is already installed and named in your traditional font stack
  • Will not: Displaying a font that is installed and named using the local() location
2010.05.26: I removed a bunch of old stuff from this article; it was kinda outdated. Additionally, the new google WebFont Loader can make mozilla behave like webkit and vice versa when it comes to FOUT. I'll update this article later on with how, specifically. :)

Is this the end-all be-all solution to quick load and FOUT?

Nope. As Jonathan Snook pointed out in the comments, these won't elimate seeing the fallback font FOUT in Gecko and Opera, they only prioritize the load of those fonts. As we know, browsers have a limit of concurrent connections, so we're using these tricks to get the fonts first in line.

Also, This is really only for the initial time, because after that, your far-futures expire header means the ttf stays cached locally, no more requests needed.

I'm not sure if we'll be able to use webkit's transparent font load in Gecko in any graceful way. (It's possible with a sniff and polling, but that seems like overkill) I'm also not sure if we'll get Gecko's load technique in Webkit, which would be optimal for slow/mobile connections. For the time being your time is best served getting the font size very small, gzipping it, prioritizing it first, and caching it for a while.

Defeat the Firefox FOUT entirely

A little bit ago, Typotheque posted a technique aiming to avoid the FOUT. Using jQuery, they hide the body on dom ready, and then reveal it at the window load event.

The posted technique doesn't work as:

  • It targets all users, but we should only tweaks things for Firefox 3.5+ users.
  • Users will actually see the text before it's hidden during at dom ready.
  • As was mentioned earlier, fonts are downloaded when text appears in the page that the font will apply to. Therefore, anything hidden with display:none will not request the font file.
  • Not everyone has jQuery, so let's go with something more general

The one serious caveat to this technique is: The page will not be visible until all content, iframes, remote scripts, fonts, and images are downloaded. for a maximum of three seconds (I added a three second bailout condition, read below.)

This should run in the <head> somwhere:

(function(){
  // if firefox 3.5+, hide content till load (or 3 seconds) to prevent FOUT
  var d = document, e = d.documentElement, s = d.createElement('style');
  if (e.style.MozTransform === ''){ // gecko 1.9.1 inference
    s.textContent = 'body{visibility:hidden}';
    e.firstChild.appendChild(s);
    function f(){ s.parentNode && s.parentNode.removeChild(s); }
    addEventListener('load',f,false);
    setTimeout(f,3000); 
  }
})();

First, we are detecting if we're firefox 3.5+ by seeing if -moz-transform is supported, which was added at the same time. We use visibility:hidden instead of display:none, so that the font will actually be requested, and we remove that style once the page has finished loading. We're hinging on window load to be our re-entry point, because as Steve Souders pointed out, "font files block the window’s onload event from firing in IE and Firefox, but not Safari nor Chrome."

I've also added a 3 second bailout condition; this means if the page has not completely loaded in three seconds, we're going to show it anyway. It's possible the font won't be ready, but unlikely, I believe. This aims to solve the issue Remy found with the Standards.next site. I wouldn't recommend it, but you can disable this behavior by commenting out the setTimeout line.

2009.11.07. Added the Defeat the Firefox FOUT section.

2009.11.08. Tweaked defeat FOUT code to have a 3 second bailout.

2009.12.14. Added the In what cases will you get a FOUT section.

2010.05.03 font-size-adjust (only supported in Firefox) normalizes x-height and may improve the FOUT.

Take a look at some of my other (recently updated) webfont stuff:

Paul Irish front-end development, typography

Chrome and @font-face: It's here!

September 25th, 2009
January 25, 2010: It is now in the stable Chrome release! The wait is over, everyone. :) [release notes]

Today, Zeldman issued an ultimatum that we've all been feeling recently:
Chrome needs to support @font-face immediately.

It's true, every major browser supports @font-face:

  • Internet Explorer: since IE5
  • Firefox: since FF3.5
  • Safari: since Safari 3.2
  • Opera: since Opera 10

But..
Google Chrome currently does not enable @font-face linking to ttf and otf.

It actually does support SVG fonts in a @font-face declaration. View this demo in Chrome or Chromium to see svg fonts in action. Divya has some great research around fonts and SVG if you're interested in more.

You can turn it on, at will

You can enable web fonts with an executable switch: −−enable-remote-fonts.

On Windows, you can tweak the shortcut path, like so.
With Chromium on OS X, you use Terminal to launch:

/Applications/Chromium.app/Contents/MacOS/Chromium --enable-remote-fonts

With proper Google Chrome on OS X, you need to escape the spaces:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --enable-remote-fonts

With Chromium on Linux[1]:

chromium-browser --enable-plugins --enable-remote-fonts %U

Once you enable it, all @font-face stuff works just as you'd expect, including the bulletproof @font-face syntax [demo] and the Nice Web Type demos.

But we need web fonts working by default

Wait, so why is this wonderful feature disabled by default? Security review. Ian Fette, the program manager of Chrome, indicated that they need to explore how do webfonts in a "reasonably safe manner". So that's the holdup.
This ticket on the Chromium bug tracker tracks the feature being enabled by default.

Okay, so when do we get our toy? Soon, in fact!

Chrome is my default browser, so my patience on this issue ran dry recently. I emailed Takuya, an engineer at Google Japan, who is working on this and he said:

We are almost done. The code is under review internally within Google. I'm expecting to make it public no later than a week or so.

So I expect we'll be seeing @font-face support enabled by default in the Chrome dev builds soon. Based on their release schedule I think it'll be near the end of the year when we see it in Chrome stable. That's good news; let's hope we see it sooner.

2009.10.19 : The ticket tracking @font-face on by default gained the Milestone-4 label, indicating it will be included in Chrome 4 Stable.

2009.11.04: The Chromium team has released ots - an OpenType sanitizer library meant to clean any security concerns from a font file included via @font-face. They have also filed a bug upstream with WebKit to integrate this code at the Webkit level. Finally we see the fruit of their security review.

2009.11.18: Remote fonts are now enabled by default!!! This should only be in the dev builds for now. I'll update when it makes it to beta builds and eventually the stable. But right now it still looks like we'll see this in version 4 stable. (Nov 21: confirmed its in dev builds.. starting with version 4.0.249.4 [blog post], [rev 32300])

2009.12.09: @font-face support is now in the Chrome Beta of both Windows and Mac.

2010.01.25: @font-face support is now in the Windows Chrome Stable release! [release notes]

Paul Irish front-end development, typography

i left this space here for you to play. <3