
CSS 单位:px、em、rem、vw 及何时使用
使用错误的 CSS 单位会导致布局在不同屏幕上出错,或忽略用户的可访问性设置。以下是一份实用指南。

px — 绝对单位
固定大小。在标准屏幕上,1px = 1 CSS 像素。
.card {
border: 1px solid #ddd; /* ✅ 始终用 px */
border-radius: 8px; /* ✅ 始终用 px */
box-shadow: 0 2px 8px rgba(0,0,0,0.1); /* ✅ px */
}
用于: 边框、阴影、固定图标。避免用于: 字体大小——px 忽略用户的浏览器字体偏好。
em — 相对于父元素字体大小
嵌套时会复合——每个子元素乘以父元素。
.parent { font-size: 20px; }
.child { font-size: 0.8em; padding: 1em; }
/* child font-size = 16px, padding = 16px */
/* 复合问题: */
.level-1 { font-size: 1.2em; } /* 19.2px */
.level-2 { font-size: 1.2em; } /* 23px */
.level-3 { font-size: 1.2em; } /* 27.6px — 非预期! */
用于: 组件内部间距(padding/margin),应随组件字体缩放。避免用于: 全局字体大小。
rem — 相对于根元素(推荐用于排版)
始终相对于 html 字体大小。不会复合。
html { font-size: 16px; } /* 浏览器默认 */
h1 { font-size: 2rem; } /* 32px */
p { font-size: 1rem; } /* 16px */
.container { max-width: 60rem; } /* 960px */
可访问性优势: 如果用户将浏览器字体设为 20px,基于 rem 的布局会按比例缩放。基于 px 的布局会忽略此偏好。
用于: 字体大小、全局间距、最大宽度——任何应尊重用户偏好的属性。

vw / vh — 视口单位
.hero { min-height: 100vh; }
h1 { font-size: clamp(1.75rem, 4vw, 3rem); } /* 流体缩放 */
移动端 vh 问题: 100vh 包含浏览器地址栏。使用现代替代方案:
.hero { height: 100svh; } /* 小视口 — 稳定 */
.modal { height: 100dvh; } /* 动态 — 随地址栏显示/隐藏更新 */
用于: 全屏区块、模态框、配合 clamp() 实现流体排版。
% — 相对于父元素
.parent { width: 800px; }
.child { width: 50%; } /* 400px */
要使 height % 生效,父元素必须有显式高度。
ch — 字符宽度
input { width: 30ch; } /* 容纳约 30 个字符 */
article { max-width: 65ch; } /* 最佳阅读行宽 */

clamp() — 最小/最大缩放
h1 { font-size: clamp(1.75rem, 2.5vw + 1rem, 3.5rem); }
.section { padding: clamp(1rem, 5vw, 4rem); }
快速参考
| 单位 | 相对于 | 最佳用途 |
|---|---|---|
| px | 绝对 | 边框、阴影、图标 |
| em | 父元素字体大小 | 组件内部间距 |
| rem | 根元素字体大小 | 排版、全局布局 |
| % | 父元素尺寸 | 流体宽度 |
| vw/vh | 视口 | 全屏、流体排版 |
| ch | 字符宽度 | 输入框、行宽 |
| svh/dvh | 视口(移动端安全) | 移动端全高区块 |
推荐模式
/* 排版:rem */
body { font-size: 1rem; }
h1 { font-size: clamp(1.75rem, 4vw, 3rem); }
/* 布局:rem */
.container { max-width: 75rem; padding: 0 1rem; }
/* 组件:em 用于内部间距 */
.button { padding: 0.75em 1.5em; }
/* 边框:px */
.card { border: 1px solid #ddd; }
/* 全屏:svh */
.hero { min-height: 100svh; }
→ 使用 CSS 单位转换器 即时转换 CSS 单位。