在CSS中,em
和rem
都是相对长度单位,用于实现灵活的尺寸控制(如字体大小、间距、宽高等),但它们的“参考基准”不同,适用场景也有明显区别。下面通过具体例子和场景分析,帮你彻底搞懂两者的用法。
一、核心区别:参考基准不同
em
:相对父元素的font-size
计算(父元素的字体大小是基准)。rem
:相对根元素(<html>
)的font-size
计算(根元素的字体大小是基准,rem
中的r
即“root”)。
二、em
的用法:依赖父元素
基础规则:
1em = 父元素的font-size
值。如果父元素没设置font-size
,则继承更上层元素的font-size
(最终默认继承浏览器的根元素默认值,通常是16px)。
示例1:简单的父元素基准
<style>
.parent {
font-size: 20px; /* 父元素字体大小为20px */
}
.child {
font-size: 1em; /* 1em = 父元素20px → 字体大小20px */
width: 5em; /* 5×20px = 100px → 宽度100px */
height: 3em; /* 3×20px = 60px → 高度60px */
background: #e0f7fa;
}
</style>
<div class="parent">
父元素(字体20px)
<div class="child">子元素(字体1em=20px,宽5em=100px)</div>
</div>
示例2:嵌套场景的“累积效应”(em
的坑)
em
会继承父元素的基准,多层嵌套时可能导致尺寸“越套越大”:
<style>
.grandpa { font-size: 16px; } /* 祖父元素:16px */
.parent { font-size: 1.5em; } /* 1.5×16px = 24px → 父元素字体24px */
.child { font-size: 1.5em; } /* 1.5×24px = 36px → 子元素字体36px */
.grandchild { font-size: 1.5em; } /* 1.5×36px = 54px → 孙元素字体54px */
</style>
<div class="grandpa">
祖父(16px)
<div class="parent">
父元素(1.5em=24px)
<div class="child">
子元素(1.5em=36px)
<div class="grandchild">孙元素(1.5em=54px)</div>
</div>
</div>
</div>
注意:这种累积效应可能导致嵌套元素尺寸失控,因此em
更适合“局部小范围”使用。
三、rem
的用法:依赖根元素
基础规则:
1rem = 根元素(<html>
)的font-size
值。无论元素嵌套多少层,rem
始终以根元素为基准,避免了em
的累积问题。
示例1:根元素基准的稳定性
<style>
html { font-size: 16px; } /* 根元素字体16px → 1rem=16px */
.parent { font-size: 2rem; } /* 2×16px = 32px → 父元素自身字体32px */
.child {
font-size: 1rem; /* 1×16px = 16px → 不受父元素32px影响 */
width: 10rem; /* 10×16px = 160px → 宽度160px */
height: 5rem; /* 5×16px = 80px → 高度80px */
background: #e8f5e9;
}
</style>
<div class="parent">
父元素(2rem=32px)
<div class="child">子元素(1rem=16px,宽10rem=160px)</div>
</div>
可以看到,子元素的rem
尺寸完全不受父元素font-size
的影响,只依赖根元素。
实用技巧:简化rem
计算
默认1rem=16px(浏览器默认根字体大小),计算时不够直观(如10px需要写0.625rem
)。通常会将根元素font-size
设为62.5%(16px×62.5%=10px),此时1rem=10px,换算更简单:
html { font-size: 62.5%; } /* 1rem=10px(简化计算) */
h1 { font-size: 2.4rem; } /* 24px(2.4×10) */
p { font-size: 1.6rem; } /* 16px(1.6×10) */
.box { width: 30rem; } /* 300px(30×10) */
四、适用场景对比
单位 | 优势 | 最佳场景 | 反面场景 |
---|---|---|---|
em |
基于父元素,适合“局部比例控制” | 1. 组件内部的尺寸关联(如按钮的图标大小随文字变化) 2. 嵌套元素的相对缩进(如列表项的 padding-left 随字体大小变化) |
多层嵌套的全局布局(易累积失控) |
rem |
基于根元素,全局统一可控 | 1. 页面全局尺寸(如容器宽度、整体字体大小) 2. 响应式设计(通过修改根元素 font-size 批量调整页面) |
组件内部需要依赖父元素动态变化的场景 |
五、响应式设计中的rem
实战
通过媒体查询动态修改根元素font-size
,可让所有rem
单位的元素自动适配不同屏幕:
/* 小屏幕(默认):1rem=10px */
html { font-size: 62.5%; }
/* 中等屏幕(≥768px):1rem=12px(整体放大) */
@media (min-width: 768px) {
html { font-size: 75%; }
}
/* 大屏幕(≥1200px):1rem=14px(进一步放大) */
@media (min-width: 1200px) {
html { font-size: 87.5%; }
}
/* 全局元素随根元素动态变化 */
.container { width: 80rem; }
/* 小屏:80×10=800px → 中屏:80×12=960px → 大屏:80×14=1120px */
总结
em
是“局部相对单位”:依赖父元素,适合组件内部的细节比例控制,但要注意嵌套累积问题。rem
是“全局相对单位”:依赖根元素,适合全局布局和响应式设计,控制更统一。- 实际开发中常混合使用:用
rem
定全局框架,用em
调组件内部细节(如按钮的内边距随文字大小变化)。