rem和em到底有啥不一样
写CSS的时候,字体大小、间距这些属性经常会用到相对单位。rem和em看起来差不多,都是相对于某个基准来计算尺寸,但它们的参照物完全不同,稍不注意就会让页面布局乱套。
em是基于父元素的字体大小
em的计算方式有点“随家风”。它参考的是当前元素的父元素font-size值。比如父元素字体是16px,那么1em就是16px;如果父元素是20px,那1em就变成20px了。更麻烦的是,em会层层继承,子元素再套子元素,每一层都可能放大或缩小。
举个例子:
<div style="font-size: 16px;">
<p style="font-size: 1.2em;">这段文字是16*1.2=19.2px</p>
<div style="font-size: 20px;">
<p style="font-size: 1.2em;">这段是20*1.2=24px</p>
</div>
</div>
同一个1.2em,在不同父级下显示效果完全不一样。这种“越嵌套越难控”的特性,让很多开发者在复杂结构里踩过坑。
rem只认根元素
rem就不一样了,它永远只看根元素(也就是html标签)的字体大小。默认情况下,大多数浏览器的html font-size是16px,所以1rem = 16px。只要你没改过根字号,整个页面里所有1rem都是一样大。
比如你设置了:
html {
font-size: 18px;
}
.box {
font-size: 1.5rem; /* 18 * 1.5 = 27px */
}
.text {
margin: 1rem; /* 18px 的外边距 */
}
不管.box或.text被嵌套多少层,它们的尺寸始终基于html的18px来算,不会因为父级变化而改变。这种“认准一个爹”的设定,在做响应式布局或者设计系统时特别省心。
实际场景怎么选
如果你在做一个组件库,比如按钮、卡片这类需要独立缩放的模块,用em更合适。比如把一个按钮整体放大,里面的文字、图标、间距都能跟着父级比例变,保持视觉协调。
但如果是整站的排版、栅格、间距系统,推荐统一用rem。尤其在移动端适配时,配合JS动态调整html字号,整个页面就能等比缩放,开发和维护都轻松不少。
有些团队干脆规定:字体大小可以用em,其他所有尺寸一律用rem,避免样式失控。