技术知识文章集合TECHNICAL ARCHIVE · 457 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTCSS

px、rem、em、vh、vw 之间的区别到底是什么?

所属馆藏
CSS
文件格式
Markdown
原始路径
CSS/17-px rem em vh vw之间的区别到底是啥?
本文目录13 个章节
  1. 一、为什么需要相对长度
  2. 二、绝对长度单位:px
  3. 三、rem:相对于根元素字体大小
  4. 四、em:相对于上下文中的字体大小
  5. 五、rem 与 em 的区别
  6. 六、em 和 rem 的使用场景
  7. 七、vh 和 vw:相对于视口
  8. 八、vh、vw 与百分比的区别
  9. 九、其他常见相对单位
  10. 十、单位选择建议
  11. 十一、常见问题
  12. 十二、总结
  13. 参考资料

pxrememvhvw 之间的区别到底是什么?

Category(分类): CSS Status: 已整理

CSS 长度单位大致可以分为绝对长度和相对长度。不同单位的关键区别不只是“大小是否固定”,还在于它们参考的对象不同:

  • px:CSS 像素;
  • rem:根元素的字体大小;
  • em:根据使用它的属性和元素的字体大小计算;
  • vhvw:视口尺寸;
  • %:参考对象由具体 CSS 属性决定。

理解参考对象,是正确使用这些单位的关键。

一、为什么需要相对长度

如果所有尺寸都使用固定的 px,在不同屏幕尺寸、字体设置和布局环境下,页面不一定能保持合适的比例。例如,缩小视口时,我们通常不仅希望盒子的宽高变化,也希望间距、字体和组件尺寸能够按照一定规则调整。

相对长度可以让尺寸与根字体、局部组件、视口或包含块建立关系,从而更容易实现响应式布局。但相对单位并不意味着所有内容都会自动适配,仍然需要结合媒体查询、容器查询、clamp()、最小/最大尺寸和内容换行策略。

二、绝对长度单位:px

1. px 是 CSS 像素

px 是 CSS 中最常用的绝对长度单位:

.box {
  width: 160px;
  height: 100px;
}

这里的 pxCSS 像素,不是屏幕上的物理像素,也不一定等于设备硬件像素。实际显示还会受到以下因素影响:

  • 设备像素比 devicePixelRatio
  • 浏览器缩放;
  • 操作系统显示缩放;
  • 用户代理和显示设备。

因此,1px 在 CSS 计算中是稳定的参考长度,但不能简单理解为显示屏上的一个物理像素点。

2. 其他绝对长度

CSS 还提供了 cmmmQinptpc 等绝对长度单位。它们在 CSS 规范中有相互换算关系,但在屏幕设备上不一定能准确对应现实中的物理长度。

在网页布局中,px 通常用于:

  • 细边框;
  • 图标尺寸;
  • 阴影偏移;
  • 精确的最小尺寸;
  • 不希望随字体或容器缩放的细节。

三、rem:相对于根元素字体大小

remroot em 的缩写,始终参考根元素的计算字体大小。根元素通常是 <html>,也可以通过 :root 选择器设置。

1. rempx 的计算关系

在常见浏览器默认设置下,根元素的字体大小通常是 16px

:root {
  font-size: 16px;
}

.box {
  width: 10rem; /* 160px */
  font-size: 1rem; /* 16px */
}

计算关系是:

实际 CSS 像素值 = rem 数值 × 根元素的计算字体大小

例如:

:root {
  font-size: 20px;
}

.box {
  width: 2rem; /* 40px */
}

但根元素的默认字体大小可能受到用户设置、浏览器设置和页面样式影响,不应把 16px 视为永远固定的值。

2. 修改 rem 的参考值

可以在根元素上设置字体大小:

html {
  font-size: 32px;
}

.box {
  width: 10rem; /* 320px */
}

也可以使用 :root

:root {
  font-size: 32px;
}

不能通过普通父元素改变某个后代的 rem 参考值。下面的 .parent 不会改变 .child 使用的 rem 基准:

html {
  font-size: 16px;
}

.parent {
  font-size: 32px;
}

.child {
  width: 2rem; /* 仍然是 32px,而不是 64px */
}

如果希望尊重用户的默认字体设置,可以使用:

html {
  font-size: 100%;
}

此时 1rem 通常等于浏览器当前的默认字体大小。

3. rem 示例

<div class="div-rem">rem</div>
html {
  font-size: 16px;
}

.div-rem {
  width: 10rem;
  height: 10rem;
  font-size: 1rem;
  background-color: #a58778;
}

rem 示例效果

使用 rem 可以让页面中的字号、间距和组件尺寸共享一个全局缩放基准:

:root {
  font-size: 16px;
}

.page {
  padding: 2rem;
}

