陌上人如玉
公子世无双

前端单位深度解析:rem 与 em 的原理、区别及实战应用

在前端开发中,CSS 单位的选择直接影响页面的响应式效果和适配性,rem 和 em 作为相对单位的核心代表,是实现灵活布局的关键。本文将从底层原理、核心区别、实现方式到实际应用场景,全方位拆解这两个高频使用的单位,帮你彻底搞懂何时用、怎么用。

一、rem 与 em 的底层实现原理

1. em 单位:基于“父元素/自身字体大小”的相对单位

em 是相对于当前元素或最近父元素的 font-size 计算的相对单位,其核心原理是:
– 1em = 当前作用元素的 font-size 实际像素值;
– 若当前元素未设置 font-size,则向上追溯最近的已设置 font-size 的父元素;
– 若所有父元素均未设置,则继承浏览器默认字体大小(通常为 16px,即 1em = 16px)。

举个直观例子:

/* 父元素 */
.parent {
  font-size: 20px; /* 基准值 */
}
/* 子元素 */
.child {
  font-size: 1.5em; /* 1.5 * 20px = 30px */
  width: 2em; /* 2 * 30px = 60px(此处em基于自身font-size) */
}

注意:em 用于非字体属性(如 width、margin)时,仍基于当前元素的 font-size,而非父元素,这是容易踩坑的点。

2. rem 单位:基于“根元素字体大小”的相对单位

rem(root em)是 CSS3 新增的相对单位,核心原理是仅基于根元素 <html> 的 font-size 计算,摆脱了父元素层级的影响:
– 1rem = <html> 元素的 font-size 实际像素值;
– 若未设置 <html> 的 font-size,则默认继承浏览器基准值(16px)。

示例:

/* 根元素 */
html {
  font-size: 16px; /* 基准值 */
}
/* 任意层级元素 */
.box {
  font-size: 2rem; /* 2 * 16px = 32px */
  margin: 1rem; /* 1 * 16px = 16px */
}

即使 .box 嵌套在多层父元素中,其 rem 计算始终只依赖 <html> 的字体大小,这是 rem 最核心的优势。

二、rem 与 em 的核心区别

维度 em rem
参考基准 当前元素/最近父元素的 font-size 根元素(html)的 font-size
层级影响 受父元素 font-size 层层影响 不受任何父元素层级影响
计算复杂度 高(需追溯父元素) 低(仅参考根元素)
适配场景 局部微调(如图标与文字对齐) 全局响应式布局(如移动端适配)
兼容性 IE6+ IE9+(移动端基本无兼容问题)

三、rem 与 em 的具体实现方式

1. em 的实现与使用

em 适合局部样式调整,核心是利用“相对父元素”的特性实现精细化控制:

/* 示例1:文字与图标对齐 */
.icon-box {
  font-size: 14px; /* 基准值 */
}
.icon {
  font-size: 1.2em; /* 1.2*14=16px,图标略大 */
  margin-right: 0.5em; /* 0.5*14=7px,间距适配文字大小 */
}

/* 示例2:按钮内边距适配文字 */
.btn {
  font-size: 16px;
  padding: 0.5em 1em; /* 上下8px,左右16px,随字体大小同步变化 */
  border: 0.1em solid #007fff; /* 边框宽度1.6px,与字体成比例 */
}
/* 大按钮仅需修改字体,其他样式自动适配 */
.btn-large {
  font-size: 20px; /* padding自动变为10px/20px,边框变为2px */
}

2. rem 的实现与使用

rem 核心用于全局响应式,通常结合 JS 动态设置根元素 font-size 实现移动端适配,步骤如下:

步骤1:设置根元素基准值(基础版)

/* 以设计稿宽度375px为例,设置1rem=10px(方便计算) */
html {
  font-size: 10px; 
}
/* 设计稿中37.5px的元素,对应3.75rem */
.header {
  height: 4.4rem; /* 44px */
  font-size: 1.6rem; /* 16px */
}

步骤2:结合JS动态适配(实战版)

为适配不同屏幕宽度,需通过 JS 动态计算根元素 font-size:

