Let's say I have a font face like:
@font-face {
font-family: 'MyGreatFont';
src: url(~"./font/greatfont.woff2") format('woff2'),
url(~"./font/greatfont.woff") format('woff');
font-weight: 600;
font-style: normal;
}
In places where I use it, I do something like: font-family: 'MyGreatFamily', san-serif
.
To avoid the Flash of Unstyled Text especially on devices that have slower download speeds, I want to style the fallback font differently than I would my web font.
To that end, I have several questions. I've done some reading on document.fonts
and its methods, check
, ready
and onloadingdone
.
First, I'm not quite sure what arguments to give document.fonts.check
such that it returns true once my page is fully loaded. I have tried check('MyGreatFont')
, check('600 MyGreatFont')
, check('1em MyGreatFont')
, and even tried the computed value of the font size: check('19.2px MyGreatFont)
.
All return either false
(which is not right because I know my page is fully loaded with the web font being applied) or an error: Uncaught DOMException: Failed to execute 'check' on 'FontFaceSet': Could not resolve 'Niche' as a font.
Second, as I may have multiple web fonts on a page, I want to apply my special styling when a specific web font is available. Is there a way to do that?
So far, I have:
const MyPageComponent = () => {
const [webFontsLoaded, setWebFontsLoaded] = useState(false)
useEffect(() => {
async function areFontsReady() {
await (document as any).fonts.ready
setWebFontsLoaded(true)
}
areFontsReady()
})
return (
<div className={`${webFontsLoaded ? 'web-fonts-styling' : 'fallback-font-styling'}`}>
Content here
</div>
)
}
But what this does is that it correctly applies the fallback styling when the webfont isn't loaded but continues to apply the fallback styling when the web font is loaded and rendered to the screen. Only after ALL fonts are loaded in does the styling change. This is to be expected because I am using the document.fonts.ready
function.
Is there a way to repeatedly call the check
function (using the proper arguments?) so that I know when to toggle my styling?
Note: I would prefer to achieve this behavior without the use of third-party libraries (including JQuery, Font Face Observer, etc.)
As others have already mentioned, use-font-face-observer
solves this problem. I have solved my problem in a project with React + Vite doing this:
First, install the package
npm install use-font-face-observer
Let's say you have this CSS:
@font-face {
font-family: 'Roadgeek 2000 Series C';
/* Rest of the styles... */
}
You have to match that name in your jsx code:
import useFontFaceObserver from 'use-font-face-observer';
export function SomeComponent() {
const isFontLoaded = useFontFaceObserver([
{ family: 'Roadgeek 2000 Series C' }, // Same name you have in your CSS
]);
useEffect(() => {
console.log("Is font loaded?", isFontLoaded);
}, [isFontLoaded]);
return (
// Your jsx goes here...
)
}
In your console you will see something like this
Is font loaded? false
Is font loaded? true
That variable automatically changes when that font is loaded.
I think the best way to observe the @font-face
other than CSS is with javascript. checkout this tiny library fontfaceobserver and also this blog for more improve-your-app-first-load-by... .
And also if you are using react make sure to use useLayoutEffect
because in other hooks like useEffect
the font is already loaded and ready, you should be able to access it before react
itself.
use-font-face-observer has a hook for this
const webFontsLoaded = useFontFaceObserver([{family: `MyGreatFont`}]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.