getBoundingClientRect and custom fonts
This is a minor gotcha that you may run into when working with browser APIs like getBoundingClientRect
.
If you want to perform calculations based on the exact position of an element whose size depends on its text content, you will find that you sometimes get an incorrect result when refreshing the page. After the page is fully loaded though, everything works as expected. So what's going on here?
useEffect(() => {
const x = element.current.getBoundingClientRect().x; // wrong x position
})
This is caused by the fact that the element's position is calculated before your custom font has been applied to it. You can get around this by using the (as yet experimental) FontFaceSet
API's ready
method.
const [fontLoaded, setFontLoaded] = useState(false);
useEffect(() => {
document.fonts.ready.then(() => {
setFontLoaded(true);
});
});
Then run the effect again when the font has loaded:
useEffect(() => {
const x = element.current.getBoundingClientRect().x;
}, [fontLoaded]);
References
https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet
https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready