直接改 document.documentElement.style.fontSize 是唯一兼顾功能、可访问性和维护性的做法,前提是全站用 rem 单位;改 body font-size 会引发 em 二次计算、覆盖系统缩放、导致第三方组件失效;三档切换应基于百分比动态设置 html 字体大小,并配合 localStorage 持久化与时机控制。

直接改 document.documentElement.style.fontSize 是唯一兼顾功能、可访问性和维护性的做法,前提是全站用 rem 单位;其他方式要么破坏系统缩放,要么漏改元素,要么卡顿掉帧。
为什么不能改 body 的 font-size?
改 body { font-size: 18px; } 看似简单,但会触发两层副作用:
-
em值二次计算:比如div { font-size: 1.2em; }原本基于 16px 算出 19.2px,body 变成 18px 后它就变成 21.6px——不是线性放大,而是嵌套放大,字号跳变不可控 - 覆盖用户系统级缩放:Windows“放大文本”或 macOS“更大字体”设置会被强制重置,视障用户可能看到文字被截断、行高撑破容器、甚至按钮热区错位
- 第三方组件失效:日期选择器、弹窗等内部写死
px或em的 UI 库,会和你改的body冲突,出现字号不一致
怎么用 rem + document.documentElement.style.fontSize 实现三档切换
核心是只动根元素,让所有 rem 自动响应。初始化时别写死 px,推荐用百分比继承浏览器基准:
- 默认设
html { font-size: 100%; }(即继承系统 16px) - 小号:执行
document.documentElement.style.fontSize = '87.5%';(≈14px) - 标准:执行
document.documentElement.style.fontSize = '100%'; - 大号:执行
document.documentElement.style.fontSize = '112.5%';(≈18px) - 用
localStorage记住上次选择,页面加载后立即应用,避免刷新回退
注意:别用 document.documentElement.style.cssText = 'font-size: 18px',它会清空原有 clamp() 或媒体查询声明,导致响应式失效。
立即学习“前端免费学习笔记(深入)”;
按钮点击没反应?优先排查这三处
多数失效不是 JS 写错,而是样式或时机干扰:
-
font-size被更高优先级样式覆盖:打开开发者工具 → Computed 面板 → 查看font-size最终值及来源,重点检查带!important的第三方 CSS - 存在写死
px的元素:如h1 { font-size: 32px; },这类必须手动同步改,或统一转成2rem(以 16px 为基准) - JS 执行太早:脚本放在
</body>前,或包在DOMContentLoaded里,否则 DOM 还没加载完就去改html.style
移动端双指缩放后按钮失效怎么办
iOS Safari 用户若已双指放大过页面,再点字号按钮可能无感——因为整个视口被 transform: scale() 覆盖了。确保 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 中 user-scalable 没被设为 no,否则系统缩放能力被禁用,按钮功能形同虚设。
真正难的不是让字变大,是让变大的过程不破坏任何已有逻辑:系统缩放、第三方组件、打印样式、屏幕阅读器播报——这些都依赖 font-size 的语义正确性,而不是视觉拉伸。



















