结论:用 rem 控制全局缩放尺度,用 em 处理文字强关联的局部微调;rem 依赖根字号等比缩放全局样式,em 依据自身字号维持文字节奏,混用需严格分工以防嵌套失控。

直接说结论:用 rem 控制全局缩放尺度,用 em 处理文字强关联的局部微调;混用不是不行,但必须明确谁管“整体比例”,谁管“文字节奏”,否则嵌套一深就失控。
为什么 rem 是响应式布局的默认起点
rem 的缩放只依赖 html 元素的 font-size,改一次,所有 1.5rem 的间距、0.25rem 的圆角、1.125rem 的字体大小全部等比变化。它不关心你写了多少层 div,也不依赖父级样式——这是可控性的根本。
常见错误现象:font-size: 16px 写死在 html 里,再靠媒体查询切 html { font-size: 14px },结果横屏切换时尺寸突变;或者用 font-size: 2.666vw 直接设根字号,但在 Safari 12 及更早版本里直接失效。
- 推荐方案:用
clamp(14px, 2.5vw, 18px)设置html { font-size },小屏取下限、大屏取上限、中间线性插值,无闪动、无 JS、兼容主流浏览器(Safari 13.1+、Chrome 88+) - 必须显式声明
html { font-size: 16px },不能留空、不能靠继承;font-size: 62.5%这类技巧会和系统字体缩放冲突,尤其在 macOS + Safari 下失准 - JS 动态设置仍是底线方案:在 DOM 加载早期执行
document.documentElement.style.fontSize = (document.documentElement.clientWidth / 375) * 16 + 'px',并加防抖,避免 FOUC
em 该用在哪?只限父字号强耦合的局部场景
em 的价值不在“缩放”,而在“跟随当前文字节奏”。它的参照对象是**当前元素自身的 font-size**(注意:不是父级),所以适合图标尺寸、边框粗细、行高等必须与本元素文字对齐的属性。
危险信号:padding: 1em 用在卡片里,但卡片标题用 1.5rem、正文又用 px——这类混用会让间距逻辑彻底断裂;三层嵌套后 font-size: 1.2em × 1.2em × 1.2em = 实际放大 1.728 倍,数值已脱离直觉。
- 安全用法:
line-height: 1.5(无单位)代替line-height: 1.5em;border-width: 0.0625em仅当明确需要边框随文字缩放时才用 - 图标字体(icon-font)设
font-size: 1.2em,能自然对齐文本基线;伪元素如::before { font-size: 0.8em; }确保装饰符号始终贴合主文字 - 别用
em控制容器宽高或 flex/grid 项目尺寸,否则父级字号一调,布局容易连锁错位
混用 rem 和 em 的实际搭配建议
一个稳健的组合是:根字号用 clamp() 或 JS 动态设置 → 页面主体结构(margin/padding/width/border-radius)统一用 rem → 文字相关微调(图标、行高、内边距)用 em → 关键断点仍保留媒体查询兜底。
例如导航栏高度用 height: 3rem,内部图标用 font-size: 1.1em,这样图标始终略大于文字;按钮内边距用 padding: 0.5em 1em,文字变大时留白也自然撑开。
- 不要混着用同一套设计系统里的基础间距变量,比如
$space-md: 1.5rem和$space-md: 1.5em并存,后期换根字号时em部分会意外失效 - 调试时重点看 computed 值:如果某个
1.5rem计算出来不是预期像素,说明根字号没生效;如果1em在子元素里突然变大,大概率是父容器被 JS 修改了font-size -
margin和padding用em时,参照的是该元素自身的font-size,不是父级——很多人误以为是父级,结果改了父容器字号,子元素内边距却没变
最常翻车的地方不是单位本身,而是同一类样式在不同组件里随意切换参照系。比如一个按钮用 rem 设 padding,另一个同级按钮用 em,视觉节奏就断了。真正难的不是写对代码,而是让整个团队在设计系统里守住那条分界线:rem 管尺度,em 管节奏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











