· 3 min read
CSS :rem、em、px 怎么选
CSS
有没有遇到过这种情况?在小屏幕上字体看起来正好,放到大屏幕上却大得吓人。或者改了根字体大小,整个页面布局全乱了。这些问题都和 CSS 单位的选择有关。CSS 单位看似简单,用错地方会让响应式设计变得痛苦。
TLDR
| 场景 | 推荐 |
|---|---|
| 字体大小 | rem |
| 布局宽度 | %、vw |
| 间距(margin/padding) | rem / em |
| 边框、阴影 | px |
| 全屏hero区 | vh |
相对单位:rem vs em
rem:相对于根元素
html {
font-size: 16px; /* 默认值 */
}
h1 {
font-size: 2rem; /* 2 * 16px = 32px */
}
p {
font-size: 1rem; /* 1 * 16px = 16px */
}
为什么推荐用 rem?
-
改一处全局生效
/* 用户设置了大字号,rem 自动响应 */ html { font-size: 18px; /* 所有 rem 都自动变大 */ } -
无副作用
/* 嵌套多层时,em 会逐层累积,rem 不受影响 */ .parent { font-size: 2em; /* 子元素会是 2 * 2em = 4em */ } .child { font-size: 1rem; /* 永远是 16px,不受父元素影响 */ }
em:相对于父元素
.parent {
font-size: 20px;
}
.child {
padding: 1em; /* 1 * 20px = 20px */
margin: 2em; /* 2 * 20px = 40px */
}
适合用 em 的场景
/* 按钮:保持和文字成比例的内边距 */
.btn {
padding: 0.5em 1em;
/* 字体大 → 按钮大,字体小 → 按钮小 */
}
百分比:%
相对于父元素的尺寸。
.container {
width: 80%; /* 父元素宽度的 80% */
}
.child {
width: 50%; /* container 宽度的 50% */
}
常见应用
/* 居中布局 */
.box {
width: 80%;
margin: 0 auto;
}
/* 响应式图片 */
img {
max-width: 100%;
height: auto;
}
视口单位:vw / vh
相对于浏览器可视区域。
/* 全屏 hero 区 */
.hero {
height: 100vh; /* 100% 视口高度 */
display: flex;
align-items: center;
justify-content: center;
}
/* 响应式文字 */
h1 {
font-size: 5vw; /* 随视口宽度缩放 */
}
实用技巧:限制范围
/* vw 太大时会失控,用 clamp 限制 */
h1 {
font-size: clamp(24px, 5vw, 64px);
/* 最小 24px,最大 64px,中间随 vw 变化 */
}
绝对单位:px
固定值,不随任何东西变化。
适合场景
/* 边框 - 像素级精确 */
.card {
border: 1px solid #ddd;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* 分割线 */
.divider {
height: 1px;
background: #eee;
}
/* 小间距微调 */
.icon {
margin-right: 4px;
}
字体慎用 px
/* ❌ 响应式差,小屏手机上显得太大 */
body {
font-size: 16px;
}
/* ✅ 响应式好,尊重用户设置 */
body {
font-size: 1rem;
}
选择
典型场景对比
| 场景 | 推荐 | 原因 |
|---|---|---|
| 页面根字号 | rem | 统一控制 |
| 组件内文字 | rem | 独立组件时也能正确缩放 |
| 按钮内边距 | em | 和文字保持比例 |
| 卡片宽度 | % | 随容器自适应 |
| 弹窗居中 | flex / grid | 更可靠 |
| Hero 全屏 | vh | 直接占满视口 |
| 固定头部 | px 或 rem | 不需要响应式 |
完整示例
:root {
/* 统一管理字号 */
--font-size-base: 1rem; /* 16px */
--font-size-lg: 1.25rem; /* 20px */
--font-size-xl: 1.5rem; /* 24px */
--font-size-2xl: 2rem; /* 32px */
}
body {
font-size: var(--font-size-base);
line-height: 1.6;
}
h1 {
font-size: var(--font-size-2xl);
}
.card {
padding: 1.5rem;
margin-bottom: 1rem;
}
.btn {
padding: 0.5em 1.5em;
border: 1px solid currentColor;
}
总结
- 字号用 rem:好维护,尊重用户
- 间距用 rem/em:和字号保持比例
- 布局用 % / vw:响应式自适应
- 边框阴影用 px:精确控制
- vw/vh 做全屏:简单直接
记住:响应式设计的核心是”比例”而非”固定值”,用好相对单位能让页面缩放更自然。