1

I need to sniff the formatting for a <p> so I can pass the info to an <iframe> and match formats.

I can get the font face using jQuery

var font = $("p").css('font-family');
var fsiz = $("p").css('font-size');

However if the font-family is a web font - eg "Open Sans" I also need to find the src for the @font-face rule that loaded it.

I have no idea how to do that.

John Pettitt
  • 659
  • 6
  • 11

3 Answers3

4

Find all css-defined fonts, demo here (console).

function getFonts (obj) {
    var o = obj || {},
        sheet = document.styleSheets,
        rule = null,
        i = sheet.length, j;
    while( 0 <= --i ){
        rule = sheet[i].rules || sheet[i].cssRules || [];
        j = rule.length;
        while( 0 <= --j ){
            if( rule[j].constructor.name === 'CSSFontFaceRule' ){ // rule[j].slice(0, 10).toLowerCase() === '@font-face'
                o[ rule[j].style.fontFamily ] = rule[j].style.src;
            };
        }
    }
    return o;
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • [According to @Roemer](http://stackoverflow.com/review/suggested-edits/5725165), this does not work in FF – KyleMit Sep 08 '14 at 20:21
  • @KyleMit , In _FireFox_, you can find font rules with `rule[j] instanceof CSSFontFaceRule`, but then extracting the actual data from it doesn't seem neat, looks like you have to parse it out of the rule text – Paul S. Sep 08 '14 at 20:54
  • This fiddle outputs: {foo: "url("bar.otf")"} for me. – Jay May 04 '18 at 15:18
1

I adapted the chosen solution to work as well in IE and FF, also Safari on iOs. The chosen solution only worked in Chrome. (Alas I cannot - yet - add comments to that solution, that's why I put it in a seperate solution.)

function getFonts (obj) {
    var o = obj || {},
        sheets = document.styleSheets,
        rules = null,
        i = sheets.length, j;
    while( 0 <= --i ){
        rules =  sheets[i].cssRules || sheets[i].rules || []; // I swapped those two, IE would go wrong
        j = rules.length;
        while( 0 <= --j ){
            if( rules[j].toString() == "[object CSSFontFaceRule]" ){  // This works in IE and FF too
                o[ rules[j].style.fontFamily ] = rules[j].style.src;
            };
        }
    }
    return o;
}
Roemer
  • 1,124
  • 8
  • 23
  • There is an error in your code. You are making use of undeclared variable 'rule'. – Jay May 04 '18 at 15:20
  • I fixed it, but Chrome the latest Chrome throws a DOM exception. You can't access these rules anymore, it seems. Oh well. – Jay May 04 '18 at 15:27
  • Thanks, i fixed the rules/rule error. the DOM exception is over my head and no time to do research at the moment. – Roemer May 04 '18 at 21:58
  • Chrome simply won't let you access these properties anymore. Nothing you can do about it. – Jay May 06 '18 at 00:47
  • That's a bummer. Thanks for noting; I had to adapt some important code for my company because of this. – Roemer May 17 '18 at 00:06
  • 2
    If anyone finds a solution/workaround -- I would love to hear it. – Roemer May 17 '18 at 00:07
0

As a small improvement on Paul S's answer, I've included nested objects with the font weight and style as keys, to retrieve all versions of a font.

function getFonts (obj) {
    var o = obj || {},
        sheet = document.styleSheets,
        rule = null,
        i = sheet.length, j;
    while( 0 <= --i ){
        rule = sheet[i].rules || sheet[i].cssRules || [];
        j = rule.length;
        while( 0 <= --j ){
            if( rule[j].constructor.name === 'CSSFontFaceRule' ){
                if (!(rule[j].style.fontFamily in o)) o[ rule[j].style.fontFamily ] = Object.create(null);
                o[ rule[j].style.fontFamily ][ rule[j].style.fontWeight + '-' + rule[j].style.fontStyle ] = rule[j].style.src;
            };
        }
    }
    return o;
}
Tom
  • 6,947
  • 7
  • 46
  • 76