【导读】
你是否好奇过:为什么 375px 宽的 iPhone 和 414px 宽的 Plus 上,同一套 width: 100px 看起来一大一小?设计稿是 750 宽,标注「这个按钮 100px」,你在代码里到底该写多少?

很多开发者对移动端布局的认知,始于「用 rem 或 vw」、止于「除个 2 或除个 37.5」。但如果我问你:为什么设计稿往往是 750 而不是 375?为什么 rem 要跟根字体挂钩?vw 和 rem 到底该选谁?

只有厘清布局单位与设计稿换算的来龙去脉 ,你才能从「会抄公式」进化为「量准每一屏」。本文将带你回到技术现场,把「设计稿宽度 → 视口宽度 → rem/vw → 标注怎么转代码」这条链串联起来------不塞概念,只讲因果。

一、先理解基础:设计稿数值怎么转成代码?
1.1 设计师:按物理分辨率出图
你拿到一个 750px 宽的设计稿------这是设计师按物理分辨率画的。
以 iPhone 为例:
- iPhone 6/7/8 物理分辨率 750px → 出二倍图,画布宽 750px
- iPhone 6 Plus 物理分辨率 1080px → 出三倍图,画布宽 1080px
- 老款非 Retina 屏物理分辨率 375px → 出一倍图,画布宽 375px
大部分团队出二倍图 (750px),因为这是最主流的 Retina 屏规格。
设计师在 750px 画布里标的 100px,就是指物理像素------在 iPhone 6/7/8 上,这个按钮就是要占 100 个发光点。

1.2 前端:按逻辑分辨率写代码,矛盾出现了
但前端写代码,不能直接写物理像素。因为机型太多,浏览器统一用逻辑分辨率来沟通。
以 iPhone 6/7/8 为例:
- 物理分辨率 750px,逻辑分辨率 375px(1 个逻辑点 = 2×2 个物理像素,即 @2x)
- 你代码里写 1px,浏览器会自动用 2×2 个物理像素来显示
矛盾来了:设计师在 750px 画布里标的 100px 是物理像素,你代码里直接写 100px 是逻辑像素------在 iPhone 上会被转成 200 个物理像素。
结果:比设计师想要的大了一倍。

1.3 怎么办?换算
因为设计师画的是物理尺寸,前端写的是逻辑尺寸,中间要过一道换算。
750px 设计稿对应 375px 逻辑宽度,比例是 2:1。
所以设计稿上的数值要除以 2:
| 设计稿(物理) | 代码(逻辑) | 浏览器转物理(@2x) |
|---|---|---|
| 100px | 50px | 100px |
| 200px | 100px | 200px |
| 50px | 25px | 50px |
这样写,最终显示就和设计稿一致。

1.4 小结
设计师按物理分辨率画图,前端按逻辑分辨率写代码,中间必须换算。
这个换算是所有适配方案的基础------不管后面用 rem 还是 vw,都得先过这一关。
二、开始从现象出发:固定 px 在不同宽度设备上「失调」
2.1 令人头疼的"失调"现象
好,现在我们知道换算了。按 750 稿的数值除以 2,写进代码。
但在不同手机上打开,又发现问题:
同样写 width: 50px(换算后的值),在不同宽度的屏幕上,看起来却不一样:
- 在 375px 的屏幕上:50px 占屏幕宽度的 13.3%
- 在 414px 的屏幕上:50px 只占屏幕宽度的 12.1%
结果是:大屏上显得小,小屏上反而显得大。

为什么会这样?
因为 px 是固定的逻辑单位,50px 就是 50 个逻辑点,它只管"占多少个点",不管屏幕有多宽:
- 屏幕 375px 宽:50px 占 50 个点 → 比例 = 50/375 ≈ 13.3%
- 屏幕 414px 宽:50px 还是占 50 个点 → 比例 = 50/414 ≈ 12.1%
屏幕越宽,同样的 px 占的比例就越小。
三、第一次尝试:媒体查询
3.1 一个直观的思路
面对"同样 50px,大屏小、小屏大"的问题,最直观的思路是:为不同宽度的设备设置不同的固定像素值。
通过媒体查询,我们可以为 375px、414px、428px 等设备宽度分别写一套 CSS:
| 方案 | 具体做法 | 结果分析 |
|---|---|---|
| 媒体查询适配 | 375px 屏设 width: 50px,414px 屏设 width: 55px...... |
优点 :能大致适配 缺点:维护成本高、断点难选、只在预设宽度生效 |

3.2 为什么不够?
这套方案的实质是 "离散适配"------只在几个固定的断点上调整尺寸。如果设备宽度在 375px 和 414px 之间(比如 390px),元素尺寸要么跳变,要么维持原样,无法平滑过渡。
媒体查询治标不治本。我们需要的是:元素尺寸能连续地随视口宽度变化,屏幕宽一点就大一点,窄一点就小一点。
四、真正的解决方案:相对单位
我们需要一种能随屏幕宽度变化 的单位------屏幕宽一点,元素占的逻辑像素就多一点;屏幕窄一点,就少一点。这样它在不同屏幕上占的比例才能保持一致。
当然不是说 px 就没用了。像边框、图标这类元素,如果随屏幕缩放反而会怪 ------图标太大显得笨,边框太粗显得糙,用 px 锁定尺寸反而更稳妥。但对于容器、图片、文字块这些需要按比例缩放的元素,我们必须换一种单位。

