optimalisatie
optimalisatie

Reputation: 371

How to detect if CSS @font-face is NOT used on a page?

For the purpose of Javascript based automated unused CSS removal we are looking for a solution to detect if a @font-face block is used on a page.

Is there an easy way to verify if a font is in use in the HTML?

The method getComputedStyle() would require to test each individual HTML element and would not be efficient.

<style>@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),
       url("/fonts/OpenSans-Regular-webfont.woff") format("woff");
}</style>
<html> ... </html>
<script>function test_if_open_sans_is_used() { return; }</script>

Upvotes: 3

Views: 2028

Answers (3)

Dylan Maxey
Dylan Maxey

Reputation: 1116

This will help determine all fonts used on a given webpage. You can then use this to determine if your target font has been used.

const fontUnstack = (stack, size, style, weight) => {
    if (typeof stack === "string")
        stack = stack.match(/[^'",;\s][^'",;]*/g) || [];

    for (const family of stack) {
        if (document.fonts.check(style + ' ' + weight + ' ' + size + ' ' + family))
            return family;
    }
    console.log('undetected font', fontStyle, fontWeight, fontSize, fontFamily, el);
    return null;
};

const els = document.querySelectorAll('*');
let fonts = {};

for (const el of els) {
    const computedStyles = [
        window.getComputedStyle(el),
        window.getComputedStyle(el, '::before'),
        window.getComputedStyle(el, '::after')
    ];
    for (const computedStyle of computedStyles) {
        const fontFamily = computedStyle.getPropertyValue('font-family'),
              fontSize = computedStyle.getPropertyValue('font-size'),
              fontStyle = computedStyle.getPropertyValue('font-style'),
              fontWeight = computedStyle.getPropertyValue('font-weight'),
              usedFontFamily = fontUnstack(fontFamily, fontSize, fontStyle, fontWeight);

        if (usedFontFamily && !fonts.hasOwnProperty(usedFontFamily))
            fonts[usedFontFamily] = [];
        if (fonts[usedFontFamily].indexOf(fontStyle + ', ' + fontWeight) === -1)
            fonts[usedFontFamily].push(fontStyle + ', ' + fontWeight);
    }
}

console.log(fonts);

Upvotes: 3

There is no API you can use or CSS selector for computed styles. (Old example with jQuery) The only options you have is to iterate over the entire DOM, or simply use the Chrome css coverage

If you want to automate your solution you can always extend Chrome Dev tools

Upvotes: 1

optimalisatie
optimalisatie

Reputation: 371

document.fonts.check API can be used to detect font-usage. It depends on a font-string style weight size font-family.

To match Open-Sans-Italic:

document.fonts.check('italic 14px "Open Sans"');

Upvotes: 3

Related Questions