CSS: Fallback fonts
you can specify multiple fonts:
p {
font-family: "Times New Roman", Times, serif;
}
The browser will try the first one, if that one isn't available the second, and so forth. In the end it uses the family serif, so the browser chooses any serif font. You should use the monospace family.
So in your case, something like this is what you want:
p {
font-family: "Lucida Console", "Courier New", monospace;
}
Adding fallback fonts to the @font-face definition
No, you cannot specify any fallback fonts inside a @font-face
rule, because such a rule defines a font face and assigns a name to it. Inside the rule, the font-family
part can contain only one name, the name you choose to assign. It would be pointless list several names there, since only the first one can possibly matter (and, besides, in this context no name has any predefined meaning, e.g. Arial would not mean the Arial font but be just an arbitrary assigned name).
Fallback fonts can be specified only in normal font-family
rules.
Consider organizing your style sheet so that the relevant font-family
list appears only once, using a suitable list of selectors, like
p, blockquote, .foobar, .something {
font-family: MyWebFont, Arial, Helvetica, sans-serif;
}
How to set font family but retain fallback stack?
Method 1: CSS custom properties
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
JSFiddle demo
Support
Check here
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.
Method 2: FontFace
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');
JSFiddle demo
Support
Check here
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.
Node canvas use fallback font for unknown characters
You just need to specify 'Code2000' when you're setting the font. Consecutive fonts separated by commas are used as fallback fonts.
ctx.font = '50px Uni Sans, Code2000'
I tested this myself, and it worked perfectly.
How to apply fallback font to all text, not only missing characters
Alright, so if you would avoid a bit of font flickering at any cost, I would suggest server side processing here - if you want to save a bit of performance on your server, I would go client side with javascript:
the css:
.font-montserrat {
font-family: Montserrat;
}
and the js with jQuery (server side, you would adapt this during rendering and put in some php function or whichever language you use):
$('p').each(function() {
var p = $(this);
// here it is important to avoid other inline tags like b, i, span, etc
var textWithoutOtherTags = p.text();
// this is the main bit and one would simply test by a regular expression
// - this can be adapted as needed, at the moment it returns true, if a
// single latin or cyrilic letter is present
var hasLatin = /[a-z]/gi.test(textWithoutOtherTags);
var hasCyrilic = /[а-я]/gi.test(textWithoutOtherTags);
// now add the class depending on the containing characters
if (hasLatin && hasCyrilic) {
p.addClass('font-montserrat');
}
});
You can of course also do it easily without jQuery, but then please be aware of the b, i, strong, span and other inline tags, that might occur inside of your p, and filter them out before the regex testing.
Nice task ;)
How to add a fallback font for a non supported character in font-face?
Actually if I understand your question right you can by using css unicode-range
see @font-face/unicode-range at: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range
and a quick example:
@font-face {
font-family: Almoni;
src: url(Almoni.ttf);
unicode-range: U+0590-05FF;
}
@font-face {
font-family: CoolOtherLanguageFont;
src: url(CoolOtherLanguageFont.ttf);
unicode-range: U+0370-03FF, U+1F00-1FFF;
}
body {
font-family: Almoni, CoolOtherLanguageFont, Helvetica;
}
Related Topics
CSS Targetting The Last of a Class Type That Isn't The Last-Child
Add Cell Borders in an R Datatable
Why Does The Img Tag Accept The Margin-Top Property
How to Capitalize The First Letter of an Input
CSS Column-Count Not Respected
Improving Balance in Flexbox Lines
Make an Image Fit Its Container by Setting The Image Height to The Containers Heights
CSS3 Selector Last Element That Is Not of Class X
When Do Nested Child Elements Expand Their Parent Elment
CSS Media Queries for Print Paper Size
Fill Parent Container and Reduce Image Resolution with Next/Image
Fill a Parent Div While Maintaining a Ratio
CSS Target Just Class Name Starts with and Ends with String