在 CSS 里,有两种相对单位可以用来做适配:
| 单位 | 相对谁 | 特点 |
|---|---|---|
| rem | 根元素的字体大小(html 的 font-size) | 通过控制根字体,间接控制所有用 rem 的元素 |
| vw | 视口宽度(1vw = 屏幕宽的 1%) | 直接关联视口,不依赖任何中间变量 |
它们都能实现 "屏幕越宽,元素越大" 的效果,但路径不同:
- rem 像是给全站装了一个"总开关"------改根字体,所有 rem 一起变
- vw 像是每个元素自己"盯着屏幕看"------屏幕宽多少,它就长多少

接下来两章我们分别拆解 rem 和 vw。
五、方案一:rem 详解
5.0 rem 核心思想:切份思维
问题 :不同手机宽度不同,内容怎么自动适配?
思路:把屏幕想象成可以切分的整体,你只管说要几份,每份多宽由屏幕自己决定。
- 根字体 = 当前屏幕的"每份宽度"
- rem = "我要几份"

5.1 具体操作:怎么从设计稿到 rem?
设计稿 750px,你约定 1rem = 设计稿上的 100px(B=100)。
| 设计稿 | 你的代码 | 逻辑 |
|---|---|---|
| 100px 按钮 | width: 1rem |
100÷100 = 1份 |
| 24px 字体 | font-size: 0.24rem |
24÷100 = 0.24份 |
在不同手机上:
- 375px 屏:每份 = (375÷750)×100 = 50px → 1rem = 50px
- 414px 屏:每份 ≈ 55.2px → 1rem ≈ 55.2px
你只写"要几份",具体宽度根字体自动算。
所以如果你看到 html { font-size: 50px; },意思就是"当前屏幕每份 50px 宽"。那么:
1rem= 要 1 份 = 50px2rem= 要 2 份 = 100px0.5rem= 要半份 = 25px

5.2 底层原理:两个公式说透
- D = 设计稿宽度
- B = 你约定的 1rem 对应设计稿多少 px
- A = 设计稿上元素的 px 值
1. 写代码时: rem值 = A ÷ B
2. 运行时: 根字体大小 = (当前屏幕宽 ÷ D) × B

5.3 落地实现:怎么让根字体(每份多宽)自动变?
问题:根字体要等于「当前屏幕宽 ÷ 7.5」,但 CSS 没法直接读到屏幕宽度。怎么办?

有两种主流做法:JS 动态计算,或者用 vw 单位。
方案A:用 JS 动态计算(传统)
页面加载时用 JS 读一次屏幕宽,算好根字体写进 html,同时监听 resize 事件,屏幕旋转或缩放时重新计算。
javascript
function setRootFontSize() {
const W = document.documentElement.clientWidth;
// 750设计稿,1rem=100px → 屏幕宽 ÷ 7.5
document.documentElement.style.fontSize = (W / 7.5) + 'px';
}
setRootFontSize();
window.addEventListener('resize', setRootFontSize);

优点:可以精确控制,比如限制最大最小字号、排除平板
缺点:要写 JS,且首屏可能出现「闪一下」(先渲染默认字号,再被 JS 覆盖)


方案B:用 CSS 的 vw 单位(现代,无需 JS)
vw 本身就是视口宽度的 1%。如果想让根字体 = 屏幕宽 ÷ 7.5,那就是:
屏幕宽 ÷ 7.5 = (100vw) ÷ 7.5 = calc(100vw / 7.5)
直接写进 CSS 就行:
css
html {
font-size: calc(100vw / 7.5); /* 375px屏 → 50px,414px屏 → 55.2px */
}

如果想限制根字体太大或太小,可以用 clamp():
css
html {
font-size: clamp(42px, 13.333vw, 54px); /* 最小42px,最大54px */
}

优点:纯 CSS,零 JS,无闪烁

缺点 :在大屏设备(比如 iPad)上可能会过大,需要配合 clamp() 或媒体查询限制

两种方案怎么选?

| 场景 | 推荐方案 |
|---|---|
| 老项目改造、需要精确控制 | JS 动态计算 |
| 新项目、追求简洁 | CSS vw + clamp() |
| 要支持用户调浏览器默认字体 | 用 rem 体系时注意:vw 方案不会响应字体设置 |
两种都能让"每份宽度"跟着屏幕走,团队习惯哪个就用哪个。
5.4 常见疑问
Q:为什么不用百分比?
A:因为设计师给的是 px(具体数值),不是比例。用百分比你每次都要心算:100÷750≈13.3%,麻烦且容易错。
Q:"除以37.5"是啥?
A:设计稿 375px 时,为了让 1rem 在 375px 手机上等于 37.5px(好算),B 就取 37.5。本质和 B=100 一样,只是基准不同。

