F4.15.3webfont metric mismatch CLS设计

回退字体与目标字体的度量差异会造成加载后的布局跳动

别名: 字体度量 · CLS · fallback metrics · size-adjust

概念解释

后备字体先画上去,自定义字体一到,字母宽度、字身高度、行盒都可能变,已经排好的行会重排,下面的按钮被顶走。这是度量不匹配造成的布局跳动(metric mismatch / cumulative layout shift),不是「换了个更好看的脸」那么轻。FOUT 让字尽早可见,账单在这一跳上。

机制

字体的度量是一套数字:x 高度、升部、字宽、默认行高。两张脸的数字对不上,同样的字符序列占的盒子就不同。换脸等于把一段已经布局完的文本换成另一套盒子,后续块的位置全部重算。用户若正在点那个被顶走的按钮,点到的是新上来的别的东西。跳动的大小跟两张脸的差异成正比,跟这段文本的面积成正比:导航上几个词跳一点,一篇文章跳整屏。补救不是回到隐形等待,而是让两张脸的度量靠近——选度量相近的后备,或用覆盖度量(如 size-adjust、ascent-override)把后备「假装」成目标脸的盒子,换脸时盒子几乎不变,变的只有轮廓。

边界

两张脸几乎是同一家族的不同文件(可变字体的轴、同一设计的网页版与系统版),跳动可以小到看不出。阻塞到自定义字体到达才绘制,没有换脸,也就没有这一种跳动——那是用 FOIT 换掉了 CLS,不是度量被修好了。图标、不参与文档流的绝对定位字标,跳了也不挤别人。用户正在滚动时发生的换脸,跳动会被滚动本身盖住,但停下来读的时候仍会感到段落在挪。

怎么落地

  • 为正文指定度量接近的后备字体,或给 @font-face 写度量覆盖,让换脸前后行宽和行数尽量不变。
  • 在换脸瞬间截前后两帧叠在一起,看行末和下面按钮挪了多少。导航和第一屏正文若发生明显重排,先改度量,不要先改回长时间空白。
  • 用布局偏移作为验收:自定义字体到达不应把主按钮移出原先的点击位置。

延伸

  • 同组F4.15.1 自定义字体加载完成前的文本呈现方式需要显式策略 · F4.15.2 长时间空白等待字体会比先用回退字体展示更损害体验 · F4.15.4 网络字体加载失败时系统字体应作为兜底而非留白
  • 相邻F4.02 行高 · F4.07 字体选择
  • 站内检索CLS · font metrics · size-adjust

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/F4.15.3