JavaScript code to detect available availability of a particular font in a browser using JavaScript and CSS.
Update: I have updated the algo of the script and it is almost 100% accurate.
This JavaScript class can be used to guess if a particular font is present in a machine. This may be help of desktop-like web application developers when they want to provide different skins or fonts preferences to their users. This may also be help for blog skin designers which can provide different fonts for different users based on the list of fonts on their machine. Designers don’t have to rely on the most common fonts like Arial, Verdana or Times New Roman. Since increasing number of users
have modern PC with new operating system / applications, they may very well have a wide array of other common fonts in their machine.
How does it work?
This code works on the simple principle that each character appears differently in different fonts. So different fonts will take different width and height for the same string of characters of same font-size.
We try to create a string with 3 generic font-face, monospace, sans-serif and sans and note their width. Then try to create the same string in HTML using the font to be tested and the generic fallback font. If the font-face is not available, it takes up the generic fallback font-face. We then compare the width of the string with the new font and width of the string with the fallback generic font-face, if they are different, then the font exists, otherwise not.
<span style="font-family: monospace; font-size: 72px">mmmmmmmmmmlli</span> vs. <span style="font-family: New-Font, monospace; font-size: 72px">mmmmmmmmmmlli</span>
Since this test is repeated three times against 3 font families, it gives almost 100% accurate results. The string which we will use to generate the widths can be anything. But I guess we use ‘m’ or ‘w’ because these two characters take up the maximum width. And we use a trailing ‘l’ and ‘i’ so that the same width fonts-faces can get separated based on the width of l character. I have tested it on Firefox, IE, Opera, Safari, Chrome
Note:
It required to execute the script after its completely loaded for some browsers like Opera. (Opera cannot calculate the offsetWidth until all the parents are completely loaded)
Download ver 0.3 (24 Mar 2012)
Released under Apache Software License 2.0.
Demo
You can test any Font here:
// Usage window.onload = function() { var detective = new Detector(); alert(detective.detect('font name')); };
Fonts on your computer
This table below shows which fonts are present on your system. (I have listed some of the most common and some uncommon fonts.)
| Font Name | Detected? |
|---|