.title {
  font-size: 1.5rem;
}

需要注意,在根元素的 font-size 声明中使用 rem 有特殊计算规则,不建议写成:

html {
  font-size: 2rem;
}

如果需要设置根字体大小,使用 px、百分比或其他明确的方式更容易理解。

四、em:相对于上下文中的字体大小

em 的参考规则需要根据使用它的属性区分。

1. 用在 font-size

em 用在元素的 font-size 声明中时,通常参考父元素的计算字体大小:

<div class="parent">
  I'm parent div set to 20px.
  <div class="child">
    I'm the child div set to 2em, i.e. 40px.
  </div>
</div>
.parent {
  font-size: 20px;
}

.child {
  font-size: 2em; /* 2 × 20px = 40px */
}

em 字体大小示例

如果父元素没有显式设置字体大小,就会使用继承链上得到的计算值;如果祖先都没有修改,通常会接近浏览器的默认字体大小。

2. 用在其他属性中

对于 widthheightpaddingmargin 和多数边框宽度等属性,em 通常参考当前元素的计算字体大小:

.box {
  font-size: 20px;
  width: 10em; /* 200px */
  padding: 2em; /* 40px */
  border-width: 0.1em; /* 2px */
}

因此,不能笼统地说 em 永远等于父元素的字体大小。

3. 元素自身设置字体大小的情况

.div-em {
  font-size: 32px;
  width: 10em;  /* 320px,width 使用当前元素字体大小 */
  height: 10em; /* 320px */
  background-color: aquamarine;
}

但对于下面的 font-size 声明,2em 仍然参考父元素的字体大小,而不是当前元素未来的字体大小:

.child {
  font-size: 2em;
}

rem 与嵌套元素示例

这是因为计算 font-size 时,当前元素的字体大小还没有确定。

4. 嵌套继承会产生累积效果

.grandparent {
  font-size: 20px;
}

.parent {
  font-size: 1.5em; /* 30px */
}

.child {
  font-size: 2em; /* 60px */
}

em 的灵活性很高,但深层嵌套时计算链可能变得复杂,需要注意实际的计算字体大小。

五、remem 的区别

单位主要参考对象常见特点
rem根元素的计算字体大小全局统一,嵌套层级不会改变基准
em 用于 font-size父元素的计算字体大小会沿继承关系累积
em 用于多数其他属性当前元素的计算字体大小适合组件内部按字号缩放

一个常见误解是“rem 继承父元素”。实际上,font-size 属性本身可以继承,但 rem 的参考基准始终是根元素。

六、emrem 的使用场景

1. 适合使用 rem 的场景

rem 适合全局设计令牌和页面级尺寸:

:root {
  font-size: 100%;
}

.page {
  padding: 2rem;
}

.heading {
  font-size: 2rem;
}

常见用途包括:

  • 页面级字号;
  • 全局间距;
  • 设计系统中的尺寸令牌;
  • 希望统一缩放的组件尺寸。

2. 适合使用 em 的场景

em 适合组件内部与自身字体大小建立比例:

.button {
  font-size: 1rem;
  padding: 0.75em 1.25em;
  border-radius: 0.5em;
}

.button--large {
  font-size: 1.25rem;
}

改变按钮字号时,内边距和圆角也会按组件自身的字体大小一起变化。

3. 不要为了“响应式”大量修改根字号

过去常见的做法是根据视口宽度用 JavaScript 或复杂公式不断修改 htmlfont-size。现代 CSS 通常可以使用:

.title {
  font-size: clamp(1.5rem, 1rem + 2vw, 3rem);
}

clamp(min, preferred, max) 可以在范围内平滑缩放,同时设置最小值和最大值,通常比无上限地修改根字体大小更容易维护。

七、vhvw:相对于视口

vhvw 的参考对象是视口(viewport),不是父元素:

  • 1vh:视口高度的 1%;
  • 1vw:视口宽度的 1%;
  • 100vh:传统意义上视口高度的 100%;
  • 100vw:视口宽度的 100%。

示例:

.viewport-box {
  width: 10vw;  /* 视口宽度的 1/10 */
  height: 10vh; /* 视口高度的 1/10 */
  background-color: pink;
}

移动端视口高度

移动端浏览器的地址栏、工具栏会展开和收起,传统 100vh 在不同浏览器或不同状态下可能无法准确表示当前可见区域。现代 CSS 提供了三组视口尺寸单位:

  • svh:小视口高度;
  • lvh:大视口高度;
  • dvh:动态视口高度。

例如:

.page {
  min-height: 100dvh;
}

如果页面需要避免浏览器 UI 覆盖,应该根据实际交互选择 svhlvhdvh,必要时再结合安全区域:

.page {
  min-height: 100dvh;
  padding-bottom: env(safe-area-inset-bottom);
}

