15

Consider that I have this CSS rule for an anchor tag:

font-family: Helvetica, Verdana, Calibri, Arial, sans-serif;

Of course by watching at what is rendered in the browser, I can judge which of these fonts has already been used (applied) to format the current anchor element's text.

However, I need to know which font is currently in use via JavaScript (jQuery for example). This jQuery code doesn't help me:

$('#anchor-id').css('font-family');

because it returns 'Helvetica, Verdana, Calibri, Arial, sans-serif;'. Is there a way to know which font is in action now?

Update: Based on @MC answer, I created this fiddle and you can check that it's working just nice and quite.

Saeed Neamati
  • 35,341
  • 41
  • 136
  • 188
  • Why do you need to know? – thirtydot Sep 05 '11 at 09:18
  • 5
    See this question: http://stackoverflow.com/questions/1960817/get-computed-font-family-in-javascript (to sum it up, you can't do it easily, but there is a technique you could try) – James Allardice Sep 05 '11 at 09:21
  • 2
    @thirtydot, I just need to know. :). I want to do some business based on the applied font. (statistical analysis). To be more specific, I have an script on my page, which just like Google Analytics, sends back an ajax request, which contains information about the current applied font to the server. – Saeed Neamati Sep 05 '11 at 09:22
  • Well, that sounds like a good reason. I asked only because there are some silly reasons for which one could want to do this difficult task. – thirtydot Sep 05 '11 at 09:29
  • I'm curious as to why you think Verdana and Calibri are better fallbacks for Helvetica than Arial (which is nearly identical and considered [web-safe](http://en.wikipedia.org/wiki/Web-safe_fonts)). – sethobrien Sep 05 '11 at 09:33
  • 1
    @sethbrien, I'm not a designer :D. I just wrote a sample here. I didn't know that and to tell you the truth, I can't say the difference between blue and red ;). – Saeed Neamati Sep 05 '11 at 09:37
  • 2
    @seth Because Arial is the illegitimate bastard from hell! ;o) – deceze Sep 05 '11 at 09:37

1 Answers1

8

First, you need to test if a font has been installed. I have used some scripts on the internet which will test if a font is installed or not.

Include this snippet of code somewere (thanks to Lucas Smith):

var Font = {

    isInstalled : function (name) {
        name = name.replace(/['"<>]/g,'');

        var body = document.body;
        var test = document.createElement('div');
        var installed = false;
        var teststring = "mmmmmmmmwwwwwwww";
        var template = '<b style="display:inline !important; width:auto !important; font:normal 10px/1 \'X\',sans-serif !important">' + teststring + '</b><b style="display:inline !important; width:auto !important; font:normal 10px/1 \'X\',monospace !important">' + teststring + '</b>';
        var ab;

        if (name) {
            test.innerHTML = template.replace(/X/g, name);
            test.style.cssText = 'position: absolute; visibility: hidden; display: block !important';
            body.insertBefore(test, body.firstChild);
            ab = test.getElementsByTagName('b');
            installed = ab[0].offsetWidth === ab[1].offsetWidth;
            body.removeChild(test);
        }
        return installed;
    }
}

In addition, use the following snippet (I wrote that myself) to get the font-family value and split that value into parts. Each part is a font, as they are separated by a comma in the CSS code (e.g. font-family: "Nimbus", "Courier New";):

function workingFont(element) {
    var fontString = $(element).css('font-family');
    var fonts = fontString.split(",");
    for (var f in fonts) {
        if (Font.isInstalled(fonts[f])) {
            return fonts[f];
        }
    }
}

As you can see, the first installed font will be returned.

Use workingFont(element), where element is the element id, class or tagname. This is part of the jQuery API. Notice you must have jQuery included to get the aforementioned script working.

Update: I created this jsfiddle to test it.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • +1 for a great idea, but I wouldn't trust this script in a serious application. There is way to much chance of 'ii' string being same width in two different fonts. Choose longer strings, consisting of many different letters. – Rok Kralj Sep 06 '11 at 10:15
  • That's right. I read another script where 'mmmmmmwwwwwwwwww' was the test string. I guess that, with that test string, it's very unlikely that the font widths are exactly the same, isn't it? – MC Emperor Sep 06 '11 at 10:17
  • I would prefer a string where higher number of different letters would appear. Let's say you have a font which differs only in one letter from another. Extreme case, for demonstration. – Rok Kralj Sep 06 '11 at 10:19
  • 2
    What about the whole alphabet, with some characters doubled or something? – MC Emperor Sep 06 '11 at 10:22
  • @RokKralj Not just two fonts having the same width, but browsers will use fallback fonts for certain font families, eg. my Linux laptop doesn't have either Arial or Verdana installed, but Firefox will render a different font for both of them (and different to sans-serif). – robertc Sep 06 '11 at 12:45