9

Is it possible to retrieve the assigned font of an element in jQuery?

Let's say there is css:

#element
{
font-family: blahblah,Arial;
}

In the above example, Arial font will be assigned to #element. Is there a way to get that information via JS/JQuery?

Something like:

$('#element').css('font-family');

returns just blahblah,Arial;

Trott
  • 66,479
  • 23
  • 173
  • 212
el vis
  • 1,302
  • 2
  • 16
  • 32
  • 3
    You can't, but there are clever workaround. Please see: http://stackoverflow.com/a/1961519/1064286 – Piet van Dongen Mar 27 '13 at 16:58
  • @donderpiet thats interesting workaround, but doesn't solve my problem. For example when I want to check to which font browser fallbacks when there is not suitable font. – el vis Mar 27 '13 at 17:08

4 Answers4

11
(function($) {
    $.fn.detectFont = function() {
        var fonts = $(this).css('font-family').split(",");
        if ( fonts.length == 1 )
            return fonts[0];

        var element = $(this);
        var detectedFont = null;
        fonts.forEach( function( font ) {
            var clone = element.clone().css({'visibility': 'hidden', 'font-family': font}).appendTo('body');
            if ( element.width() == clone.width() )
                detectedFont = font;
            clone.remove();
        });

       return detectedFont;
    }
})(jQuery);

edit: had to remove the cloned item from the dom.

Whipped this up just now, again, it still relies on element width - so your mileage may vary.

$('#element').detectFont(); //outputs Arial

kmfk
  • 3,821
  • 2
  • 22
  • 32
3

You can use Detector library to do it: http://www.lalit.org/lab/javascript-css-font-detect/

As the browser takes the first found font from the list, you should look through the list of fonts and try to check if you have this font in your system.

Here is JS/JQuery code:

$(function() {
    var detectFont = function(fonts) {
        var detective = new Detector(), i;
        for (i = 0; i < fonts.length; ++i) {
           if (detective.detect(fonts[i]) !== true) {
               continue
           }
           return fonts[i];
        }    
    }
    var fonts = $('#abcde').css('font-family');
    fonts = fonts.split(',');
    console.log(detectFont(fonts));
});

And here is live demo, I've prepared: http://jsfiddle.net/netme/pr7qb/1/

Hope, this approach will help you.

Mikhail Chernykh
  • 2,659
  • 22
  • 15
  • netme, yeah that's almost that, but most case i would like use this is when there will be none font from font-family assigned, but some default after fallback, like when i use `font-family:Arial` for some Japanese or Chinese. – el vis Mar 27 '13 at 17:33
  • @pawlakppp - even if the font is actually inherited from a parent element, it should still work fine. – kmfk Mar 27 '13 at 17:35
  • @netme, but in fallback case font won't be inherited from parent element, but there will be assigned font (from OS fonts) that is able to display Japanese/Chinese characters, and I need to know which one. Now i see it is probably impossible. Thanks though – el vis Mar 27 '13 at 17:39
  • @pawlakppp yes, I think, it is impossible then. – Mikhail Chernykh Mar 27 '13 at 20:42
2

Modified kmfk's answer so that it works for all elements. Block elements have fixed or dynamic width won't work so this uses inline elements:

/**
 * Detects the font of an element from the font-family css attribute by comparing the font widths on the element
 * @link http://stackoverflow.com/questions/15664759/jquery-how-to-get-assigned-font-to-element
 */
(function($) {
    $.fn.detectFont = function() {
        var fontfamily = $(this).css('font-family');
        var fonts = fontfamily.split(',');
        if ( fonts.length == 1 )
            return fonts[0];

        var element = $(this);
        var detectedFont = null;
        fonts.forEach( function( font ) {
            var clone = $('<span>wwwwwwwwwwwwwwwlllllllliiiiii</span>').css({'font-family': fontfamily, 'font-size':'70px', 'display':'inline', 'visibility':'hidden'}).appendTo('body');
            var dummy = $('<span>wwwwwwwwwwwwwwwlllllllliiiiii</span>').css({'font-family': font, 'font-size':'70px', 'display':'inline', 'visibility':'hidden'}).appendTo('body');
            //console.log(clone, dummy, fonts, font, clone.width(), dummy.width());
            if ( clone.width() == dummy.width() )
                detectedFont = font;
            clone.remove();
            dummy.remove();
        });

       return detectedFont;
    }
})(jQuery);
bucabay
  • 5,235
  • 2
  • 26
  • 37
-5
$('#element').css("font-family", "Arial");

Try this.

Hassaan
  • 328
  • 1
  • 2
  • 9
  • 1
    That will _assign_ the Arial font, not _return_ it, which is what the OP is asking to do. If he sets font to "blahblah,Arial" - he wants to know which of the two is actually being used by the browser. – Troy Alford Mar 27 '13 at 19:23
  • 1
    oops sorry ... i didn't understand question fully well. Now i am gonna try. – Hassaan Mar 27 '13 at 19:28