100vw 与滚动条

在部分浏览器中,100vw 可能包含垂直滚动条占用的区域,从而造成轻微横向溢出。需要填充普通内容区域时,通常可以使用:

.full-width {
  width: 100%;
}

八、vhvw 与百分比的区别

百分比的参考对象由具体 CSS 属性决定;vhvw 则参考视口。

<div class="parent">
  <div class="percentage-child"></div>
</div>

<div class="viewport-box"></div>
.parent {
  width: 400px;
  height: 200px;
  background-color: #f5f5f5;
}

.percentage-child {
  width: 50%;
  height: 50%;
  background-color: aliceblue;
}

.viewport-box {
  width: 50vw;
  height: 50vh;
  background-color: pink;
}

在这个例子中:

  • .percentage-child 的宽高参考包含块的宽高;
  • .viewport-box 的宽高参考视口宽高;
  • 如果百分比高度的包含块高度不确定,height: 50% 可能无法得到预期的固定结果。

但“百分比总是参考父元素”也不准确。例如:

  • width 百分比通常参考包含块宽度;
  • height 百分比需要包含块有确定高度;
  • paddingmargin 的百分比通常参考包含块的宽度;
  • font-size 百分比参考父元素字体大小。

九、其他常见相对单位

1. vminvmax

.square {
  width: 50vmin;
  height: 50vmin;
}
  • vmin:视口宽度和高度中较小值的 1%;
  • vmax:视口宽度和高度中较大值的 1%。

它们适合创建始终基于视口短边或长边缩放的图形。

2. chex

  • ch 大致参考当前字体中字符 0 的 advance measure,适合控制文本行宽;
  • ex 参考当前字体的 x-height,实际值依字体而异。

例如:

.article {
  max-width: 70ch;
}

ch 不是严格的“一个汉字宽度”,不同字体、字符和语言环境下都会有差异。

十、单位选择建议

场景常见选择说明
细边框、图标细节px需要稳定的 CSS 像素尺寸
页面级字号和间距rem统一参考根元素字体大小
组件内部间距em随组件字体大小一起缩放
视口相关布局vwvhdvh参考视口,移动端要考虑动态视口
相对于容器的尺寸%参考对象取决于具体属性
文本阅读宽度chrem应结合实际字体和内容测试
有上下限的流式尺寸clamp() 与相对单位避免尺寸无限缩放

不要把某一种单位当成所有场景的固定答案。网页还需要考虑内容长度、用户字体设置、浏览器缩放、可访问性和最小/最大尺寸。

十一、常见问题

1. 为什么设置 height: 100% 没有效果?

因为百分比高度通常需要包含块具有确定的高度:

html,
body {
  height: 100%;
}

.page {
  height: 100%;
}

如果祖先高度都是 auto,子元素的百分比高度可能无法按预期解析。

2. 为什么 em 嵌套后越来越大?

因为 font-size 中的 em 会参考父元素字体大小,多个嵌套层级会产生累积:

.parent {
  font-size: 1.5em;
}

.child {
  font-size: 1.5em;
}

组件内部需要稳定基准时,可以使用 rem,或者在组件根节点明确设置 font-size

3. 为什么 100vw 会产生横向滚动?

可能是 100vw 包含了垂直滚动条宽度,也可能是元素同时存在边距、边框或自身宽度计算超出容器。可以检查:

* {
  box-sizing: border-box;
}

并在普通内容区域优先使用 width: 100%

4. 相对单位会带来性能问题吗?

正常使用 emremvhvw 不应被简单归因于性能问题。更需要关注的是:

  • 是否造成频繁的布局变化;
  • 是否在 JavaScript 中高频修改样式;
  • 是否产生大量复杂的嵌套计算;
  • 是否因为内容溢出触发不必要的滚动和重排。

十二、总结

  • px 是 CSS 像素,不等于设备物理像素;
  • rem 始终参考根元素的计算字体大小;
  • emfont-size 中通常参考父元素,在多数其他属性中通常参考当前元素的字体大小;
  • vhvw 参考视口,不参考普通父元素;
  • 移动端全屏布局应根据情况使用 svhlvhdvh
  • 百分比的参考对象取决于具体属性,不能统一理解为父元素尺寸;
  • rem 适合全局设计令牌,em 适合组件内部缩放;
  • clamp() 可以限制流式尺寸的上下限;
  • 单位选择应同时考虑响应式布局、内容、用户设置和可访问性。

参考资料

457 DOCUMENTS · 10 COLLECTIONS
ARCHIVE SEARCH457 篇文章

SEARCH GUIDE

输入关键词开始搜索

支持搜索文章标题、所属分类和原始文档路径。

按分类浏览

10 COLLECTIONS