HTML5 Fonts: Let’s Make them DRY

The Problem

Much fun can be had designing with the ever-increasing universe of fonts offered by directory’s like Google’s. Photoshop Tamagotchi is a thing of the past as you can rapidly iterate with a few keystrokes. But it’s still a few keystrokes too many …

A niggle with CSS3 fonts is they involve some redundancy. Here’s a real-world example:

  1. @font-face { font-family: Delicious; src: url('Delicious-Roman.otf'); }
  2. @font-face { font-family: Delicious; font-weight: bold; src: url('Delicious-Bold.otf'); }
  3. h3 { font-family: Delicious, sans-serif; }

What happened to Don’t Repeat Yourself? We have “Delicious” mentioned five times here! If we switch from the “Delicious” font to the “Pinboard” font, we’ll need to make five changes. And not everyone uses vim, yo. Moreover, we’ll need to locate a suitable font, e.g. Pinboard, and download it.

I get it, this level of indirection serves a purpose. We can give a handle to the font once and then use that everywhere else. Heck, we could even continue to call the font “Delicious”, but surreptiously switch the “src” to “Pinboard-Roman.otf”. But that wouldn’t be very nice, would it?

Now, a font directory like Google solves part of the problem by explicitly allowing you to link cross-domain to Google. In fact, if you want, it will even generate the stylesheet for you. But you’ll still have the same DRY issue in your CSS – for each new font, you’ll need to include the stylesheet and use it in your CSS.

The Solution

Bottom line, I decided to make this crazy snippet, by manually walking through the font directory and picking out every single possible font:

  1. <link href="http://fonts.googleapis.com/css?family=Droid+Sans|Lobster|Droid+Serif:regular,italic,bold,bolditalic|Nobile|Yanone+Kaffeesatz|PT+Sans:regular,italic,bold,bolditalic|PT+Sans+Caption:regular,bold|PT+Sans+Narrow|Reenie+Beanie|Tangerine:regular,bold|Molengo|OFL+Sorts+Mill+Goudy+TT:regular,italic|Vollkorn:regular,italic,bold,bolditalic|Cantarell|Inconsolata|Crimson+Text|Arvo:regular,italic,bold,bolditalic|Cardo|Neucha|Neuton|Droid+Sans+Mono|Cuprum|Old+Standard+TT:regular,italic,bold|Philosopher|Tinos:regular,italic,bold,bolditalic|Josefin+Sans:100,100italic,light,lightitalic,regular,regularitalic,600,600italic,bold,bolditalic|Arimo:regular,italic,bold,bolditalic|Josefin+Slab:100,100italic,light,lightitalic,regular,regularitalic,600,600italic,bold,bolditalic|Allerta|Geo|Allerta+Stencil|Puritan|Puritan:regular,italic,bold,bolditalic|Cousine:regular,italic,bold,bolditalic|UnifrakturMaguntia|Bentham|IM+Fell+DW+Pica:regular,italic|IM+Fell+English:regular,italic|IM+Fell+English+SC|IM+Fell+DW+Pica+SC|IM+Fell+Double+Pica+SC|IM+Fell+Double+Pica|IM+Fell+Great+Primer+SC|IM+Fell+Great+Primer|IM+Fell+French+Canon|IM+Fell+French+Canon+SC|Coda:800|Raleway:100|UnifrakturCook:bold|Covered+By+Your+Grace|Just+Me+Again+Down+Here" rel="stylesheet" type="text/css" />

I’ll repeat that below for ease of cut-and-paste:

<link href=”http://fonts.googleapis.com/css?family=Droid+Sans|Lobster| Droid+Serif:regular,italic,bold,bolditalic|Nobile|Yanone+Kaffeesatz| PT+Sans:regular,italic,bold,bolditalic|PT+Sans+Caption:regular,bold| PT+Sans+Narrow|Reenie+Beanie|Tangerine:regular,bold|Molengo| OFL+Sorts+Mill+Goudy+TT:regular,italic| Vollkorn:regular,italic,bold,bolditalic|Cantarell|Inconsolata|Crimson+Text| Arvo:regular,italic,bold,bolditalic|Cardo|Neucha|Neuton|Droid+Sans+Mono| Cuprum|Old+Standard+TT:regular,italic,bold|Philosopher| Tinos:regular,italic,bold,bolditalic| Josefin+Sans:100,100italic,light,lightitalic, regular,regularitalic,600,600italic,bold,bolditalic| Arimo:regular,italic,bold,bolditalic| Josefin+Slab:100,100italic,light,lightitalic,regular, regularitalic,600,600italic,bold,bolditalic| Allerta|Geo|Allerta+Stencil|Puritan|Puritan:regular,italic,bold,bolditalic| Cousine:regular,italic,bold,bolditalic|UnifrakturMaguntia|Bentham| IM+Fell+DW+Pica:regular,italic|IM+Fell+English:regular,italic| IM+Fell+English+SC|IM+Fell+DW+Pica+SC|IM+Fell+Double+Pica+SC| IM+Fell+Double+Pica|IM+Fell+Great+Primer+SC|IM+Fell+Great+Primer| IM+Fell+French+Canon|IM+Fell+French+Canon+SC|Coda:800|Raleway:100| UnifrakturCook:bold|Covered+By+Your+Grace| Just+Me+Again+Down+Here” rel=”stylesheet” type=”text/css” />

