绝大多数项目该用rem,因其只依赖html{font-size}一个可控源头,实现整站文字、间距、圆角等按相同比例缩放;em仅适用于组件内局部微调且需显式声明自身font-size。

绝大多数项目该用 rem,不是因为它“更现代”,而是它只依赖 html { font-size } 这一个可控源头;em 仅适合组件内局部微调,且必须显式声明自身 font-size,否则参照系会漂移。
什么时候必须用 rem
当你要整站文字、间距、圆角、行高等按相同比例缩放,且不希望改一处、查三层时,rem 是唯一靠谱选择。它的计算链路干净:所有值都只乘以 html 的最终计算字号。
- 必须显式写
html { font-size: 16px; },别依赖浏览器默认——iOS Safari 可能在双击缩放后悄悄重置根字号 - 推荐用
html { font-size: clamp(14px, 2.5vw, 18px); }:小屏保可读、大屏不溢出、中间平滑过渡(Safari 13.1+ / Chrome 88+ 支持良好) - 若需兼容 Safari 12 或更低版本,只能用 JS 动态设
document.documentElement.style.fontSize,且必须在DOMContentLoaded后立即执行 + 防抖,否则首屏渲染取不到视口宽 - 别用
font-size: 62.5%这类“方便心算”的写法——它依赖用户系统默认字号,且和 macOS + Safari 的字体缩放功能冲突,实测失准
em 真正该用在哪
em 不是错,只是适用面极窄。它只在“当前文字节奏就是设计节奏”的局部场景里自然,比如图标对齐、边框粗细随字号微调、按钮内边距随自身文字同比例伸缩。
-
padding和margin用em时,参照的是该元素**自身的**font-size,不是父级——很多人误以为是父级,结果改了父容器字号,子元素内边距却没变 - 安全前提:组件自身显式声明了
font-size,且嵌套层级 ≤ 2。例如:.btn { font-size: 14px; padding: 0.75em; } - 危险信号:
padding: 1em用在卡片里,但标题用1.5rem、正文用px——混用等于主动放弃间距逻辑一致性 - 绝对陷阱:
line-height: 1.5em(会二次乘以自身字号),正确写法是line-height: 1.5(无单位)
哪些地方必须用 px
border、border-radius、box-shadow、小图标尺寸这些要像素级精准的属性,一律用 px。它们不能被缩放干扰,否则边框变粗、圆角突兀、阴影层次崩塌。
立即学习“前端免费学习笔记(深入)”;
-
border: 1px solid #ccc—— 改字体或视口,边框粗细不能变 -
border-radius: 4px、box-shadow: 0 2px 8px rgba(0,0,0,0.1)—— 像素级控制才保证 UI 精致感 -
icon-font尺寸可用1.2em对齐基线,但装饰性小图标(如width: 24px)仍得用px保证像素对齐 - 高清屏模糊问题不是单位问题,是渲染策略问题:基础值仍得是
px,再配合transform: scale(0.5)修复
混用单位最隐蔽的坑
单位选错不会报错,但会让样式在缩放、嵌套或主题切换时突然失衡。最常出问题的地方不是数值算错,而是参照物打架。
-
font-size: 1.5rem+line-height: 1.5是安全的;但若写成line-height: 1.5em,就会二次乘以当前字号,行高翻倍 - 伪响应:全局用
rem,但某个弹窗组件 JS 动态设置了父容器的font-size,结果里面所有em值被带偏,按钮文字变小、间距变大 - 自定义 CSS 变量(如
--space-md: 1rem)不能参与rem计算,rem只认html最终计算值,不是变量名 - 媒体查询里改
html { font-size }时,别用硬切断点:@media (max-width: 768px)容易导致横屏/缩放时尺寸突变
真正难的不是选单位,而是守住参照系——一旦让 em 跨组件传播,或让 rem 失去对根字号的控制权,调试时就得逐层回溯 computed 值,而不是一眼看清缩放路径。


















