JavaScript check if a font is available

Small JavaScript function to test if a font is available on a web page.

How it works

First the widths of the generic fonts monospace, serif and sans-serif are computed for the letters wi repeated 99 times. w because it’s wide and i because it should differ between monospace and proportional fonts.

Then to check a font is available the font-family is set to the font with a generic font as the fallback. The width of the font-family is the compared to the width of the fallback. If the widths differ then fallback wasn’t used and the font is available otherwise another fallback is tried.

As long as one of the fallback fonts has a different width from the others this will be 100% accurate¹. In the unlikely event all fallbacks have the same width this will still be accurate for fonts with a different width to the fallbacks.

¹This function will detect substituted fonts as being available. By default Windows substitutes the fonts Helv, Helvetica, Times and Tms Rmn. With Linux the substitutes vary between distributions. If you need to know a font is available and not substituted then you can use @font-face to load it.

Source:

/**
 * Checks if a font is available to be used on a web page.
 *
 * @param {String} fontName The name of the font to check
 * @return {Boolean}
 * @license MIT
 * @copyright Sam Clarke 2013
 * @author Sam Clarke <sam@samclarke.com>
 */
(function (document) {
  var width;
  var body = document.body;

  var container = document.createElement('span');
  container.innerHTML = Array(100).join('wi');
  container.style.cssText = [
    'position:absolute',
    'width:auto',
    'font-size:128px',
    'left:-99999px'
  ].join(' !important;');

  var getWidth = function (fontFamily) {
    container.style.fontFamily = fontFamily;

    body.appendChild(container);
    width = container.clientWidth;
    body.removeChild(container);

    return width;
  };

  // Pre compute the widths of monospace, serif & sans-serif
  // to improve performance.
  var monoWidth  = getWidth('monospace');
  var serifWidth = getWidth('serif');
  var sansWidth  = getWidth('sans-serif');

  window.isFontAvailable = function (font) {
    return monoWidth !== getWidth(font + ',monospace') ||
      sansWidth !== getWidth(font + ',sans-serif') ||
      serifWidth !== getWidth(font + ',serif');
  };
})(document);

Tested with:
Desktop: IE 5+, FF 1+, Chrome, Safari, Opera, Epiphany
Mobile: Opera Mobile, Android, FF

Minified version:

(function(d){function c(c){b.style.fontFamily=c;e.appendChild(b);f=b.clientWidth;e.removeChild(b);return f}var f,e=d.body,b=d.createElement("span");b.innerHTML=Array(100).join("wi");b.style.cssText=["position:absolute","width:auto","font-size:128px","left:-99999px"].join(" !important;");var g=c("monospace"),h=c("serif"),k=c("sans-serif");window.isFontAvailable=function(b){return g!==c(b+",monospace")||k!==c(b+",sans-serif")||h!==c(b+",serif")}})(document);

Only 461 characters.

Usage

var isInstalled = isFontAvailable('Arial Black'));

if (isFontAvailable('Arial')) {
    alert('Arial is available');
} else {
    alert('Arial is not available');
}

Demo

Comments