Now include that in your CSS and you can freely use whatever font you want, whenever you want:

  1. h3 { font-family: Neucha, sans-serif; }
  2. div { font-family: "Reenie Beenie"; }

Production Use

I haven’t tested it, but I’m informed modern browsers will thankfully download only the fonts they need, so this is actually a viable solution for sites which will be frequented only by modern browsers, though obviously the snippet itself is too big for sites where performance is critical.

Unfortunately, IE6-IE8 will actually download every single font specified! So really, you should only be using this for development, and ensure production sites only declare the fonts they need. However, don’t lose site of DRY! In the spirit of Agile, DRY, and Continuous Integration, it would still be worth looking at ways to automate that process, e.g. with a server-side solution that generates the minimalist “link” tag.

Of course, the snippet is limited only to the Google fonts, good enough for my aesthetically-challenged purposes, but the principle could be generalised to encompass other font directories. Or someone in a company which has licensed and/or issued a standard set of fonts via their style guide, could also generate a company-specific snippet fot this purpose, containing all fonts. They could then make this a standard stylesheet which could be linked to from any HTML document.

Events Last Week: Web Fonts, Social Design Patterns, BT Dev Day, Real-Time Javascript

Last week saw a confluence of excellent events. In the same week as a house move, it proved to be a week of much learning and little sleep. I’d hoped to do a better write-up, it never happened, a combination of being too busy and new MAC BATTERIES SUCK, meaning the lappy couldn’t last through the whole session. But fortunately, I have some links to point to. Here’s a quick summary anyway, along with the linkage.

Web Fonts at London Web Standards

@otrops captured the live notes in glorious detail, as did Rob Crowther.

Ben is ideally placed to cover the brave new world of web fonts, being a web maker who studied fonts at uni. He walked us through the evolution of font hacks on the web: image with alt tag; CSS background image with text pushed off the page; rendering with Flash (SiFR); rendering with Canvas or SVG (Cufon, TypeFace.js), using JSON-based font spec data. It all leads up to the holy grail: @font-face.

Great, so we have @font-face, but issues remain: * The foundries – Mark Pilgrim, in no uncertain terms, complains the font vendors are stuck in the dark ages of the printing press, in their resistance to support @font-face. This seems to be changing with WOFF, a web-only format that seems to placate the foundries, who worry their fonts will be stolen. It seems more like a symbolic gesture, since the data could still be converted and in any event the print fonts could still be appropriated, but the foundries are feeling more reassured and making signs they will go along with it. * Performance issue – Bandwidth issues and Paul Irish’s “flash of unstyled text”, where the user notices the font change once the fancy @font-face font has been downloaded. * Compatibility – IE has long supported font-face, but with EOT format fonts, and that remains the case. You therefore need both types of fonts, and licenses will generally not give you both.

Social Design Patterns

I was, needless to say, psyched about this. Yahoo! has been the closest thing to a realisation of the inspiring design pattern vision of the mid-late ’90s. Patterns on the web, for both its own employees and the wider community to learn from and evolve. These are social design patterns mined by Christian Crumlish (@mediajunkie), in many respect the closest thing software has to an analogy of building architecture, where design patterns originally came from.

There are 96 patterns in all and I’m looking forward to poring through them. In these patterns are hundreds of people-years’ experience of observing real-world social systems. In my own pattern work, I’ve found it necessary to articulate the overarching design principles behind the patterns. Pattern languages should be opinionated, so it’s a good thing to make explicit your criteria for filtering design features. Christian has followed this model too, and identified 5 overarching principles:

  • Paving the cowpaths. Facilitating the patterns that are already happening, rather than imposing your own invented process. Also means evolving with your users, ev dogster started as photo sharing but evolved to social network.
  • Talk like a person.
  • Play well with others. Open standards, mashups, etc. “if you love something, set if free”
  • Learn from games.
  • game UI concepts
  • designing the rules, but ultimately letting the people who come into the space finish the experience themselves.*
  • Respect the ethical dimension.

See the wiki or the book for more details.

BT Developer Day

This was an internal conference for BTers in London covering a range of general tech trends, and also being a chance to get together and talk shop. The agenda included talks on Scala, Rails, Kanban, iPhone development, and even a lightning talk from @psd on the horrors and delights of APL.

I gave a talk on Embracing the Web, emphasising open standards and the supreme primacy of Konami Cornification.

Real-Time Javascript

At the Javascript meetup, a great talk on NodeJS and WebSockets. NodeJS is coming on thick and fast, and Makoto Inoue showed how the technology plays nicely with WebSockets. WebSockets are all about Comet-style interaction, so expect to see a lot more of this combo in the next couple years.

Luis Ciprian, visiting from Brazil, gave us an overview of XMPP and talked us through a real-time web app – a basketball score and conversation tracker – using XMPP.

Fin.