绝大多数项目用 rem 更稳妥,因其仅依赖根元素字体大小、计算路径短且可预测性强;em 则相对父元素,嵌套后调试成本高,易引发样式不一致问题。

rem和em到底该选哪个
绝大多数项目用 rem 更稳妥,不是因为更“高级”,而是它只依赖根元素字体大小,计算路径短、可预测性强。而 em 是相对父元素的,嵌套三层以后,font-size: 0.875em 到底是 14px 还是 12.25px,得一层层往上扒,调试成本高。
常见错误现象:margin: 1em 在不同组件里表现不一致;某个弹窗里的按钮文字突然变小——八成是父容器改了 font-size,把里面的 em 全带偏了。
- 用
rem:适合全局尺寸控制,比如间距、圆角、字体大小 - 用
em:仅限需要跟随文字缩放的场景,比如border-width配合font-size做比例缩放,或图标字体(icon-font)对齐文本基线 - 别混着用:同一套间距系统里同时出现
1rem和1em,等于主动放弃可维护性
如何让rem真正响应式而不是“假装响应”
光写 html { font-size: 16px } 不叫响应式,那是固定尺寸。真响应的关键在于:根字号必须随视口动态变化,且变化曲线要平滑、有依据。
性能影响:用 vw 直接设置 font-size(如 font-size: 2.666vw)最轻量,但 iOS Safari 旧版本不支持;用 JS 动态计算更兼容,但要注意防抖和首次渲染时机。
立即学习“前端免费学习笔记(深入)”;
- 推荐方案:CSS clamp(),例如
font-size: clamp(14px, 2.5vw, 18px),兼顾可读性与伸缩性 - 避坑点:别用媒体查询硬切几档
font-size(如@media (max-width: 768px) { html { font-size: 14px } }),断点之间会突变,用户横屏/缩放时体验割裂 - 注意兼容性:
clamp()在 Safari 13.1+、Chrome 88+ 支持良好;若需支持 Safari 12 或更早,JS 方案仍是底线选择
px转rem时为什么总是算错
不是计算能力问题,是基准没对齐。开发者常默认“1rem = 16px”,但实际项目里,根字号可能被重设为 10px(方便心算)、62.5%(即 10px)、甚至 100vw / 375 * 10(适配 iPhone 6/7/8 的 375px 宽度)。
错误现象:width: 320px 写成 20rem,结果在 iPhone 上变成 200px——因为此时 1rem = 10px,不是 16px。
- 永远以运行时
document.documentElement.style.fontSize为准,别凭记忆换算 - 开发阶段建议加一行调试:
console.log('1rem =', parseFloat(getComputedStyle(document.documentElement).fontSize), 'px') - 工具链里如果用了 PostCSS 插件(如
postcss-pxtorem),务必确认其rootValue配置和实际根字号一致,否则编译结果和运行时不匹配
字体大小用rem,行高还用em吗
不用。行高(line-height)建议统一用无单位数值(如 1.5),这是 CSS 规范推荐做法,它会自动基于当前元素的 font-size 计算,无论你用的是 px、rem 还是 em。
常见错误:写 line-height: 1.5rem,结果在子元素里字体变大后,行高卡死不变,文字挤在一起;或者写 line-height: 1.5em,又陷入父级继承陷阱。
- 正确写法:
font-size: 1.125rem; line-height: 1.5 - 例外情况极少:只有当你需要强制某段文字的行高脱离自身字体大小(比如固定高度容器内垂直居中),才考虑用
px或vh,但那已不属于响应式排版范畴 - 注意:无单位
line-height不会继承“计算值”,只继承“数值”,所以不会放大嵌套误差
最麻烦的从来不是单位本身,而是团队里有人改了根字号却没同步文档,有人写了 em 却以为是 rem,还有人把设计稿的 px 值直接除以 16 就往代码里贴——这些细节不盯住,再好的方案也会在第三个月开始漏气。


















