The CSS Font Loading API provides a promise-based manner to load web fonts dynamically, which can enhance performance and reliability for web applications. This API allows developers to precisely control when and how fonts are used after they've loaded, reducing content flash or layout shifts that happen when web fonts are asynchronously loaded.
Understanding CSS Font Loading API
Before diving into code examples, let’s understand what the CSS Font Loading API offers. The Font Loading API enables us to load both local and remote fonts efficiently, providing a FontFace
constructor, FontFaceSet
, and the global document.fonts
interface which we can use to control the fonts on a webpage.
Basic Usage of FontFace Constructor
The FontFace
Constructor allows us to create new fonts programmatically. We can use this to specify font descriptors and URLs. Here’s a simple example of creating a FontFace instance in JavaScript:
// Initialize a new FontFace
const myFont = new FontFace('MyFont', 'url(https://example.com/fonts/myfont.woff2)');
// Load the font using the load method
myFont.load().then(function(loadedFontFace){
// Add the loaded font to the document
document.fonts.add(loadedFontFace);
console.log('Font loaded!');
});
Loading Fonts Asynchronously
One of the big advantages of the Font Loading API is the ability to use Promises to load fonts asynchronously, ensuring that the rest of the webpage does not block while awaiting font resources. This involves using the document.fonts.ready
promise, which resolves when all fonts are loaded:
document.fonts.ready.then(function() {
console.log('All fonts have either loaded or failed!');
});
Monitoring Individual Font Load Status
You may wish to know not only when fonts are loaded but also track their loading status (success or failure). This can be achieved using document.fonts.load
and handling the returned promise:
document.fonts.load('12px MyFont').then(function(fonts) {
if (fonts.length > 0) {
console.log('MyFont successfully loaded');
} else {
console.log('MyFont failed to load');
}
});
Using Multiple Font Faces
If you need to load multiple fonts, you can easily chain them together or use Promise.all()
for concurrent loading:
const font1 = new FontFace('Font1', 'url(https://example.com/font1.woff2)');
const font2 = new FontFace('Font2', 'url(https://example.com/font2.woff2)');
Promise.all([font1.load(), font2.load()]).then(function(loadedFonts) {
loadedFonts.forEach(function(font) {
document.fonts.add(font);
});
console.log('All fonts loaded successfully');
});
Handling Fallback Fonts
One important aspect to handle is fallback fonts while waiting for your desired fonts to load. Browsers typically handle fallback fonts automatically, but you can further customize this behavior by using CSS. For example, set a fallback in your CSS file:
body {
font-family: Arial, sans-serif; /* Fallback fonts */
}
.custom-font {
font-family: MyFont, Arial, sans-serif;
}
Ensure your styles are structured to look seamless, even when the desired fonts are loading or if they fail to load.
Conclusion
The CSS Font Loading API provides fine-grained control over how and when web fonts are applied to different elements on your page. With a solid grasp of the fundamentals, you can make sure your web application leverages dynamic font loading to improve both performance and user experience. As with any asynchronous operations, handling errors and planning for potential failures is key in providing a robust solution that accommodates all possibilities.