ToolPal
展示笔记本电脑、平板和智能手机的现代工作空间,适合科技和自由职业使用。

px vs rem vs em vs vh:该用哪种CSS单位?完整指南

📷 Negative Space / Pexels

px vs rem vs em vs vh:该用哪种CSS单位?完整指南

CSS有15种以上的长度单位,大多数开发者用错了。这里是在响应式、可访问设计中何时使用每种单位的清晰指南。

D作者: Daniel Park2026年3月2日10分钟阅读

简介:为什么CSS单位很重要

CSS单位决定了网页上每个元素的大小——从字体大小和间距到布局尺寸和动画。为不同场景选择正确的单位是响应式、可访问网页设计中最重要的决策之一。

使用错误的单位会导致布局在不同屏幕尺寸上崩溃、移动端文字太小无法阅读,以及设计不尊重用户的可访问性偏好。使用正确的单位能创建灵活、响应式的界面,优雅地适配任何设备并尊重用户设置。

本指南涵盖2026年你需要了解的每一种CSS单位,并提供何时以及如何使用每种单位的实用建议。如果需要在不同度量单位之间转换,请试试我们的单位转换器工具。

绝对单位

绝对单位代表固定的测量值。它们不会因父元素、视口或用户设置而改变。

像素(px)

像素是Web开发中最常用的绝对单位。一个CSS像素在标准密度显示器上对应一个设备像素,但在高DPI(视网膜)显示器上,一个CSS像素可能映射到多个设备像素。

.box {
  width: 300px;
  height: 200px;
  border: 1px solid #333;
  padding: 16px;
}