This approach is quite innovative!
Cool! Great idea compare font sizes. But I had problems with Firefox:
When Firefox don’t find the font, not always shows ‘sans-serif’ type. Changing next line solves it:
f[0] = s.style.fontFamily = font;
to
f[0] = s.style.fontFamily = font + “, sans-serif”;
Anyway, good work.
Wow! This is a gerat Solution. Thank you very much.
OS X 10.5 using FF 3.5.7 and all testing works fine (including Calibri).
Great temp fix until CSS3 is in play–tx.
May I suggest adding single quotes around the font name when setting for the test font. Firefox 3.6.3 at least is omitting the “font-family: ” part if there are spaces in the name for at least the “Free 3 of 9 Extended” from http://www.barcodesinc.com/free-barcode-font/ and may be playing a part in some of the other issues too. Plus it still detects just fine (on Firefox 3.6.3 & IE 8) with the extra single quotes.
f[0] = s.style.fontFamily = font; // Name of the font
changes to
f[0] = s.style.fontFamily = “‘” + font + “‘”; // Name of the font
I think this font detector is great for installed fonts but doesn’t seem to do it for fonts downloaded by @font-face, does it? This applies to folks who have disabled font downloading in IE security options.
Thanks for the great post.
[edit] Oh snap! I was testing incorrectly. YES, this font detector detects even when a font is downloaded to the client browser using the @font-face css rule and effectively provides a work-around for Internet Explorer users whose security settings disable font downloads. THANK YOU
Thanks, great script !!!
It might be usefull some time
I delight in, lead to I found just what I was having a look for. You have ended my four day lengthy hunt! God Bless you man. Have a great day. Bye
The idea doing it this way is nice, but not really reliable enough if you need a near 100% solution. Different rendering of browsers and of course different font smoothing and subpixeling methods will add an – from javascript perspective – blackbox.
Sure, if you render the font large, these “jitter” will be smaller in relation to the font itself but it is not zero. Also important to know is, that there might exist customized corporate fonts which mostly have identical metrics to the source font but may be different in certain details. It is impossible to surely detect those fonts by simply measuring a string containing only 3 different faces of it.
Sure, in most cases this doesn’t happen and asking the question why would someone choose to use those fonts on a webpage may be understandable. But it might happen for some reason – e.g. in a near-wysiwyg-scenario for customizing print products without plugin technology or if some intranet stuff uses fonts to implement the corporate design without relying on cufon or sifr for some reason.
You can reduce the gap and increase accuracy for firefox or opera etc for example, if you query the computed style for these browsers. If you set a particular font and it does not exist, normal behaviour means to use a default font. Unfortunately getting the computed style in IE won’t be possible yet as far as i know (you might try to play with element.currentStyle in IE – i didn’t do this until now).
Anyhow your solution delivers surprisingly exact results with a view on it’s simplicity and therefore it might for most cases a good and specially easy to implement and small footprint compromise to perform font detection.
Alex,
Thanks for the feedback.
I am also working on a solution which will be 100% sure in matching the font names. I will post it soon on my blog.
Alex,
I have uploaded a new version of my script. This should be almost 100% fool proof solution. Let me know your thoughts.
Hi Lalit,
sounds interesting. I am curious to see and test the updated version as soons as it is available.
Best regards,
Axel
Worked great.
Thank you very much.
You have the three default fonts as monospace, sans-serif, and sans. As in:
var baseFonts = ['monospace','sans-serif','sans'];
But I think you should change the last one to “serif” instead of “sans”. Like this:
var baseFonts = [‘monospace’,’sans-serif’,‘serif’];
I have updated the script adding `serif` instead of `sans`.
Thanks for reporting!
Thanks for sharing your work. Finally a way using JS only to detect system fonts. I still wish you could get all system fonts without specifying a font-family to detect all fonts installed as you can do with Flash and Java.
Hi,
Will this script work even on Android. Because When I ran it on android, it gave me true for all the fonts and I do not have some of those fonts in android at all.
Any idea?
Seems to be a discrepancy between Firefox Mac and -webkit Mac browsers…
Your on-page demo hero in Safari correctly detects Courier New. Firefox reports it as not avialable (“false”).
To this same effect, testing for “HelveticaNeue-Light” in a -webkit browser reports “true” when it is present, but the same font-name reports false in Firefox – on the same computer.
“Helvetica Neue” however is found “true” on Firefox, however.
The webpage even renders ‘HelveticaNeue-Light’ in Firefox correctly, but only when set using an @font-face src: local(‘HelveticaNeue-Light’); rule.
How is your script handling font names with dashes/spaces? How about when the font is only available through the src: local() syntax? And why would Safari be able to find the Helvetica Neue’s font face, “Light” when Firefox can’t?
Would love to get to the bottom of this. Thanks for your script!
Good point. I will post a fix to it soon.
Still wondering about Firefox vs. Chrome and why one picks up fonts like “Helvetica Neue Light” and the other doesn’t, when the font is installed and the browsers are on the same system (Mac). Please see my earlier comment (in moderation) for more details. Thanks.
Brilliant. Absolutely brilliant.
Damn this script is brilliant. I used it to solve a problem regarding trying to load a webfont that was going to be used in markup. Because browser load web fonts asyncronously, the javascript that drew the canvas would run before the web font was finished loading, therefore causing the browser to use either a fallback font in Firefox or not show any font at all in Chrome. Using this font detector, I was able to programatically choose which font to use in the Canvas, depending on if the web font was finished downloading. If the user’s browser hadn’t downloaded the webfont yet, their canvas would use a default fallback font. But the next time they loaded the page, it would use the proper font since it was cached in their browser by then. Seriously, really slick script…
I have a slightly different problem. I am using unusual Unicode characters, and I want to know if the user has a font loaded that can display them at all – I don’t care which font.
I guess I could adapt your idea by comparing some text with my unusual characters against the browser’s missing-character icon, which I could generate by referring to an unmapped codepoint.