
px vs rem vs em vs vh:该用哪种CSS单位?完整指南
📷 Negative Space / Pexelspx vs rem vs em vs vh:该用哪种CSS单位?完整指南
CSS有15种以上的长度单位,大多数开发者用错了。这里是在响应式、可访问设计中何时使用每种单位的清晰指南。
简介:为什么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) - 间距和内边距(改用
rem或em) - 布局宽度(使用百分比、
fr或视口单位) - 任何应响应用户字体大小偏好的内容
其他绝对单位
| 单位 | 描述 | 换算 | 用途 |
|---|---|---|---|
px | 像素 | 1px | 屏幕元素 |
cm | 厘米 | 37.8px | 打印样式表 |
mm | 毫米 | 3.78px | 打印样式表 |
in | 英寸 | 96px | 打印样式表 |
pt | 点 | 1.33px(1/72英寸) | 打印样式表 |
pc | 派卡 | 16px(1/6英寸) | 打印样式表 |
注意: 物理单位(cm、mm、in、pt、pc)只在打印样式表中有意义。在屏幕上,它们只是使用标准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 是大多数场景最佳选择的原因:
- 尊重用户偏好:如果用户将浏览器字体大小设为20px(出于可访问性需要),所有基于
rem的值都会按比例缩放 - 一致性:与
em不同,rem始终引用根元素,因此没有复合效果 - 可预测:计算简单——如果根是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
| 方面 | rem | em |
|---|---|---|
| 参考基准 | 根元素字体大小 | 父/自身字体大小 |
| 复合效果 | 无 | 有 |
| 可预测性 | 高 | 低(取决于上下文) |
| 最适用于 | 字体大小、间距、布局 | 组件级比例缩放 |
| 可访问性 | 尊重根字体大小设置 | 尊重父字体大小 |
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 | 大写字母高度 | 与大写文本对齐 |
ic | CJK"水"字的宽度 | 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: 希望高度随地址栏动画时
同样适用于宽度单位:svw、lvw、dvw。
vi和vb(视口内联和块方向)
这些单位具有书写模式意识:
vi= 内联方向的视口大小(水平文本为宽度,垂直文本为高度)vb= 块方向的视口大小(水平文本为高度,垂直文本为宽度)
/* 书写模式感知布局 */
.container {
max-inline-size: 90vi; /* 内联方向视口的90% */
margin-block: 5vb; /* 块方向视口的5% */
}
vmin和vmax
vmin=vw和vh中较小的一个vmax=vw和vh中较大的一个
/* 适合任何视口的正方形元素 */
.square {
width: 50vmin;
height: 50vmin;
}
/* 在纵向和横向都能良好缩放的排版 */
h1 {
font-size: 8vmin; /* 竖屏和横屏都有效 */
}
视口单位比较
| 单位 | 描述 | 移动端地址栏 |
|---|---|---|
vw | 视口宽度的1% | 不受影响 |
vh | 视口高度的1% | 使用大视口 |
svh | 小视口高度的1% | 始终安全 |
lvh | 大视口高度的1% | 最大高度 |
dvh | 动态视口高度的1% | 随地址栏动画 |
vmin | vw/vh中较小的 | 从vh继承 |
vmax | vw/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% |
cqmin | cqi和cqb中较小的 |
cqmax | cqi和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 | 考虑移动端地址栏 |
| 媒体查询断点 | px 或 em | 一致的触发点 |
| 圆角 | rem 或 px | 均可;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开发各个方面的基础主题——布局、排版、可访问性和响应式设计。关键洞察是没有单一的"最佳"单位;正确的选择取决于上下文。
关键要点:
- 以
rem为默认 — 用于字体大小、间距和大多数测量 - 精细细节使用
px— 边框、盒阴影和轮廓 - Grid布局使用
fr— 按比例分配空间 - 全高移动端布局用
dvh代替vh - 行长使用
ch— 优化可读性 - 响应式值使用
clamp()— 带最小和最大约束 - 谨慎使用
em— 用于比例组件缩放(如按钮内边距) - 始终考虑可访问性 — 选择尊重用户偏好的单位
掌握CSS单位需要实践,但原则很清晰:优先选择相对单位而非绝对单位,思考你的设计如何响应不同上下文,并始终考虑可访问性。
在开发工作流中快速进行单位转换,请试试我们的单位转换器工具。CSS颜色值可以使用颜色选择器,其他Web开发任务可以使用我们的CSS相关开发者工具。
相关资源
- 单位转换器 -- 在不同单位之间转换
- 颜色选择器 -- 选取和转换CSS颜色
- Web开发趋势2026 -- 现代CSS及更多
- JSON格式化器 -- 格式化设计令牌和CSS配置
- 正则表达式测试器 -- 测试CSS相关的正则表达式模式