一、先别死记概念,先理解"尺子"
前端里的:
px→ 固定尺子em→ 看父元素的尺子rem→ 看根元素(html)的尺子
你可以把它们理解成:
| 单位 | 参考对象 | 类比 |
|---|---|---|
| px | 固定像素 | 固定长度的钢尺 |
| em | 当前/父级字体大小 | 会继承的弹性尺 |
| rem | html根字体大小 | 全局统一缩放尺 |
二、px(像素)------ 最容易理解
1. 什么是 px
TypeScript
font-size: 16px;
width: 200px;
意思:
- 字体固定16像素
- 宽度固定200像素
这是最"死板"的单位
2. px 的特点
优点
精准
适合:
- 边框
- 阴影
- 小图标
- 细节控制
缺点
不会跟着用户字体习惯变化
比如:
- 用户系统字体调大
- 浏览器缩放
- 无障碍模式
px 不够灵活
三、em ------ 最容易把人绕晕的单位
很多人学不会 em。
原因:
没理解"它到底参考谁"。
1. em 到底参考谁?
font-size 时
参考父元素字体大小。
其他属性时
参考当前元素自己的字体大小。
这是最容易懵的地方。
2. 看一个例子
TypeScript
<div class="parent">
<div class="child">
Hello
</div>
</div>
css
.parent {
font-size: 20px;
}
.child {
font-size: 2em; // 2em = 父元素20px × 2 = 40px
}
3. em 会"连锁放大"
这是它最危险的地方。
TypeScript
<div class="a">
<div class="b">
<div class="c">文本</div>
</div>
</div>
css
.a {
font-size: 16px;
}
.b {
font-size: 2em; // b = 16 × 2 = 32px
}
.c {
font-size: 2em; // c = 32 × 2 = 64px
}
会层层叠加。
这叫:
em 的继承陷阱
4. em 更适合什么?
适合组件内部比例缩放
例如按钮:
css
.button {
font-size: 16px;
padding: 0.5em 1em;
// 上下 padding = 16 × 0.5 = 8px
// 左右 padding = 16 × 1 = 16px
}
这就是 em 的价值:
相对该元素自己的 font-size,进行"组件自适应缩放"
四、rem ------ 现代前端最重要的单位
现在:
- React
- Vue
- Ant Design
- Tailwind
- 移动端适配
大量使用 rem。
1. rem 是什么?
root em
root = 根元素
也就是:
rem 永远参考 html
css
html {
font-size: 16px;
}
1rem = 16px
2rem = 32px
0.5rem = 8px
3. rem 最大优势
全局统一缩放
例如,如果改:
css
html {
font-size: 20px;
}
整个网站自动变大。
这就是:
rem 的核心价值
五、为什么现代项目更喜欢 rem?
因为:
更适合响应式
1. 以前的移动端适配
TypeScript
html.style.fontSize = window.innerWidth / 37.5 + 'px'
// 37.5 的由来:设计稿 375px 宽时,希望 1rem = 10px,方便心算:
// 设计稿标 100px → 写 10rem
// 设计稿标 37.5px → 写 3.75rem
// 公式:根字号 = 屏宽 / 37.5,所以在 375 屏上 1rem = 10px。
css
width: 10rem;
页面会整体缩放。
这就是:
淘宝 flexible 方案
2. 20年以前的移动端(H5)适配
vw + flex/grid 配合 postcss-px-to-viewport(自动把 px 转 vw)
postcss.config.ts
TypeScript
module.exports = {
plugins: {
'postcss-px-to-viewport': {
viewportWidth: 375, // 设计稿宽度
unitPrecision: 6, // 保留小数位
minPixelValue: 1, // 小于多少 px 不转换
exclude: [/node_modules/], // 排除
},
},
};
正常写:width: 100px;
打包自动变:width: 26.6667vw;
3. 现在的移动端(H5)适配
- 布局:
flex/grid
- 字体:
rem(或clamp())
- 尺寸:
rem + 断点 media query
- 安全区适配用
env(safe-area-inset-*)(刘海屏、底部手势区)。
- 补充:
dvh/svh+safe-area+max-width容器约束
4、小程序
- 布局:
flex+rpx
- 宽高/间距:都按 x * 750 / 350 转
rpx
- 字体:可用
rpx(常见),也可少量px做精细控制
- 1px 线:用小程序常见发丝线方案(
transform: scaleY(0.5)等)
css
@function r($px) {
@return ($px * 750 / 350) * 1rpx;
}
.card {
padding: r(16);
font-size: r(14);
}
2. 用户无障碍友好
如果用户浏览器字体调大:
rem 会跟着变化。
体验更好。
六、现代企业项目推荐方案
| 场景 | 推荐单位 |
|---|---|
| 字体 | rem |
| 页面布局 | rem / % / flex |
| 组件内部间距 | em |
| 边框 | px |
| 阴影 | px |
| 圆角 | px |
| 图标 | px |
| 超细线 | px |