移动端开发中,px、em、rem、vw/vh 的区别和适用场景?
在移动端开发中,选择合适的 CSS 单位是实现响应式布局(Responsive Layout)和屏幕适配的关键。
以下是 px、em、rem、vw/vh 的详细对比、区别及适用场景:
1. 核心概念与区别速查表
| 单位 | 全称 | 基准(参考对象) | 特点 | 移动端主要用途 |
|---|---|---|---|---|
| px | Pixel | 屏幕逻辑像素 | 绝对单位(在同一设备上固定),不随屏幕大小变化。 | 边框、阴影、极小的固定元素。 |
| em | Element meter | 父元素的字体大小 | 相对单位。存在嵌套计算问题(利滚利),难以控制。 | 极少用于移动端布局,偶用于组件内部缩放。 |
| rem | Root em | 根元素(html)的字体大小 | 相对单位。全局统一,无嵌套问题。 | 主流适配方案。用于大部分布局、字体、间距。 |
| vw/vh | Viewport Width/Height | 视口的宽/高 | 相对单位。1vw = 视口宽度的 1%。 | 现代适配方案。用于容器宽度、大屏展示、流体排版。 |
2. 详细解析与适用场景
1. px (Pixels)
- 定义:逻辑像素(CSS 像素)。在高清屏(Retina)上,1px 可能对应 2 个或 3 个物理像素(取决于 DPR)。
- 特点:
- 固定死板:写了
100px,在 iPhone SE 上是 100px,在 iPad Pro 上也是 100px,不会自动缩放。
- 固定死板:写了
- 移动端适用场景:
- 边框(Border):如
border: 1px solid #ccc。 - 阴影(Box-shadow)。
- 最小尺寸限制:如
min-width。 - 不希望随屏幕缩放的元素:例如某些固定大小的图标。
- 边框(Border):如
2. em
- 定义:相对单位,相对于当前元素的
font-size;如果当前元素未设置,则继承自父元素。 - 特点:
- 嵌套地狱:如果父容器是
1.2em,子元素又是1.2em,实际大小是 倍基准大小。这使得计算非常复杂。
- 嵌套地狱:如果父容器是
- 移动端适用场景:
- 极少用于整体布局。
- 首行缩进:
text-indent: 2em(永远缩进两个字的大小)。 - 组件内部相对缩放:例如一个按钮,padding 设置为
0.5em,当你调整按钮字体大小时,padding 会自动按比例调整,保持美观。
3. rem (Root em)
- 定义:相对单位,相对于 HTML 根元素 (
<html>) 的font-size。 - 特点:
- 基准统一:无论在哪里使用,参考的都是同一个值,避免了
em的嵌套问题。 - 适配核心:通过 JavaScript 或 CSS 媒体查询,根据屏幕宽度动态改变
html的font-size,页面中所有使用rem的元素就会整体等比缩放。
- 基准统一:无论在哪里使用,参考的都是同一个值,避免了
- 移动端适用场景:
- 目前最主流的移动端适配方案(如淘宝的 Flexible 方案,尽管现在推荐用 vw,但 rem 依然广泛存在)。
- 用于容器高度、宽度、间距(margin/padding)、字体大小。
- 原理:
- JS 检测屏幕宽 375px 设置 html font-size = 37.5px (假设 1rem = 10vw)。
- CSS 写
width: 10rem实际渲染 375px。 - 换个手机宽 414px JS 设置 html font-size = 41.4px。
- CSS 还是
width: 10rem实际渲染 414px。
4. vw / vh (Viewport Width / Height)
- 定义:
1vw= 视口宽度的 1%。1vh= 视口高度的 1%。
- 特点:
- 纯 CSS 适配:不需要 JS 动态计算,浏览器原生支持。
- 直接响应:屏幕变宽,元素直接变宽。
- 移动端适用场景:
- 现代主流适配方案(替代 rem)。
- 全屏布局:如
height: 100vh做首屏海报。 - 容器宽度:
width: 50vw(屏幕的一半)。 - 结合 rem 使用:将
html的font-size设置为vw单位(例如html { font-size: 13.333vw }),从而实现不用 JS 也能让 rem 随屏幕缩放。
3. 深度对比:Rem 方案 vs VW 方案
在 2024 年的移动端开发中,主要存在两种流派:
方案 A:纯 Rem 适配(配合 JS 或 媒体查询)
- 做法:使用
amfe-flexible等库,根据屏幕宽度动态设置 html 的 font-size。 - 优点:兼容性极好(甚至兼容 IE8+),生态成熟。
- 缺点:需要引入 JS,或者写很多媒体查询;在某些安卓机上可能有轻微的计算延迟导致“闪烁”。
方案 B:VW 适配(推荐)
- 做法:直接使用
vw作为单位,或者使用postcss-px-to-viewport插件,在打包时自动将设计稿的px转换为vw。 - 优点:不依赖 JS,性能最好,所见即所得。
- 缺点:
px转vw后,在大屏(如 iPad 或横屏)上元素会变得过大。通常需要配合max-width或媒体查询限制最大宽度。
方案 C:Rem + VW (最佳实践)
- 做法:css
html { /* 假设设计稿是 750px,1rem = 100px */ font-size: calc(100vw / 7.5); } @media screen and (min-width: 750px) { html { font-size: 100px; /* 限制最大字号,防止在大屏上无限放大 */ } } - 优点:结合了 vw 的自动缩放和 rem 的最大宽度控制能力。
4. 总结:开发中该怎么选?
- Border(边框)、Shadow(阴影):
- 使用 px。
- Layout(布局容器)、Image(图片)、Padding/Margin(间距):
- 首选 vw(通过构建工具自动转换)。
- 或者 rem(如果项目较老或需要严格控制最大宽度)。
- Font-size(字体):
- 使用 rem:为了无障碍访问(Accessibility)。如果用户在浏览器设置中调大了字体,rem 能感知到并放大,而 px 和 vw 往往会忽略用户的系统字体设置。
- 或者 px:如果你强制要求字体大小不随屏幕变化(某些 App 内部 H5)。
- Full Screen(全屏背景/弹窗):
- 使用 vh 和 vw。
一句话建议:
在现代移动端项目中,使用 PostCSS 插件(如 postcss-px-to-viewport),在代码里直接写设计稿的 px,让工具自动编译成 vw,特殊情况(如边框)使用 /* px-to-viewport-ignore */ 保持 px。