Skip to content

3-1 移动端适配:viewport / rem / vw

H5 = 在手机浏览器里跑的网页。手机屏幕尺寸五花八门(iPhone SE 到大屏安卓),怎么让页面在不同尺寸上比例协调?这就是「移动端适配」要解决的核心问题。本章讲清楚原理和工程里的标准做法。

配套 demo:demo/3-1-vw-adapt.html(用 vw 做的页面,缩放浏览器窗口看它整体等比缩放)。


1. 第一步:viewport 设置(必做)

每个 H5 页面的 <head> 里必须有这一行:

html
<meta name="viewport" content="width=device-width, initial-scale=1.0">

含义:让页面宽度 = 设备宽度,初始缩放 1。不加这行,手机会用一个虚拟的 980px 宽来渲染,页面会缩得很小。前面所有 demo 都已经加了它。


2. 问题:px 是固定的,屏幕是变化的

你写 width: 200px,在 375px 宽的手机上占大半屏,在 414px 的手机上占比就变小。用固定 px 做移动端,不同手机上比例会不一致。

解决思路:用「相对单位」,让尺寸随屏幕宽度等比缩放。两种主流方案:remvw


3. 方案一:vw(推荐,最简单)

vw = viewport width 的百分之一。100vw = 整个屏幕宽,1vw = 屏幕宽的 1%。

它天生就是相对屏幕宽度的,屏幕越宽,同样的 vw 值对应的像素越大,自动等比。

设计稿通常按某个宽度出图(常见 375px)。换算公式:

目标 vw = 设计稿 px / 设计稿宽度 × 100

例:设计稿 375px 宽,一个元素标注 width: 100px:

100 / 375 × 100 = 26.666vw
css
.box { width: 26.666vw; }   /* 在任何宽度的手机上都占屏幕 100/375 的比例 */

手算太麻烦?工程里用插件自动把 px 转成 vw(下面讲),你照着设计稿写 px 就行。


4. 方案二:rem(老牌方案,了解)

rem = 相对根元素 <html>font-size。如果 html { font-size: 16px },那 1rem = 16px

技巧:用 JS 让 html 的 font-size 随屏幕宽度变化,所有用 rem 的尺寸就跟着变:

js
// 让 1rem = 屏幕宽度 / 10
function setRem() {
  document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px'
}
setRem()
window.addEventListener('resize', setRem)

这套逻辑有现成库 amfe-flexible,配合 postcss-pxtorem 自动转换。

vw 还是 rem?新项目优先 vw(更简单,不用 JS 动态设根字号)。Vant 官方也推荐 vw。rem 多见于老项目。


5. 工程化:自动 px → vw(项目里的标准配置)

实际开发没人手算 vw。在 Vite 项目里装一个 PostCSS 插件,你照设计稿写 px,构建时自动转成 vw。

bash
npm install postcss-px-to-viewport-8-plugin -D

postcss.config.js:

js
export default {
  plugins: {
    'postcss-px-to-viewport-8-plugin': {
      viewportWidth: 375, // 设计稿宽度(按你们 UI 出图的宽度填)
      unitPrecision: 5,
      viewportUnit: 'vw',
      selectorBlackList: ['.ignore'], // 不想转换的类名
      minPixelValue: 1, // 小于这个值不转换
    },
  },
}

配好后,CSS 里写:

css
.box { width: 100px; height: 50px; }  /* 构建后自动变成 vw,自动适配 */

后端类比:像一个「编译期的单位转换器」,源码写直观的 px,产物是自适应的 vw。第 5 部分实战项目用的就是这套配置。

⚠️ 注意:它对 Vant 组件库(基于 375 设计)也会生效,正好匹配,所以 viewportWidth 常设 375。


6. 一些移动端常识

  • 1px 边框问题:高清屏下 CSS 的 1px 可能显示成 2 物理像素,想要细线可用 transform: scale(0.5) 技巧或 Vant 的 van-hairline。初学先不纠结。
  • 点击 300ms 延迟:老问题,现代浏览器加了 viewport 设置后基本没有了。
  • 安全区域(刘海屏):用 env(safe-area-inset-bottom) 给底部留白。用到再查。

动手练习

  1. 打开 demo/3-1-vw-adapt.html,拖动浏览器窗口改变宽度,观察卡片、文字、图标整体等比缩放(因为用了 vw)。
  2. 对比:demo 里有一个用固定 px 的盒子,缩放窗口时它不变,体会差异。
  3. 按 F12 → 点左上角「设备工具栏」图标(手机/平板图标),切换不同机型预览,看 vw 布局在各机型下都协调。
  4. 思考:你们 UI 出的设计稿是多少宽?(决定 viewportWidth 填几)

小结

  • H5 必加 <meta viewport>
  • 移动端适配核心:用相对单位让尺寸随屏幕等比缩放
  • 首选 vw(px/设计稿宽×100),工程里用 postcss-px-to-viewport 插件自动转换,你只管写 px。
  • rem 是老方案,配 amfe-flexible + postcss-pxtorem

➡️ 下一章:3-2 Vant 组件库

写给有后端基础、想系统学习 Vue 3 与 H5 的开发者