如何检测页面上是否未使用 CSS @font-face?

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

为了基于 Javascript 自动删除未使用的 CSS,我们正在寻找一种解决方案来检测页面上是否使用了 @font-face 块。

有没有简单的方法来验证 HTML 中是否使用了某种字体?

方法 getComputedStyle() 需要测试每个单独的 HTML 元素并且效率不高。

<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>

没有 API 您可以使用或 CSS 计算样式的选择器。 (Old example with jQuery) 您唯一的选择是遍历整个 DOM,或者简单地使用 Chrome css coverage

如果你想自动化你的解决方案,你总是可以extend Chrome Dev tools

document.fonts.checkAPI可以用来检测font-usage。这取决于font-string style weight size font-family.

匹配Open-Sans-Italic:

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

这将有助于确定给定网页上使用的所有字体。然后您可以使用它来确定您的目标字体是否已被使用。

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);