font-family是系统字体探针而非指定列表,各平台按顺序查找本地字体,iOS用San Francisco(-apple-system),Android用Roboto,需将平台首选字体前置、保留sans-serif兜底,避免跨端渲染差异。

font-family回退链为什么在Android和iOS上走不同分支
不是浏览器“不按规则执行”,而是各系统压根没有你写的那个字体。比如font-family: "Helvetica Neue", Arial, sans-serif,iOS有"Helvetica Neue",直接用;Android系统里根本没这个文件,浏览器秒跳到Arial(实际可能再 fallback 到Roboto);微信旧版WebView甚至可能绕过整个列表,强行用自己内核内置的默认等宽体。
关键点在于:font-family是「尝试列表」,不是「指定列表」。浏览器从左到右逐个查系统字体文件是否存在,一旦命中就停,后续全忽略。
- 必须把各平台原生首选字体放在最前面,例如
-apple-system(iOS/macOS)、Roboto(Android)、"Segoe UI"(Windows) - 字体名含空格或特殊字符(如
"PingFang SC"、"Hiragino Sans GB")必须用英文双引号包裹,否则解析失败 -
sans-serif必须保留且不加引号,它是最后兜底的通用族名;写成"sans-serif"会被当成自定义字体名,直接失效 - 避免混用中英文优先级逻辑——比如把
"Microsoft YaHei"放在Roboto前面,安卓设备会硬加载微软雅黑(如果存在),但体验差、加载慢、还可能触发渲染抖动
Android和iOS系统字体栈的实际可用性差异
iOS 13+ 的-apple-system实际指向 San Francisco 字体,支持全字重(100–900)、光学尺寸适配、动态类型;Android 原生Roboto只稳定提供 400/500/700 三档字重,且 500 在 Android 9 以下常被忽略;华为/小米等厂商定制内核(如 X5)可能进一步屏蔽非 400/700 的字重解析。
这意味着哪怕你写了font-weight: 500,在多数安卓设备上它就是400,连描边模拟都不会触发——因为系统连“该调用哪个字重”都没法识别。
立即学习“前端免费学习笔记(深入)”;
- 不要依赖
font-weight数字值跨端一致,尤其避开 300/600/800 这类非主流档位 -
bolder和lighter在各平台计算基准不同,生产环境禁用 - 中文文案若需强视觉层级,优先用
font-size、color、letter-spacing组合,而非仅靠font-weight
@font-face引入Web Font时的格式与顺序陷阱
只引入.woff2?Safari 旧版本、部分国产安卓浏览器直接跳过;只引.ttf?IE 和部分微信 WebView 拒绝加载。格式缺失 ≠ 加载失败,而是“静默降级”到系统字体,导致你调试时看不出问题,上线后才发现 iOS 显示 Noto Sans SC,安卓显示思源黑体,视觉割裂。
正确做法是用@font-face声明多格式,并确保 Web Font 在font-family列表中处于末尾:
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;
-
@font-face必须包含font-display: swap,防止文字闪白或阻塞首屏 - WOFF2 + WOFF 双格式覆盖 95%+ 现代设备;必要时补 EOT(仅针对 IE11)
- Web Font 名称必须与
font-family中引用的字符串完全一致(包括大小写、空格、引号) - 避免在
@font-face中声明font-weight但未提供对应字重文件——这会导致 fallback 失效或渲染异常
line-height和-webkit-text-size-adjust如何协同生效
line-height在 iOS 和安卓表现不一致,根源不在属性本身,而在底层字体度量值(ascent/descent)不同,以及 WebKit 内核对容器宽度的自适应缩放行为。iOS 默认line-height约 1.2,安卓无统一默认值;更麻烦的是,iOS 会根据父容器宽度动态调整字号(尤其在小屏或窄列布局中),导致相同font-size渲染出不同物理尺寸。
解决不能只调line-height,得先锁死基础渲染行为:
- 全局加
-webkit-text-size-adjust: none,禁用 WebKit 自动缩放(注意:该声明只对移动端 Safari / WebView 生效,Chrome for Android 忽略) - 用
rem单位替代px做字体响应式,但需配合 JS 动态设置html根字体大小,避免 iOS 横屏时 rem 基准错乱 - 行高建议用无单位数值(如
line-height: 1.5),避免em或px引入嵌套计算偏差 - 对关键模块(如按钮、标题)用
@supports (-webkit-touch-callout: none)单独微调 iOS 行高,比用 UA 判断更可靠
font-family当配置项来写,而不是当作「系统字体探针」来设计。你写的每一个字体名,都是在向目标设备发一次“你有没有这个文件”的询问——答案取决于它装了什么,而不是你希望它装什么。


