何时使用像素:

  • 边框和轮廓(border: 1px solid black
  • 盒阴影(box-shadow: 0 2px 4px rgba(0,0,0,0.1)
  • 不应缩放的精细视觉细节
  • 媒体查询断点(@media (min-width: 768px)
  • 图标等固定大小元素

何时不使用像素:

  • 字体大小(改用 rem
  • 间距和内边距(改用 remem
  • 布局宽度(使用百分比、fr 或视口单位)
  • 任何应响应用户字体大小偏好的内容

其他绝对单位

单位描述换算用途
px像素1px屏幕元素
cm厘米37.8px打印样式表
mm毫米3.78px打印样式表
in英寸96px打印样式表
pt1.33px(1/72英寸)打印样式表
pc派卡16px(1/6英寸)打印样式表

注意: 物理单位(cmmminptpc)只在打印样式表中有意义。在屏幕上,它们只是使用标准96 DPI比率转换为像素。

/* 使用物理单位的打印样式表 */
@media print {
  body {
    font-size: 12pt;
    margin: 1in;
  }

  h1 {
    font-size: 18pt;
    margin-bottom: 0.5cm;
  }
}

相对单位:基于字体

相对单位根据另一个值计算——父元素的字体大小、根字体大小或视口尺寸。它们是响应式设计的基础。

rem(根em)

rem 代表"根em",相对于根元素(<html>)的字体大小。默认情况下,浏览器将根字体大小设为16px,所以 1rem = 16px

html {
  font-size: 16px; /* 这是浏览器默认值 */
}

h1 {
  font-size: 2rem;    /* 32px */
  margin-bottom: 1rem; /* 16px */
}

p {
  font-size: 1rem;     /* 16px */
  line-height: 1.5rem; /* 24px */
  margin-bottom: 1rem; /* 16px */
}

.card {
  padding: 1.5rem;     /* 24px */
  border-radius: 0.5rem; /* 8px */
}

rem 是大多数场景最佳选择的原因:

  1. 尊重用户偏好:如果用户将浏览器字体大小设为20px(出于可访问性需要),所有基于 rem 的值都会按比例缩放
  2. 一致性:与 em 不同,rem 始终引用根元素,因此没有复合效果
  3. 可预测:计算简单——如果根是16px,1.5rem 始终是24px

62.5%技巧(谨慎使用):

/* 让rem计算更简单:1rem = 10px */
html {
  font-size: 62.5%; /* 16px的62.5% = 10px */
}

body {
  font-size: 1.6rem; /* 恢复到16px等效值 */
}

h1 {
  font-size: 3.2rem; /* 32px */
}

.spacing {
  padding: 2.4rem;   /* 24px */
}

这种技术使计算更简单,但可能与假定默认根字体大小的第三方组件发生冲突。请谨慎使用。

em(相对于父元素)

em 对于字体相关属性相对于元素自身的字体大小,对于其他属性相对于父元素的字体大小。这使它对组件级缩放很有用,但由于复合效果可能比较棘手。

.parent {
  font-size: 18px;
}

.child {
  font-size: 1.2em;  /* 18px * 1.2 = 21.6px */
  padding: 1em;      /* 21.6px(相对于自身字体大小) */
}

.grandchild {
  font-size: 1.2em;  /* 21.6px * 1.2 = 25.92px -- 复合效果! */
}

复合问题:

/* 每个嵌套级别字体都变大 */
ul { font-size: 1.1em; }

/*
  第1级: 16px * 1.1 = 17.6px
  第2级: 17.6px * 1.1 = 19.36px
  第3级: 19.36px * 1.1 = 21.3px
  第4级: 21.3px * 1.1 = 23.4px
  -- 嵌套越深文字越大!
*/

em 真正有用的场景:

当你希望间距随元素自身字体大小缩放时,em 非常出色。对于按钮和内联组件特别有用:

/* 按比例缩放的按钮 */
.button {
  font-size: 1rem;       /* 来自根的基础大小 */
  padding: 0.5em 1em;    /* 随字体大小缩放 */
  border-radius: 0.25em; /* 随字体大小缩放 */
}

.button--large {
  font-size: 1.25rem;    /* 其他一切自动缩放 */
}

.button--small {
  font-size: 0.875rem;   /* 内边距和圆角也缩小 */
}

比较:rem vs. em

方面remem
参考基准根元素字体大小父/自身字体大小
复合效果
可预测性低(取决于上下文)
最适用于字体大小、间距、布局组件级比例缩放
可访问性尊重根字体大小设置尊重父字体大小

ch(字符宽度)

ch 等于当前字体中"0"(零)字符的宽度。它对于将文本宽度限制在可读的行长度很有用。

/* 最佳阅读宽度 */
.article-content {
  max-width: 65ch;  /* 每行约65个字符 */
  margin: 0 auto;
}

/* 根据预期内容调整的输入字段 */
.zip-code-input {
  width: 6ch;  /* 足够容纳5位数+一些空间 */
}

.phone-input {
  width: 15ch;
}

ch 对可读性的重要性: 研究表明,最佳阅读行长为45-75个字符。使用 ch 单位无论字体大小如何都能轻松实现这一目标。

ex(x高度)

ex 等于当前字体中小写"x"字符的高度。虽然很少直接使用,但对于精确的垂直对齐很有用。

/* 将图标与文本垂直居中 */
.icon-inline {
  height: 1ex;
  vertical-align: middle;
}

lh和rlh(行高单位)

lh 等于元素的计算 line-height,而 rlh 等于根元素的行高。

/* 按行高的倍数间隔元素 */
.paragraph {
  margin-bottom: 1lh; /* 一行的间距 */
}

.section {
  margin-bottom: 2rlh; /* 两个根行高的间距 */
}

cap、ic和其他高级单位

单位描述用途
cap大写字母高度与大写文本对齐
icCJK"水"字的宽度CJK排版
lh元素的行高垂直节奏
rlh根行高一致的垂直间距

视口单位

视口单位相对于浏览器视口(网页的可见区域)。

vw和vh(视口宽度和高度)

/* 全屏英雄区 */
.hero {
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 响应式排版 */
h1 {
  font-size: 5vw; /* 随视口宽度缩放 */
}

重要: 移动端浏览器上的 100vh 不考虑浏览器的地址栏和导航栏。这促使了新视口单位的创建。

移动端视口问题

在移动端浏览器上,滚动时地址栏显示和隐藏会导致视口高度变化。旧的 vh 单位基于最大视口(地址栏隐藏),当地址栏可见时会导致内容被裁剪。

dvh、svh、lvh(动态、小和大视口高度)

CSS现在提供三种变体来处理移动端视口:

/* svh: 小视口高度(地址栏可见) */
.safe-full-height {
  height: 100svh; /* 永远不会被地址栏遮挡 */
}

/* lvh: 大视口高度(地址栏隐藏) */
.max-full-height {
  height: 100lvh; /* 地址栏隐藏时的最大高度 */
}

/* dvh: 动态视口高度(随地址栏显隐变化) */
.dynamic-full-height {
  height: 100dvh; /* 实时调整 */
}

如何选择:

  • svh: 安全默认值——内容始终完全可见
  • lvh: 需要最大可能高度时
  • dvh: 希望高度随地址栏动画时

同样适用于宽度单位:svwlvwdvw

vi和vb(视口内联和块方向)

这些单位具有书写模式意识:

  • vi = 内联方向的视口大小(水平文本为宽度,垂直文本为高度)
  • vb = 块方向的视口大小(水平文本为高度,垂直文本为宽度)
/* 书写模式感知布局 */
.container {
  max-inline-size: 90vi;   /* 内联方向视口的90% */
  margin-block: 5vb;        /* 块方向视口的5% */
}

vmin和vmax

  • vmin = vwvh 中较小的一个
  • vmax = vwvh 中较大的一个
/* 适合任何视口的正方形元素 */
.square {
  width: 50vmin;
  height: 50vmin;
}

/* 在纵向和横向都能良好缩放的排版 */
h1 {
  font-size: 8vmin; /* 竖屏和横屏都有效 */
}

视口单位比较

单位描述移动端地址栏
vw视口宽度的1%不受影响
vh视口高度的1%使用大视口
svh小视口高度的1%始终安全
lvh大视口高度的1%最大高度
dvh动态视口高度的1%随地址栏动画
vminvw/vh中较小的从vh继承
vmaxvw/vh中较大的从vh继承

百分比(%)

百分比相对于父元素的对应属性。参考值会根据你设置的属性而变化。

.parent {
  width: 800px;
  font-size: 20px;
  line-height: 1.5;
}

.child {
  width: 50%;        /* 400px(父宽度的50%) */
  margin-left: 10%;  /* 80px(父宽度的10%) */
  font-size: 80%;    /* 16px(父字体大小的80%) */
  padding: 5%;       /* 40px(父宽度的5%,不是高度!) */
}

重要陷阱: 垂直内边距和外边距的百分比是基于父元素的宽度计算的,而不是高度。这对于创建宽高比盒子实际上很有用(尽管现在推荐使用 aspect-ratio 属性)。

/* 使用百分比内边距的旧宽高比技巧 */
.video-container {
  position: relative;
  width: 100%;
  padding-bottom: 56.25%; /* 16:9宽高比 */
}

/* 现代方法 */
.video-container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

容器查询单位

容器查询单位相对于查询容器的大小,实现真正的基于组件的响应式设计。

cqw、cqh、cqi、cqb、cqmin、cqmax

.card-container {
  container-type: inline-size;
  container-name: card;
}

.card-title {
  font-size: clamp(1rem, 4cqi, 2rem); /* 随容器内联大小缩放 */
}

.card-description {
  font-size: clamp(0.875rem, 3cqi, 1.125rem);
}
单位描述
cqw容器宽度的1%
cqh容器高度的1%
cqi容器内联大小的1%
cqb容器块大小的1%
cqmincqi和cqb中较小的
cqmaxcqi和cqb中较大的

fr单位(分数)

fr 单位专门用于CSS Grid中按比例分配可用空间。

.grid {
  display: grid;

  /* 三列:1份、2份、1份 */
  grid-template-columns: 1fr 2fr 1fr;
  /* 1200px容器中:300px、600px、300px */

  /* 混合单位:固定侧边栏、弹性内容 */
  grid-template-columns: 250px 1fr;

  /* 多行 */
  grid-template-rows: auto 1fr auto;
  /* 页眉、弹性内容区、页脚 */

  gap: 1rem;
}
/* 使用fr单位的响应式网格 */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1.5rem;
}

Grid中 fr vs 百分比:

/* 这些看起来相似但行为不同 */
.grid-percent {
  grid-template-columns: 25% 50% 25%;
  gap: 1rem;
  /* 列+间距 > 100%,导致溢出! */
}

.grid-fr {
  grid-template-columns: 1fr 2fr 1fr;
  gap: 1rem;
  /* fr单位自动计算间距 */
}

带单位的CSS函数

clamp() - 带约束的响应式值

clamp() 是响应式设计中最强大的CSS函数之一。它接受三个值:最小值、首选值和最大值。

/* 不会太小也不会太大的响应式字体大小 */
h1 {
  font-size: clamp(1.5rem, 4vw, 3rem);
  /* 最小值:1.5rem (24px)
     首选值:4vw(随视口缩放)
     最大值:3rem (48px) */
}

/* 响应式容器宽度 */
.container {
  width: clamp(320px, 90%, 1200px);
}

/* 响应式间距 */
section {
  padding: clamp(1rem, 5vw, 4rem);
}

min() 和 max()

/* 宽度取90%和1200px中较小的 */
.container {
  width: min(90%, 1200px);
}

/* 至少300px宽,但可以增长 */
.sidebar {
  width: max(300px, 25%);
}

/* 组合用于复杂的响应式值 */
.card {
  width: min(100% - 2rem, 600px);
  padding: max(1rem, 2vw);
}

calc() - 跨单位计算

calc() 允许你在计算中混合不同单位:

.sidebar-layout {
  /* 全宽减去侧边栏 */
  .main-content {
    width: calc(100% - 280px);
  }

  /* 带最大宽度和自动边距的居中 */
  .content {
    width: calc(100% - 2 * 1.5rem);
    max-width: 800px;
    margin: 0 auto;
  }
}

/* 使用calc的流式排版 */
h1 {
  /* 基础大小 + 缩放因子 */
  font-size: calc(1.5rem + 1.5vw);
}

/* 带最小值的基于视口的间距 */
.hero {
  padding-top: calc(2rem + 5vh);
  padding-bottom: calc(2rem + 5vh);
}

实用建议:什么场景用什么单位

字体大小

/* 根字体大小:使用百分比或px */
html {
  font-size: 100%; /* 尊重用户浏览器设置 */
}

/* 所有其他字体大小:使用rem */
body { font-size: 1rem; }       /* 16px */
h1 { font-size: 2.5rem; }      /* 40px */
h2 { font-size: 2rem; }        /* 32px */
h3 { font-size: 1.5rem; }      /* 24px */
small { font-size: 0.875rem; } /* 14px */

/* 响应式字体大小:使用带rem和vw的clamp */
h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
}

间距(内边距、外边距、间隙)

/* 使用rem实现一致的间距 */
.card {
  padding: 1.5rem;
  margin-bottom: 2rem;
}

.grid {
  gap: 1.5rem;
}

/* 使用em实现随字体大小缩放的间距 */
.button {
  padding: 0.5em 1em;
}

布局宽度

/* 使用百分比、fr或视口单位 */
.container {
  width: min(90%, 1200px);
  margin: 0 auto;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

/* 全出血区块 */
.hero {
  width: 100vw;
  margin-left: calc(-50vw + 50%);
}

边框和阴影

/* 使用px表示精细视觉细节 */
.card {
  border: 1px solid #e0e0e0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  border-radius: 0.5rem; /* border-radius用rem也可以 */
}

媒体查询

/* 断点使用px或em */
@media (min-width: 768px) {
  /* 平板及以上 */
}

@media (min-width: 1024px) {
  /* 桌面及以上 */
}

/* 基于em的断点尊重用户缩放 */
@media (min-width: 48em) {
  /* 48em = 默认字体大小下的768px */
}

完整推荐表

用途推荐单位理由
字体大小rem尊重用户偏好,无复合效果
响应式字体大小clamp(rem, vw, rem)带约束的平滑缩放
间距(内边距、外边距)rem一致,随根字体缩放
按钮内边距em随按钮自身字体大小缩放
容器宽度%min()clamp()灵活且响应式
网格列fr按比例分配空间
行长ch优化可读性
边框px精细细节,不应缩放
盒阴影px精细细节,一致的外观
全屏区块dvh考虑移动端地址栏
媒体查询断点pxem一致的触发点
圆角rempx均可;rem 略微缩放

可访问性与CSS单位

选择正确的CSS单位与可访问性直接相关。

尊重用户字体大小设置

用户可能会增大浏览器默认字体大小以提高可读性。对字体大小和间距使用 rem 可以尊重这一偏好:

/* 好:随用户字体大小偏好缩放 */
body { font-size: 1rem; }
h1 { font-size: 2.5rem; }
.container { padding: 1.5rem; }

/* 差:忽略用户偏好 */
body { font-size: 16px; }
h1 { font-size: 40px; }
.container { padding: 24px; }

缩放支持

用户应该能够缩放到200%而不出现水平滚动(WCAG 2.1成功标准1.4.10):

/* 好:在任何缩放级别都响应 */
.content {
  max-width: min(90%, 65ch);
  margin: 0 auto;
  padding: 1.5rem;
}

/* 差:固定宽度在高缩放下崩溃 */
.content {
  width: 960px;
  margin: 0 auto;
  padding: 24px;
}

触摸目标

交互元素应至少为44x44 CSS像素(WCAG 2.5.5):

.button {
  min-height: 2.75rem; /* 44px */
  min-width: 2.75rem;
  padding: 0.75rem 1.5rem;
}

/* 确保触摸目标之间有足够间距 */
.nav-list li + li {
  margin-top: 0.5rem;
}

常见错误及如何避免

错误1:字体大小使用px

/* 差:不随用户偏好缩放 */
body { font-size: 16px; }
h1 { font-size: 32px; }

/* 好:随用户偏好缩放 */
body { font-size: 1rem; }
h1 { font-size: 2rem; }

错误2:移动端全高布局使用vh

/* 差:被移动端地址栏遮挡 */
.mobile-layout { height: 100vh; }

/* 好:考虑移动端地址栏 */
.mobile-layout { height: 100dvh; }

/* 最安全:对旧浏览器提供回退 */
.mobile-layout {
  height: 100vh;
  height: 100dvh;
}

错误3:em值复合

/* 差:字体大小随嵌套增大 */
li { font-size: 1.1em; }

/* 好:无论嵌套如何都保持一致 */
li { font-size: 1.1rem; }

错误4:无约束地使用vw设置字体大小

/* 差:移动端太小,桌面端太大 */
h1 { font-size: 5vw; }

/* 好:用clamp约束 */
h1 { font-size: clamp(1.5rem, 5vw, 3rem); }

错误5:百分比内边距的混淆

/* 意外:垂直内边距基于宽度 */
.box {
  padding-top: 10%;    /* 父宽度的10%,不是高度! */
  padding-bottom: 10%; /* 同样基于宽度 */
}

现代框架中的CSS单位

Tailwind CSS

Tailwind使用基于 rem 的间距比例:

{/*  Tailwind间距:1单位 = 0.25rem = 4px */}
<div class="p-4 m-6 text-lg">
  {/*  p-4 = padding: 1rem (16px) */}
  {/*  m-6 = margin: 1.5rem (24px) */}
  {/*  text-lg = font-size: 1.125rem (18px) */}
</div>

CSS模块 / CSS-in-JS

// Styled Components / Emotion
const Card = styled.div`
  padding: 1.5rem;
  margin-bottom: 2rem;
  font-size: 1rem;
  border: 1px solid #e0e0e0;
  border-radius: 0.5rem;
  max-width: min(100%, 600px);
`;

结论

CSS单位是影响Web开发各个方面的基础主题——布局、排版、可访问性和响应式设计。关键洞察是没有单一的"最佳"单位;正确的选择取决于上下文。

关键要点:

  1. rem 为默认 — 用于字体大小、间距和大多数测量
  2. 精细细节使用 px — 边框、盒阴影和轮廓
  3. Grid布局使用 fr — 按比例分配空间
  4. 全高移动端布局用 dvh 代替 vh
  5. 行长使用 ch — 优化可读性
  6. 响应式值使用 clamp() — 带最小和最大约束
  7. 谨慎使用 em — 用于比例组件缩放(如按钮内边距)
  8. 始终考虑可访问性 — 选择尊重用户偏好的单位

掌握CSS单位需要实践,但原则很清晰:优先选择相对单位而非绝对单位,思考你的设计如何响应不同上下文,并始终考虑可访问性。

在开发工作流中快速进行单位转换,请试试我们的单位转换器工具。CSS颜色值可以使用颜色选择器,其他Web开发任务可以使用我们的CSS相关开发者工具

相关资源

常见问题

D

关于作者

Daniel Park

Senior frontend engineer based in Seoul. Seven years of experience building web applications at Korean SaaS companies, with a focus on developer tooling, web performance, and privacy-first architecture. Open-source contributor to the JavaScript ecosystem and founder of ToolPal.

了解更多

分享文章

XLinkedIn

相关文章