S1.03.4Grapheme and rendered-width mismatch设计

字符计数与显示宽度不成正比

别名: 字符数不等于字宽 · 字素簇 · rendered text width

概念解释

字符计数与渲染宽度错配(grapheme and rendered-width mismatch)指程序得到的字符串长度、用户感知的字符数和文字最终占用的像素宽度是三种不同量。一个可见符号可能由多个 Unicode 码位组成,一个码位也可能通过字体塑形与相邻字符形成连字;相同数量的可见字符还会因字形宽窄而占据完全不同的空间。

机制

字符串 API 可能按字节、UTF 编码单元或 Unicode 标量计数,而用户编辑的最小单位通常更接近扩展字素簇。组合附加符、肤色修饰符、零宽连接符序列和旗帜都能让多个码位形成一个感知字符。排版阶段又把字符序列塑形成带有 advance width、字距调整和连字的字形序列,因此计数不会线性映射为宽度。比例字体中的窄字与宽字差异,足以让等长标签产生不同换行。

边界

等宽字体只能让其覆盖范围内的常规字形占据近似固定单元,不能保证 emoji、全角字符、组合标记或后备字体仍等宽。按字素簇限制输入比按编码单元更接近用户预期,但字素簇数量仍不能预测屏幕宽度。像素测量也只对当前字体、字号、语言、塑形设置和设备缩放有效,不能作为跨平台常量。

怎么落地

  • 输入上限按业务含义选择计量单位;面向用户说明“字符数”时优先采用平台的字素簇分段,而非 UTF 编码单元。
  • 布局是否容纳文字应调用实际排版测量或直接让布局引擎排版,不用字符数乘平均字宽。
  • 截断、删除和光标移动不得拆开组合标记、emoji 修饰符或零宽连接符序列。
  • 用宽窄字形、组合字符、CJK、emoji、混合字体和文字放大构造测试;核验计数提示、一次删除行为、换行和可见内容都符合用户感知。

延伸

  • 同组S1.03.1 字体缺字会触发回退并改变版面 · S1.03.2 同一字符在不同地区有不同字形 · S1.03.3 表情与符号的渲染跨平台不一致
  • 相邻S1.01 文案膨胀与布局弹性 · S2.09 输入校验的地区差异
  • 站内检索extended grapheme cluster · text shaping · rendered text width

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/S1.03.4