Tom Lauck’s

A First Date with TypeKit


Several weeks ago, I found myself in a friendly debate with a co-worker over the handling and future of fonts through the web browser.  Hours later, a TypeKit invite landed in my inbox; how coincidental.

Vegetarian Chicken

To break down what is happening with TypeKit, Jonathan Snook has a nice article that articulates the licensing limitation and techniques needed for successful @font-face embedding – TTF/OTF, EOT, and SVG.  These are the basic tenets of utilizing @font-face from a technical standpoint, minus TypeKit’s JavaScript for legal embedding and SVG.

@font-face {
	font-family: 'GothicCustom';
	src: url("LeagueGothic.eot");
	src: local('League Gothic'),
		url("LeagueGothic.svg#lg") format('svg'),
		url("LeagueGothic.otf") format('opentype');

Jonathan Snook – Becoming A Font Master

He also encapsulates the fact that font issues break down to essentially two buckets, browser compatibility and licensing.  This is a huge differentiator for TypeKit – all fonts based on your subscription level are properly licensed.  This does not come without a caveat unfortunately.  Rather than choosing from fonts common to designers such as Frutiger, Futrura, Univers, etc – TypeKit presents a list of imitations.  And thus I suddenly felt like I was looking at a Chinese buffet dish labeled as “chicken” even though it’s not – you’re not fooling me!

Rationale: Who cares if it’s not real chicken, Chinese “chicken” tofu kind of tastes and feels like real chicken so stop complaining – it’s healthy for you.  Translation: TypeKit font families aren’t quite what you are used to but most of them are close enough – and they are fully licensed, everyone is happy.

The Vegetarian Dies of Malnutrition

If you are not a fan of JavaScript and are just interested in a purist CSS only solution, you should really leave now – yes, TypeKit relies on JavaScript just as most of its competitors. Comparing apples to apples (in this case TypeKit vs sIFR), TypeKit’s JavaScript footprint is a bit smaller than sIFR’s ~10k compared to sIFR’s ~20k.  But wait – how exactly is the font getting inserted into the page – it’s not like we are using a system font that can just be accessed at the OS level?  As it turns out, each font in TypeKit is upwards of 100k and in my small use case, for 2 fonts in my kit, I was hitting 240k. Now you can trim this down depending on the font you choose and exact character sets, however, this was what the TypeKit editor defaulted to for my demo site’s needs.  


Comparing apples to apples again, in my small use case for 2 separate fonts via a single SWF file – oh and these were my EXACT brand fonts, not imitations – I was hitting about 50k.  This could certainly explain the load and render delay many (not just myself) have been experiencing with TypeKit.  Another contributor to render time could be the fact that TypeKit requires their script to load in the <head>.  This is contradictory to Yahoo’s optimization guidelines and progressive loading – it forces that 250k to be rendered before anything else on page can be rendered.  Did I mention TypeKit costs money too?

File size and loading optimization aside, browser compatibility – the overriding limiting factor we usually face is also an interesting study. Obviously there is always a significant margin in these statistics, but for reference here is the current browser usage share and Flash penetration:



Adobe Systems, Inc.

In some of my personal findings with TypeKit, Chrome is a no-go, along with earlier versions of Firefox, IE, Opera, and Safari and sporadic behavior in all of the above. And I’m not the only one.  Again TypeKit is still in beta, so they get a little bit of a freebie here, but the fact remains that @font-face has remained somewhat elusive for so long, for so many reasons, and to think that it is solved right now would be a bit naïve.  By comparison, Flash replacement is somewhat bulletproof these days as Flash has become somewhat ubiquitous.

Give Me My Meat and Potatoes

Indeed, it is hard to argue the need for better handling of non-standard web fonts.  My personal philosophy around non-standard web fonts has always been holistic in nature – sIFR is good, but it still doesn’t solve the problem fully and neither does Cufon for that matter – so I often err on the side of creative use of standard web fonts. TypeKit is definitely a progressive effort to solve the problem of non-standard fonts in the browser.

Maybe I’ve been abused by bad technology hacks in the past, but I think the real issue goes deeper than our siloed world of web browsers and markup.  Which brings me to a conclusion of why we have been trying to implement non-standard web fonts in the first place: designers want finite control.  And this is the very reason why there is such a difference in standards between OS’s standard fonts and more importantly how they are rendered – Apple typically sides with the font designer and Microsoft does not.

The difference originates from Apple’s legacy in desktop publishing and graphic design. The nice thing about the Apple algorithm is that you can lay out a page of text for print, and on screen, you get a nice approximation of the finished product. This is especially significant when you consider how dark a block of text looks. Microsoft’s mechanism of hammering fonts into pixels means that they don’t really mind using thinner lines to eliminate blurry edges, even though this makes the entire paragraph lighter than it would be in print.

The advantage of Microsoft’s method is that it works better for on-screen reading. Microsoft pragmatically decided that the design of the typeface is not so holy, and that sharp on-screen text that’s comfortable to read is more important than the typeface designer’s idea of how light or dark an entire block of text should feel. Indeed Microsoft actually designed font faces for on-screen reading, like Georgia and Verdana, around the pixel boundaries; these are beautiful on screen but don’t have much character in print.

Joel Spolsky – Font smoothing, anti-aliasing, and sub-pixel rendering

Rather than standardizing on one solution for the masses, OS manufactures, browser developers, the W3C, and [you name it standards body here] keep giving us lame excuses instead of real options. And until then we are left with 80% complete excuses for using non-standard web fonts – sIFR, Cufon, and I’m sure TypeKit will not be the last.

Nov 3 2009

A Simple Modal – Redux


Over a year ago I walked through an example of creating the basic foundation for a modal window using jQuery.  The goal was simplicity, minimalism, and flexibility to add-on functionality as needed.

As stated at the outset, this post was meant to illustrate a bare bones and simple example of a modal window. If you wanted to extend the functionality for example, it would be quite simple to [...] suit needs.

Last Year’s A Simple Modal Post

The example was well received in feedback from readers, and there was some constructive criticism as well. Equal to the amount of people that appreciated the minimalistic approach were requests from readers to support IE6, forms, and a host of other odds and ends.  Some readers had some useful feedback for features and additions that I purposefully did not include in an effort to keep things basic.

Therefore, I thought there was a nice opportunity to revisit the basic modal window script and make it a bit more comprehensive in an effort to suit the needs and requests of the aforementioned readers.  So before we get into the code, lets outline some things that have changed:

  • Converted for use as a jQuery plugin.
  • Added IE6 compatibility
  • Added Opera compatibility
  • Added ability to fade in and out
  • Added multiple ways of setting parameters
  • Added multiple content types (‘image’ and ‘iframe’)

View Example | Download Source

The Plugin

(function ($) {

	* Ex:
	* var _settings = {
	* 	id: 'modal',
	* 	src: function(sender){
	*		return jQuery(sender).attr('href');
	*	},
	* 	width: 800,
	* 	height: 600
	* }
	var _settings = {
		width: 800, // Use this value if not set in CSS or HTML
		height: 600, // Use this value if not set in CSS or HTML
		overlayOpacity: .85, // Use this value if not set in CSS or HTML
		id: 'modal',
		src: function (sender) {
			return jQuery(sender).attr('href');
		fadeInSpeed: 0,
		fadeOutSpeed: 0

	$.modal = function (options) {
		return _modal(this, options);
	$ = function () {;
	$.modal.close = function () {
	$.fn.modal = function (options) {
		return _modal(this, options);
	_modal = function (sender, params) {
		this.options = {
			parent: null,
			overlayOpacity: null,
			id: null,
			content: null,
			width: null,
			height: null,
			modalClassName: null,
			imageClassName: null,
			closeClassName: null,
			overlayClassName: null,
			src: null
		this.options = $.extend({}, options, _defaults);
		this.options = $.extend({}, options, _settings);
		this.options = $.extend({}, options, params);
		this.close = function () {
			jQuery('.' + options.modalClassName + ', .' + options.overlayClassName).fadeOut(_settings.fadeOutSpeed, function () { jQuery(this).unbind().remove(); });
		} = function () {
			if (typeof options.src == 'function') {
				options.src = options.src(sender)
			} else {
				options.src = options.src || _defaults.src(sender);

			var fileExt = /^.+\.((jpg)|(gif)|(jpeg)|(png)|(jpg))$/i;
			var contentHTML = '';
			if (fileExt.test(options.src)) {
				contentHTML = '<div class="' + options.imageClassName + '"><img src="' + options.src + '"/></div>';

			} else {
				contentHTML = '<iframe width="' + options.width + '" height="' + options.height + '" frameborder="0" scrolling="no" allowtransparency="true" src="' + options.src + '"></iframe>';
			options.content = options.content || contentHTML;

			if (jQuery('.' + options.modalClassName).length && jQuery('.' + options.overlayClassName).length) {
				jQuery('.' + options.modalClassName).html(options.content);
			} else {
				$overlay = jQuery((_isIE6()) ? '<iframe src="BLOCKED SCRIPT\'<html></html>\';" scrolling="no" frameborder="0" class="' + options.overlayClassName + '"></iframe><div class="' + options.overlayClassName + '"></div>' : '<div class="' + options.overlayClassName + '"></div>');

				$modal = jQuery('<div id="' + + '" class="' + options.modalClassName + '" style="width:' + options.width + 'px; height:' + options.height + 'px; margin-top:-' + (options.height / 2) + 'px; margin-left:-' + (options.width / 2) + 'px;">' + options.content + '</div>');

				$close = jQuery('<a class="' + options.closeClassName + '"></a>');

				var overlayOpacity = _getOpacity($overlay.not('iframe')) || options.overlayOpacity;
				$overlay.fadeTo(0, 0).show().not('iframe').fadeTo(_settings.fadeInSpeed, overlayOpacity);

				$ () { jQuery.modal().close(); });
				$ () { jQuery.modal().close(); });
		return this;
	_isIE6 = function () {
		if (document.all && document.getElementById) {
			if (document.compatMode && !window.XMLHttpRequest) {
				return true;
		return false;
	_getOpacity = function (sender) {
		$sender = jQuery(sender);
		opacity = $sender.css('opacity');
		filter = $sender.css('filter');

		if (filter.indexOf("opacity=") >= 0) {
			return parseFloat(filter.match(/opacity=([^)]*)/)[1]) / 100;
		else if (opacity != '') {
			return opacity;
		return '';
	_defaults = {
		parent: 'body',
		overlayOpacity: 85,
		id: 'modal',
		content: null,
		width: 800,
		height: 600,
		modalClassName: 'modal-window',
		imageClassName: 'modal-image',
		closeClassName: 'close-window',
		overlayClassName: 'modal-overlay',
		src: function (sender) {
			return jQuery(sender).attr('href');

As you can see, quite a bit has changed – which is not necessarily a bad thing.  There is now tighter integration with jQuery and more out of the box configuration ability as a result.

Adding Some Style

.modal-overlay {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	height: 100%;
	width: 100%;
	margin: 0;
	padding: 0;
	background: #131313;
	opacity: .85;
	filter: alpha(opacity=85);
	z-index: 101;
.modal-window {
	position: fixed;
	top: 50%;
	left: 50%;
	margin: 0;
	padding: 0;
	z-index: 102;
	background: #fff;
	border: solid 8px #000;
	-moz-border-radius: 8px;
	-webkit-border-radius: 8px;
.close-window {
	position: absolute;
	width: 47px;
	height: 47px;
	right: -23px;
	top: -23px;
	background: transparent url(../images/close-button.png) no-repeat scroll right top;
	text-indent: -99999px;
	overflow: hidden;
	cursor: pointer;


<a href="modal.html" onclick="$(this).modal({width:833, height:453}).open(); return false;">Modal iFrame</a>
<a href="images/your-image.jpg" onclick="$(this).modal({width:500, height:375}).open(); return false;">Modal Image</a>

Although a little more weight has been added to the script itself, the implementation is more flexible and can be used with just about any jQuery chain – whether its onclick, a document being loaded, you name it.  There is also an added ability to set parameters in your area of choosing – inside the CSS, in the plugin itself, or in the method call or jQuery chain object.

Moving Forward

So if you are looking for something extra simple, head on over to last years post and in the meantime enjoy the added functionality with this updated example.

View Example | Download Source

Oct 21 2009

IIS 7, SEO, and You: Part 1 – URL Rewriting


If you currently do not take a technical interest in Search Engine Optimization (SEO) as a developer, you should.  As opposed to Search Engine Marketing (SEM), an effective SEO plan can often only be implemented by a developer becuase of it’s technical nature.  One such optimization is url rewriting.  A few minutes spent searching on Goolgle will uncover what has been going for years in the Apache world with mod_rewrite and .haccess.  The great thing about mod_rewrite is that you have full control over url structure, and essentially the way search bots crawl through your site.  Many have termed .htaccess/mod_rewrite as “the Swiss Army Knife of SEO.”

Some basic rules that most optimiztion plans include is redirecting to a canonical domain, adding a trailing slash, and removing file extensions. Since II7 natively supports url rewriting now, achieving is very straightforward. There are number of methods to do this, but one way is adding some rules to your Web.config file.

Sample rules for cannonical domain redirect, trailing slash, and file extension:

		<rule name="Redirect To Cannonical Domain" stopProcessing="true">
			<match url="^(.*)$" />
				<add input="{HTTP_HOST}" pattern="!^example\.com" />
			<action type="Redirect" url="$1" redirectType="Permanent" />
		<rule name="Remove Index Pages" enabled="true" stopProcessing="true">
			<match url="(.*)(index|default)\.(asp|aspx|html|htm)$" />
			<action type="Redirect" url="{R:1}" appendQueryString="true" />
		<rule name="Add Trailing Slashes" enabled="true" stopProcessing="true">
			<match url="^([^.?]+[^.?/])$" />
			<action type="Redirect" url="/{R:1}/" redirectType="Permanent" />
		<rule name="Remove File Ext Reverse" enabled="true" stopProcessing="true">
			<match url="^(.+)\.aspx$" />
				<add input="{REQUEST_METHOD}" negate="true" pattern="^POST$" />
			<action type="Redirect" url="/{R:1}/" appendQueryString="true" redirectType="Permanent" />
		<rule name="Remove File Ext" stopProcessing="true">
			<match url="^(.+)/$" />
				<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
				<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
			<action type="Rewrite" url="/{R:1}.aspx" appendQueryString="true" />

Avoiding duplicate content (http://www vs http:// or /pathtofile/ or /pathtofile), reducing Search Engine Ranking Page (SERP) ranking drops with a relaunch or update, and over solid URL structure are just some of the benefits of a good URL rewriting scheme.  Now that IIS 7 has a URL Rewrite as built in component, web applications built on .NET can be ever more powerful.  In the next part of the series, we will look at the new beta of the Search Engine Toolkit for IIS 7.

Jun 10 2009

Windows 7 RC x64 Boot Camp Install on a MacBook Pro


So I jumped on the bandwagon Friday night and installed the recently released RC (build 7100) of Windows 7 from MSDN.  Having missed the initial rush, I was hitting download speeds of around 1.5 mb/s on my 15 mb down FIOS connection.  After I had the ISO, I figured I would avoid the nightmere of deleting and repartitioning Boot Camp and try a boot right from my newly burned Windows 7 DVD and reformat from the installer.  In hindsight, it seems that Mac OS X does not recognize that there is a Windows volume as a startup disk now – only Mac OS is dispalyed in Sysytem Preferences > Startup Disk.

Based on my previous experiences with Vista x64 installs on my MacBook Pro, I went to a very useful post I had bookmarked on getting the ISO to be bootable (after some digging, this other post outlines basically the same thing).  And sure enough, it was even updated for Windows 7.  If you do this right off the bat, you won’t see the “Select CD-ROM boot type” with no way to make a selection.

I reformatted my NTFS drive for a clean install of Windows 7, and the install proceeded without a hangup [insert your look of surprise here].  I followed that up with an install of the regular Boot Camp drivers from Apple on my OS X CD (version 2.01) – you can also download them via a torrent – and then the Boot Camp x64 update from Apple (2.1).

After installing Boot Camp, what happened next completely blew my mind – EVERYTHING WORKED.  This was a great releif, since after every Vista x64 install I found my WiFi non-functional (had to download my own Atheros drivers) and the ATi graphics driver was sketchy (fixed with modtool).   In my opinion, Microsoft did a great job of playing nice with Apple drivers this time around – they even show a nice message in the event that a driver is unsupported as opposed to the blue screen common with Vista.

As far as first impressions, Windows 7 has simply just worked for me.  From the minimal amount of processes running to all of my hardware and software working without a hitch, Windows 7 is definately a pleasant surprise in the wake of Vista.

So, have you installed Windows 7 with Boot Camp?  If so, please share your experiences (good and bad).


Update: Some people seem to be having issues with drivers.  These are the two Boot Camp drivers that I always use – without issue:

Install First: Download and install BootCamp 2.01 (x64)
Install Second:  Download and install BootCamp 2.1 Update

May 5 2009

InsideRIA Blog Post: Silverlight Development for the Flex Developer


I have recently had the privilege to contribute as a guest blogger to In my first post, I chose to expose various interesting aspects of Silverlight to the Flex and Flash community. Even though Silverlight does not have a penetration rate that competes with Flash, Silverlight has features and advantages that make it worthwhile for an RIA developer to know about. When looking at technologies to leverage for your next project, you may not want to leave Silverilght out of the mix. Decide for yourself.

Mar 25 2009

« Older Entries