动态设置document.documentElement.style.fontSize比媒体查询或vw更可控,推荐公式为clientWidth/750*100+'px',需在DOMContentLoaded后执行并监听resize和orientationchange,配合viewport标签及clamp()兜底。

直接用 JS 动态设置 document.documentElement.style.fontSize,比媒体查询或 vw 更可控、更少翻车。
rem 基准值必须动态算,不能写死
写死 html { font-size: 16px } 或用 font-size: 10vw 都会出问题:前者在小屏上字太小、大屏上字太大;后者在部分安卓 WebView 中解析不稳定,横竖屏切换时字体跳变。
- 推荐公式:
document.documentElement.style.fontSize = document.documentElement.clientWidth / 750 * 100 + 'px'(以 750px 设计稿为基准,100px 对应 1rem) - 执行时机:必须在
DOMContentLoaded后立即执行一次,再监听resize和orientationchange - 补丁处理:iOS Safari 加载初期可能不触发
resize,建议加setTimeout(() => { setRem() }, 0)强制兜底
哪些 CSS 属性该用 rem,哪些坚决不用
rem 是缩放单位,不是万能单位。混用会破坏视觉一致性,尤其在小屏下放大/缩小失真明显。
- 该用:
font-size、margin/padding、width/height、border-radius - 禁用:
line-height(用无单位值如1.5)、border(固定写1px,否则小屏下可能缩成 0.2rem ≈ 0.2px 不可见) - 慎用:
background-size、box-shadow偏移、transform: scale()—— 这些值本就不该随根字号缩放
viewport 标签和 rem 必须协同生效
没有正确的 <meta name="viewport">,rem 就是空中楼阁。它不光影响缩放,还决定 CSS 像素与设备独立像素的映射关系。
立即学习“前端免费学习笔记(深入)”;
- 必须写:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> - 禁止写
user-scalable=yes或minimum-scale,否则用户双指缩放会干扰 rem 缩放逻辑 - 如果项目需支持横竖屏切换,
orientationchange监听后要重新计算clientWidth,别只依赖resize
clamp() 可作为 font-size 的兜底增强方案
纯 rem 在极端屏幕(如折叠屏展开态或旧款小屏)下仍可能过小或过大。用 clamp() 能设安全边界,且无需 JS。
- 示例:
font-size: clamp(14px, 4vw, 18px)—— 最小 14px,最大 18px,中间按视窗宽度弹性过渡 - 注意:这个写法只适用于
font-size,不要套到padding或width上,否则和 rem 缩放逻辑冲突 - 兼容性:Chrome 88+、Safari 14.1+、Firefox 79+ 已支持,老版本可降级为纯 rem + 媒体查询兜底
真正容易被忽略的是:rem 缩放只解决「尺寸等比」,不解决「布局结构变化」。比如超窄屏需要把横向 tab 切成纵向列表,这得靠 @media (max-width: 375px) 或 JS 检测 clientWidth 后切 class,不能指望 rem 自己扛。


















