Monthly Archives: November 2010

Waqas asks the CSS Guy how to specify an alternate font size if the preferred font isn’t available on the user’s system

Waqas writes:

Is there any way to specify alternate font size?

e.g.

p { font: 11px Tahoma, Helvetica; }

If Tahoma font is not available in machine, Helvetica will be used (if available) with size 11px. Is there any workaround that if Tahoma is available it will use size 11px & if it is not available Helvetica will use for example 13px?

Yes – here’s a way. I had found this article from 2007: JavaScript/CSS Font Detector, so let’s use that as a starting point.

I’ll start with HTML for a simple paragraph:

<p>Row, row, row your boat<br />
Gently down the stream.<br />
Merrily, merrily, merrily, merrily<br />
Life is butter dreams.</p>

And style it:

<style type="text/css">
p { font: normal 28px/1.2 'Brush Script Std',Arial,sans-serif; }
</style>

And so I have two fonts: Brush Script Std as my preferred font, and Arial as my fallback. The challenge is that supposing Brush Script Std isn’t on the user’s system, I want Arial to display not at 28px, but at 18px.

I’d approach is like this. First set a style rule for the fallback state. If we know that ‘Brush Script Std’ is available, let’s use JavaScript to add a class to the body tag that indicates the font is good to use, like <body class="hasBrushScriptStd">. I could then write a separate style rule that makes use of that selector, like so:

<style type="text/css">
p { font: normal 18px/1.2 Arial,sans-serif; }
.hasBrushScriptStd p { font: normal 28px/1.2 'Brush Script Std'; } 
</style>

Now for the script that handles the font detection and adding of the class name to the body. I verified that Waqas isn’t using jQuery, so I’m writing a couple of extra functions to handle the onload event and the adding of class names. (credits at the end of the article).

<script type="text/javascript" src="fontdetect.js"></script>
<script type="text/javascript">
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}
function addClass(element,value) {
  if (!element.className) {
    element.className = value;
  } else {
    newClassName = element.className;
    newClassName+= " ";
    newClassName+= value;
    element.className = newClassName;
  }
}
addLoadEvent(function() {
  var detective = new Detector();
  var hasBrushScriptStd = detective.test('Brush Script Std');
  if (hasBrushScriptStd == true) { 
    addClass(document.getElementsByTagName('body')[0],'hasBrushScriptStd');
  }
});
</script>

Here’s the final result where you can view source and copy if you wish. Know of other methods, better methods, or gotchas? Tell me about it.

Script credits: