如何检测浏览器实际渲染@font-face指定字体的完成时机?
字体实际渲染完成时机的检测方案
你遇到的属性赋值和实际渲染不一致的问题,是因为@font-face引入的字体资源加载、解析是独立于DOM解析流程的:DOM树构建完成时只会完成CSS属性的赋值,字体文件还在异步加载处理,因此浏览器会先渲染后备的系统字体,等字体资源准备就绪后才会替换重绘。可以通过以下方法检测字体实际渲染就绪的时机:
方案1:使用原生Font Loading API(推荐)
这是浏览器原生提供的字体加载状态检测标准API,兼容性覆盖绝大多数主流浏览器(Chrome 60+、Firefox 58+、Safari 11.1+),可以直接调用:
// 监听所有字体加载完成的时机 document.fonts.ready.then(function() { // 此处逻辑会在所有字体加载完成、可正常渲染后触发 console.log('所有字体已完成加载渲染'); }); // 如果只需要检测指定字体Montserrat-Bold的加载状态 document.fonts.load('16px Montserrat-Bold').then(function() { console.log('Montserrat-Bold字体已就绪,可以正常渲染'); });
document.fonts.ready的触发时机刚好对应你观察到的「字体样式实际生效」的节点,完全匹配你的检测需求。
方案2:兼容旧浏览器的特征检测方案
如果需要兼容更老版本的浏览器,可以通过测量字符渲染宽度的逻辑判断字体是否生效:
- 创建一个隐藏的DOM元素,先设置为使用系统后备字体,渲染一段基准字符并记录宽度
- 轮询修改该元素的font-family为目标字体,对比当前宽度和基准宽度的差异
- 当宽度发生变化时,说明目标字体已经加载完成并生效
补充优化
你可以在@font-face规则中添加font-display: swap属性,控制浏览器先直接显示后备字体,等自定义字体加载完成后再替换,避免出现文字不可见的FOIT问题。
内容的提问来源于stack exchange,提问作者Chanwoo Park
相关产品推荐
相关产品推荐

