如何设置字体系列但保留回退堆栈?

How to set font family but retain fallback stack?

是否可以使用 JavaScript 轻松设置自定义本地字体,但保留一些默认 font-family 堆栈以防用户尝试设置不存在的字体?

例如,如果堆栈是font-family: Courier, monospace;,如何在不求助于操作字符串的情况下添加到堆栈的开头?

方法一:CSS自定义属性

下面的原始答案(方法 2)有一些问题,但后来我想出了一个更直接的解决方案,使用 CSS custom properties (variables)

p {
    font-family: var(--userfont), Courier, monospace;
}
document.documentElement.style.setProperty('--userfont', 'Arial');
// Result is equivalent to font-family: Arial, Courier, monospace;

document.documentElement.style.setProperty('--userfont', 'non existant');
// Result is equivalent to font-family: 'non existant', Courier, monospace;
// which falls back to Courier assuming 'non existant' isn't actually the name of
// an installed font

JSFiddle demo

支持

Check here

与下面的方法 2 不同,Edge v15+ 支持此方法。它还避免了方法 2 中旧版本 Chromium 中的错误。


方法二:FontFace

您可以使用 @font-face, or rather the JavaScript API FontFace.

p {
  font-family: userfont, Courier, monospace;
}
function setUserFont(fontName) {
    const userFontFace = new FontFace('userfont', `local(${fontName})`);
    document.fonts.add(userFontFace);
}

setUserFont('Arial');

JSFiddle demo

支持

Check here

Old/non-Chromium Edge(最高v18)不支持JavaScript API.

在 Chromium 73 中出现 ,其中 "Segoe UI Light" 等字体将找不到,只能找到基础 "Segoe UI"。这也适用于 @font-face。它似乎从 Chrome 80 开始修复。