CSS 值与单位深入
绝对/相对单位、rem/em 细节、视口单位与字体相对单位的选择与换算。
0. 直觉:同样的“100”,在不同单位下含义完全不同
100px 是固定长度,100% 是父容器比例,100vw 是视口宽度,100ch 是字符宽度。单位决定“数值相对谁”,选错单位是响应式布局最常见的错误来源。
1. 绝对单位 vs 相对单位
| 类别 | 单位 | 特点 |
|---|---|---|
| 绝对 | px | 屏幕物理像素的 CSS 抽象,最可预测 |
| 绝对 | pt/cm/mm/in | 印刷单位,网页几乎不用 |
| 相对 | % | 相对父元素(宽度/高度语义不同) |
| 相对 | em/rem | 相对字号 |
| 相对 | vw/vh/vmin/vmax | 相对视口 |
| 相对 | ch/ex | 相对字体度量 |
讲解: 网页布局“默认信任 px”,需要随容器/视口/字号伸缩时才切换相对单位。
2. % 的两种语义
.child {
width: 50%; /* 相对父元素内容宽度 */
margin-top: 10%; /* 注意:上下 margin 的百分比也相对“宽度” */
}
讲解: width: 50% 相对父容器宽度;height: 50% 只有在父元素有确定高度时才有意义。而 margin/padding 的百分比(上下左右)一律相对父元素宽度,这是常见误区。
3. em 与 rem 的详细对比
html {
font-size: 16px;
}
.parent {
font-size: 20px;
}
.child-em {
font-size: 1.5em; /* 相对父级:20px * 1.5 = 30px */
}
.child-rem {
font-size: 1.5rem; /* 相对根:16px * 1.5 = 24px */
}
讲解:
rem永远相对根元素字号,层级再多也不变,适合全局字号体系;em相对最近父级字号,嵌套时会“叠加放大”,适合需要随上下文缩放的元素(如按钮内边距);- 用
em做padding时,内边距会随自身字号变化,这是实现“按钮越大、内边距越大”的常用技巧。
4. 视口单位:vw/vh/vmin/vmax
.hero {
height: 100vh; /* 一屏高 */
font-size: 5vw; /* 随视口宽度缩放 */
}
.cover {
width: 100vmin; /* 取视口宽高较小者 */
}
讲解: vw 是视口宽度的 1%,vh 是视口高度的 1%,vmin/vmax 取两者的小/大值。移动端注意地址栏伸缩会让 100vh 跳动,常改用 100dvh(动态视口)或 min-height。
5. 字体相对单位:ch/ex/cap
code {
max-width: 60ch; /* 约 60 个字符宽,代码行宽标准做法 */
}
讲解: ch 是“0”字符的宽度,ex 是“x”字母高度,cap 是大写字母高度。它们让尺寸跟随字体度量,常用于限定阅读行宽与首字下沉;中文场景 ch 约等于一个汉字宽度,做中文段落行宽同样好用。
6. 单位选择决策表
| 场景 | 推荐 | 原因 |
|---|---|---|
| 边框、阴影、圆角 | px | 不随缩放,视觉稳定 |
| 全局字号体系 | rem | 跟随根字号,方便整体缩放 |
| 组件内自缩放 | em | 随自身/父级字号联动 |
| 容器占比 | % | 跟随父容器 |
| 全屏/首屏区域 | vh/dvh | 跟随视口高度 |
| 阅读行宽 | ch | 跟随字符度量 |
| 流体字号 | clamp() + vw | 见 css/120-CSSFunctions |
7. 动手试试
- 分别用
px/em/rem给同一元素设置字号,用 DevTools Computed 面板查看最终像素值; - 给嵌套三层父级各设不同字号,对比
em与rem的叠加效果; - 用
100vh做全屏区块,在手机模拟器上观察地址栏伸缩时的跳动,再换100dvh; - 进阶挑战:给文章设置
max-width: 65ch,对比不同字号下的阅读体验。
8. 核心知识点
一句话记住值与单位:
px稳、%随容器、rem随根字号、em随父级、vw/vh随视口、ch随字符。
- 绝对单位网页只用
px,其余留给印刷; margin/padding的百分比相对宽度;rem相对根字号,em相对父级字号且会叠加;vw/vh相对视口,移动端优先dvh;ch约等于一个字符宽,适合行宽限制;- 复杂场景用
calc()/clamp()组合,见css/120-CSSFunctions。
9. 注意事项与改进建议
| 问题点 | 说明 | 改进方案 |
|---|---|---|
height: 50% 不生效 | 父元素没有确定高度 | 用 min-height 或视口单位 |
| 深层嵌套 em 失控 | 字号层层叠加 | 优先 rem,只在局部用 em |
| 移动端 100vh 跳动 | 地址栏占位变化 | 用 100dvh 或 min-height: 100dvh |
| 百分比与视口混用 | 嵌套层级变化后难预测 | 先定“相对谁”,再选单位 |
10. 扩展学习
- 函数与流体排版:
css/120-CSSFunctions; - 文本与字体基础:
css/070-TextAndFontsBasics; - 响应式设计:
css/370-ResponsiveDesign; - 移动端适配:
css/380-MobileAdaptation。