// 动态设置rem基准值(设计稿宽度750px,1rem=100px)
function setRemBase() {
  // 获取屏幕宽度
  const screenWidth = document.documentElement.clientWidth;
  // 限制最大宽度(避免平板/PC端过大)
  const maxWidth = 750;
  const baseWidth = screenWidth > maxWidth ? maxWidth : screenWidth;
  // 计算根元素font-size:1rem = (baseWidth / 750) * 100
  document.documentElement.style.fontSize = (baseWidth / 750) * 100 + 'px';
}

// 初始化执行
setRemBase();
// 窗口大小变化时重新计算
window.addEventListener('resize', setRemBase);
// 横屏切换时重新计算
window.addEventListener('orientationchange', setRemBase);

步骤3:CSS中使用rem(实战示例)

/* 设计稿中75px的元素,对应0.75rem */
.container {
  width: 7.5rem; /* 750px设计稿的100%宽度,适配所有屏幕 */
  margin: 0 auto;
}
.card {
  width: 3.4rem; /* 设计稿340px */
  height: 2rem; /* 设计稿200px */
  padding: 0.2rem; /* 设计稿20px */
  font-size: 0.28rem; /* 设计稿28px */
}

四、实际场景中的应用选择

1. 优先使用 em 的场景

  • 局部样式微调:如图标与文字的间距、按钮内边距(随字体大小同步变化);
  • 继承式布局:如嵌套列表的缩进(子列表 font-size: 0.9em,逐层缩小);
  • 兼容旧版浏览器:如需适配 IE6-8 的项目(rem 不兼容)。

2. 优先使用 rem 的场景

  • 移动端全局适配:如页面宽度、组件尺寸、字体大小(统一基于屏幕宽度缩放);
  • 多端适配:如一套样式适配手机、平板(仅需调整根元素 font-size);
  • 避免层级干扰:如复杂嵌套结构(em 易因父元素字体变化导致尺寸错乱,rem 更稳定)。

3. 混合使用场景

实际开发中常结合两者优势:

/* 全局尺寸用rem,局部细节用em */
.page {
  width: 7.5rem; /* 全局宽度,基于rem适配屏幕 */
  padding: 0.3rem; /* 全局内边距 */
}
.title {
  font-size: 0.32rem; /* 标题字体,全局统一 */
  margin-bottom: 0.5em; /* 标题下方间距,基于自身字体大小(0.5*0.32rem=0.16rem) */
}
.icon {
  font-size: 1.2em; /* 图标大小,适配标题字体 */
  margin-right: 0.3em; /* 图标与文字间距,适配标题字体 */
}

五、使用注意事项

  1. em 避免多层嵌套:多层嵌套时,em 会因父元素 font-size 层层叠加导致计算复杂(如父元素 20px,子元素 1.5em,孙元素 1.5em,最终孙元素 font-size=201.51.5=45px),易超出预期;
  2. rem 避免固定基准值:仅设置 html { font-size: 16px } 无法适配不同屏幕,需结合 JS 动态计算;
  3. 基准值简化计算:设置 1rem=10px(html { font-size: 62.5% },因默认16px*62.5%=10px),可大幅降低换算成本(如设计稿32px=3.2rem)。

总结

  1. em 是“局部相对单位”:基于当前/父元素 font-size,适合局部样式微调,需注意层级继承的影响;
  2. rem 是“全局相对单位”:仅基于根元素 font-size,适配性更稳定,是移动端全局响应式的首选;
  3. 实战核心原则:全局布局用 rem 保证适配性,局部细节用 em 实现精细化控制,两者结合可兼顾灵活性与稳定性。

掌握 rem 和 em 的核心逻辑,能让你的 CSS 布局更灵活、适配更高效,告别固定像素单位的“硬编码”,真正实现“一次开发,多端适配”。

赞(0) 打赏
未经允许不得转载:陌上寒 » 前端单位深度解析:rem 与 em 的原理、区别及实战应用

评论 抢沙发

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

微信扫一扫

支付宝扫一扫