font-variant-numeric: tabular-nums 在旧版 Safari ≤15.3 和 Firefox ≤91 中被完全忽略,getComputedStyle 返回 "normal";需配合支持 tnum 特性的字体(如 SF Mono、Fira Code)及结构分离(数字与单位分 span)才能可靠生效。

font-variant-numeric: tabular-nums 在旧版 Safari 和 Firefox 中直接被忽略
Chrome 103+、Edge 103+、Firefox 92+、Safari 15.4+ 才稳定支持 font-variant-numeric: tabular-nums。Safari ≤15.3 和 Firefox ≤91 会完全跳过该声明,连 getComputedStyle(el).fontVariantNumeric 都返回 "normal" 或空字符串,而不是报错——这导致你查样式面板也看不出问题。
不要依赖 @supports (font-variant-numeric: tabular-nums) 做判断:旧版 Safari 对它的检测结果不可靠,可能返回 true 但实际不渲染;Firefox ≤91 则常返回 false 即使你写了属性。
- 保底方案是加
font-family: monospace(或明确等宽字体栈),它不依赖 OpenType 特性,所有浏览器都强制等宽,只是字母/汉字也会被拉平,可读性略降 - 渐进增强写法:
font-family: "SF Mono", "Fira Code", monospace; font-variant-numeric: tabular-nums;—— 先兜底,再叠加语义化控制 - 若必须区分支持状态,可用 JS 实测:
const el = document.createElement('span'); el.style.fontVariantNumeric = 'tabular-nums'; el.textContent = '0123456789'; document.body.appendChild(el); const width = el.getBoundingClientRect().width; document.body.removeChild(el);,对比纯比例数字的宽度波动(需同字体同字号)
移动端 iOS/Android 上字体不带 tnum 特性才是真瓶颈
写了 font-variant-numeric: tabular-nums 却没变化?大概率不是浏览器问题,而是字体本身没打包 tnum OpenType 特性。iOS 的 PingFang SC、Android 的 Roboto 默认 Web 字体子集、HarmonyOS Sans 等,几乎都不含等宽数字变体。
San Francisco 只有 Pro 版本(如 SF Pro Display)才支持 tnum;系统默认用的 SF UI Text 不支持。Google Fonts 的 roboto-v20-latin 也不含该特性,除非你手动加载带 &text=0123456789 参数的定制子集。
立即学习“前端免费学习笔记(深入)”;
- 验证方法:用
font-feature-settings: "tnum"替代测试,效果一致但更底层,某些旧引擎反而更敏感 - 快速定位:在 DevTools 中给元素加
.test { font-feature-settings: "tnum"; },观察0123456789是否视觉等宽;若仍不等宽,换字体栈再试 - 推荐移动端可用字体栈:
font-family: "SF Mono", "Fira Code", "IBM Plex Mono", monospace;—— 这些开源字体明确打包了tnum,且压缩后体积可控
表格里数字+单位混合时对齐失效,不是属性没生效,是作用域错了
font-variant-numeric: tabular-nums 只影响 Unicode 数字字符(U+0030–U+0039),对 ¥、%、℃、kg、括号、负号(短横 - 而非 U+2212)完全无效。所以给整个 <td>¥123.45</td> 加该属性,只会让 123.45 等宽,但 ¥ 和 . 宽度依旧浮动,整体还是歪的。
- 结构分离是唯一可靠解法:把数字包进
<span class="num">123.45</span>,单位放<span class="unit">¥</span> -
.num设font-variant-numeric: tabular-nums; font-family: "Fira Code", monospace; -
.unit设固定宽度(如width: 1.6em)或统一padding-left: 0.4em+text-align: left,避免单位字符宽度差异干扰 - 负号处理:用
<span class="num">−17</span>(U+2212)代替-17,多数支持tnum的字体能自动对其
font-feature-settings: "tnum" 和 font-variant-numeric 是等价的,但别混用
font-feature-settings: "tnum" 不是“更底层的替代方案”,它是 font-variant-numeric: tabular-nums 的等效实现,现代浏览器中两者渲染结果一致。但它们行为差异明显:
-
font-variant-numeric支持多值叠加,比如tabular-nums oldstyle-nums;而font-feature-settings必须手动拼字符串:"tnum", "onum",容易漏引号或逗号 -
font-feature-settings在部分旧版 Safari(≤15.2)中会被@supports误判为支持,实际不生效;font-variant-numeric的检测虽也有瑕疵,但更接近真实行为 - 调试时可用
font-feature-settings快速验证字体是否真含tnum:它绕过 CSS 解析层,直通字体引擎,响应更“硬”
真正容易被忽略的是:这两个属性都不会“生成”等宽数字,只负责“启用”。如果字体文件里压根没存 tnum 字形,无论怎么写,浏览器都只能回退到比例数字——这点在自定义 Web Font 或 Electron 桌面应用中尤其关键。


















