Is it possible to easily set a custom local font using JavaScript, but retain some default font-family
stack in case the user tries to set a font that doesn't exist?
E.g., if the stack is font-family: Courier, monospace;
, how to add to the beginning of the stack without resorting to manipulating strings?
The original answer below (method 2) had some issues, but then I came up with a more straightforward solution using 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
Unlike method 2 below, this method is supported by Edge v15+. Also it avoids the bug in older versions of Chromium that method 2 suffers from.
You can use @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');
Old/non-Chromium Edge (up to v18) does not support the JavaScript API.
It appears there is a bug in Chromium 73 whereby fonts such as "Segoe UI Light" will not be found, only the base "Segoe UI" will be found. This applies to @font-face
as well. It seems to be fixed as of Chrome 80.