六、方案二:vw 详解
6.1 vw 是什么?
vw 是视口宽度的 1%。1vw = 视口宽度的 1% ,100vw 就等于整个视口的宽度。
6.2 直接换算,无需"桥接"
既然 vw 直接关联视口,我们就可以跳过 rem 和根字体,直接进行换算。核心思想是:设计稿上的尺寸占设计稿宽度的百分之多少,就写多少 vw。

换算公式 :
设计稿量到 A px,设计稿宽度为 D px。
- 代码 vw 值 =
(A / D) * 100 vw
以 设计稿750宽 为例:
| 设计稿标注(px) | 代码(vw) | 计算过程 |
|---|---|---|
| 100 | 13.333vw | (100 / 750) * 100 |
| 50 | 6.667vw | (50 / 750) * 100 |
| 24 | 3.2vw | (24 / 750) * 100 |
| 750 | 100vw | (750 / 750) * 100 |
七、选型指南:rem 还是 vw?
根据当前行业趋势,答案是:新项目里 vw 用得越来越多,但 rem 仍然有它不可替代的位置。
rem:优势在于"整体控制"。通过修改根字体,可以轻松缩放整个页面的布局比例。换算时100px -> 1rem更符合直觉。vw:优势在于"直接纯粹"。不依赖 JS 和根字体,是更彻底的响应式方案。但小数位可能较多,且无法通过单一变量控制全局缩放。

选择哪种取决于团队习惯。现代工程中,常用 PostCSS 插件(如 postcss-px-to-viewport)自动完成 px 到 vw/rem 的转换,开发者几乎可以无感地以设计稿像素值进行开发。
7.1 看项目类型
| 项目类型 | 主流选择 | 原因 |
|---|---|---|
| 面向消费者的H5页面(活动页、营销页、电商详情) | vw 为主 | 追求"丝滑等比缩放",vw 直接关联视口,不需要 JS 计算根字体,代码更干净。配合 clamp() 可以完美控制极限尺寸。 |
| 后台管理系统 / 文档型网站 | rem 或 px | 这类系统更看重可访问性------用户如果调大浏览器默认字体,用 rem 布局的页面可以整体缩放,而 vw 不会响应。 |
| 需要整体缩放控制的项目(如老年模式、夜间模式、可调字号) | rem | rem 可以通过修改根字体一键缩放全页面,vw 做不到这一点。 |
| 小程序 | rpx | 微信小程序专用单位,本质是 vw 的变体(1rpx = 屏幕宽的 1/750)。 |
7.2 为什么 vw 越来越流行?
- 无需 JS :vw 是纯 CSS 方案,根字体用
calc(100vw / 7.5)就能动态计算,不再需要 flexible 那套 JS。 - 更符合直觉:vw 直接表达"占视口的百分之几",和你最初理解的"直接乘比例"是一致的。
- clamp() 解决了边界问题 :以前 vw 在大屏上会无限放大,现在用
clamp(最小值, vw值, 最大值)可以完美控制。
7.3 为什么 rem 还没被淘汰?
- 可访问性:用户如果调大浏览器默认字体,用 rem 的页面会响应,vw 不会。这是 rem 最核心的优势。
- 整体控制:想实现"一键切换老年模式"或"夜间模式缩放",rem 只需要改根字体,vw 需要改所有元素。
- 习惯和存量项目:很多老项目基于 rem 构建,团队也熟悉这套方案。
7.4 专业开发者的选择
现在很多团队的做法是:vw + rem 混用。
- 布局尺寸 (宽高、边距)用 vw,让容器随屏幕平滑缩放。
- 字体大小 用 rem,保留用户调整字体的能力。
- 极端尺寸控制 用 clamp(),防止太大或太小。

八、全文总结
一句话记住整条链:
「设计稿宽度(如750)和视口宽度(如375)存在固定比例(如2倍);使用 rem(通过动态根字体桥接)或 vw(直接百分比)让尺寸能按此比例缩放;设计稿量到的px值,按约定公式换算即可。」
通过这条清晰的因果链,我们串联起了所有关键点:
- ✅ 为什么设计稿常是750:对应高倍屏物理像素,与CSS逻辑像素视口成比例关系。
- ✅ 为什么px量不准:它是固定单位,无法实现跨设备的比例一致性。
- ✅ rem如何工作 :通过动态根字体(
font-size)作为"比例尺",将设计稿尺寸等比映射到不同视口。 - ✅ vw如何工作:作为视口的天然百分比,直接映射设计稿的占比关系。
- ✅ 如何换算:确定设计稿宽度和换算基准(1rem对应多少px 或 直接用vw公式),标注值按比例计算。
下一步:从「量准」到「布局稳健」
掌握布局单位的换算,解决了 「量准」 的问题。但这只是移动端适配的第一步。接下来你会面临:
在极端尺寸(如很窄的320px或很宽的平板)下,如何防止布局错乱、字体过大过小?多栏卡片何时应该断行?
这就是适配的下一篇章:响应式断点与布局约束 ------将 rem/vw 与媒体查询、max-width、clamp() 等工具结合,实现 「不断点、不挤爆」 的稳健布局。