font-weight 渲染不一致是浏览器、系统字体栈与合成策略共同作用的结果,需从字体交付、字重声明、合成控制三方面协同解决。

直接说结论:font-weight 解析不一致不是 CSS 写错了,而是浏览器+系统字体栈+合成策略三者共同作用的结果;靠改一个属性值或加前缀无法根治,必须从字体交付、字重声明、合成控制三个层面协同处理。
为什么 font-weight: 700 在 Chrome/macOS 看着粗,Android 上却发虚?
Core Text(macOS)和 DirectWrite(Windows)对“加粗”的实现逻辑不同:前者增强笔画厚度与对比度,后者优先保清晰防糊;而 Android WebView 多数只内置 Regular(400)字重,font-weight: 700 只能靠描边模拟,导致边缘毛糙、字形膨胀。这不是渲染 bug,是字体资源缺失下的必然 fallback 行为。
用 @font-face 显式声明每个字重档位,别共用 font-family 名
系统字体(如 "PingFang SC"、"Microsoft YaHei")通常只提供 400/700 两个物理字形,font-weight: 500 或 600 很可能被降级到 400。真正可控的方式是引入多字重 Web Font,并为每个档位单独写 @font-face:
/* 正确:每个字重独立声明 */
@font-face {
font-family: "Inter";
src: url("inter-400.woff2") format("woff2");
font-weight: 400;
font-display: swap;
}
@font-face {
font-family: "Inter";
src: url("inter-500.woff2") format("woff2");
font-weight: 500;
font-display: swap;
}
@font-face {
font-family: "Inter";
src: url("inter-700.woff2") format("woff2");
font-weight: 700;
font-display: swap;
}- 禁止把多个字重塞进同一个
@font-face块里,否则浏览器无法准确匹配 - 必须搭配
font-display: swap,避免加载期间回退到系统字体造成粗细跳变 - 中文推荐用
HarmonyOS Sans、Alibaba PuHuiTi或Noto Sans SC,它们明确支持 300–900 全档位
禁用 font-synthesis 防止浏览器乱合成
当指定的 font-weight 在字体文件中不存在时,浏览器会自动合成(synthesis),但 macOS 合成更激进,Android 几乎不合成——这放大了跨平台差异。用 font-synthesis 显式约束:
立即学习“前端免费学习笔记(深入)”;
-
font-synthesis: none:强制只用字体文件里真实存在的字重,适合你已提供完整档位的场景 -
font-synthesis: weight:仅允许合成字重(不合成斜体),比默认值all更可控 - 避免
font-synthesis: all(默认),尤其在中文下合成粗体会明显发虚
示例:
h2 {
font-family: "Inter", sans-serif;
font-weight: 500;
font-synthesis: weight;
}别信 transition: font-weight,它根本不会动
所有主流浏览器(Chrome/Firefox/Safari)都不支持 font-weight 的 CSS 过渡动画,写了 transition: font-weight 0.3s 也只会瞬间跳变。这不是兼容性问题,是规范层面就不支持离散字重切换的插值。
- 想模拟“动态加粗感”,可用
transform: scale(1.01)+opacity: 0.98组合,视觉上更自然 - 真要渐变粗细,得换技术栈:SVG 文字控制描边宽度,或 Canvas 手动绘制字形
- 关键文案别依赖
font-weight做层级区分,优先用font-size、color、letter-spacing组合
最易被忽略的一点:Web Font 加载完成前,浏览器用系统字体渲染,此时 font-weight 行为完全由系统决定;加载完成后才切换。这个过程在低端 Android 设备上可能持续几百毫秒,造成肉眼可见的闪动——必须用 font-display: swap + 预加载 + 尽量减少字重档位来压低影响。


















