屏幕适配方案完全指南
涵盖移动端(手机/平板)和 PC 端(桌面浏览器)的常见适配方案、 工程化实施方法及浏览器兼容性对照。
一、核心概念
二、移动端适配方案
方案 1:VW 方案(推荐)
原理:通过构建工具(postcss-px-to-viewport)自动将 CSS 中的 px 转换为 vw 单位,元素尺寸随视口宽度等比缩放。
计算公式:元素 vw 值 = (设计稿中的 px / 设计稿宽度) × 100
例:设计稿 375px,元素 16px → 16 / 375 × 100 = 4.267vw
实施步骤
① 安装依赖
pnpm add -D postcss-px-to-viewport② 配置 vite.config.js
import postcssPxToViewport from 'postcss-px-to-viewport'
export default defineConfig({
css: {
postcss: {
plugins: [
postcssPxToViewport({
viewportWidth: 375, // 设计稿宽度
unitPrecision: 5, // 转换精度
viewportUnit: 'vw', // 转换单位
fontViewportUnit: 'vw', // 字体单位
selectorBlackList: ['.ignore'], // 忽略类名
minPixelValue: 1, // 1px 不转
mediaQuery: false, // 不转媒体查询内 px
exclude: [/node_modules/], // 排除 Vant
}),
],
},
},
})③ 容器约束(可选)
#app {
min-width: 320px; // 防止超窄屏过度挤压
max-width: 480px; // 防止特大屏变形
margin: 0 auto;
}④ 不需要转换的元素加 .ignore 类
<div class="ignore" style="border: 1px solid #eee">不转换</div>浏览器兼容性
降级方案:搭配 postcss-viewport-units 生成 px 回退值。
优缺点
方案 2:Rem 方案(成熟稳定)
原理:通过 JS 动态设置 <html> 的 font-size 为视口宽度的 1/10,CSS 使用 rem 单位,所有尺寸自动缩放。
计算公式:html font-size = 屏幕宽度 / 10
375px → font-size: 37.5px → 元素 16px = 16 / 37.5 = 0.4267rem
实施步骤
① 安装依赖
pnpm add amfe-flexible
pnpm add -D postcss-pxtorem② main.js 引入
import 'amfe-flexible'③ 配置 vite.config.js
import postcssPxtorem from 'postcss-pxtorem'
export default defineConfig({
css: {
postcss: {
plugins: [
postcssPxtorem({
rootValue: 37.5, // 基准值(375 设计稿 / 10)
propList: ['*'], // 全部属性转换
selectorBlackList: [],
minPixelValue: 2, // < 2px 不转
exclude: [/node_modules/], // 排除 Vant
}),
],
},
},
})浏览器兼容性
⚠️ 注意:
部分浏览器有字体最小 12px 限制,可能影响 rem 基准
与 Vant 冲突,必须
exclude排除需监听
resize事件更新 font-size(amfe-flexible 已实现)
优缺点
方案 3:CSS clamp() 函数
原理:使用 CSS 原生 clamp(MIN, PREFERRED, MAX) 函数为属性设置弹性范围值,无需构建工具。
/* font-size: 最小 14px,理想 3.5vw,最大 20px */
font-size: clamp(14px, 3.5vw, 20px);
/* padding: 最小 8px,理想 2vw,最大 24px */
padding: clamp(8px, 2vw, 24px);
/* 卡片宽度:灵活比例 */
width: clamp(280px, 45vw, 480px);实施步骤
无需安装,直接在 CSS/Less 中使用即可。
① 定义全局常用 clamp 值
@font-body: clamp(13px, 3.5vw, 16px);
@font-title: clamp(18px, 5vw, 28px);
@spacing: clamp(8px, 2vw, 16px);② 兼容降级
/* 不支持 clamp 的浏览器使用固定值兜底 */
font-size: 16px;
font-size: clamp(14px, 3.5vw, 20px);
/* 或用 @supports 判断 */
@supports (font-size: clamp(1px, 1vw, 2px)) {
body { font-size: clamp(14px, 3.5vw, 20px); }
}浏览器兼容性
优缺点
方案 4:媒体查询断点(修补方案)
原理:通过 @media 在不同的屏幕宽度下覆盖 CSS 值,仅用于修补边界。
/* 超小屏 */
@media (max-width: 320px) { ... }
/* 小屏手机 */
@media (min-width: 321px) and (max-width: 375px) { ... }
/* 大屏手机 / 小平板 */
@media (min-width: 376px) and (max-width: 480px) { ... }
/* 平板 */
@media (min-width: 481px) and (max-width: 768px) { ... }
/* 桌面 */
@media (min-width: 769px) { ... }浏览器兼容性:CSS2.1 即支持,✅ 无兼容问题 但只能修修补补,无法根本解决适配问题。
方案 5:组合方案(生产推荐)
实际生产环境通常多种方案组合使用:
视图层面:postcss-px-to-viewport(自动转 vw)
字体层面:clamp() 控制范围(不无限放大)
布局层面:Flex + 百分比(流动布局)
边界修补:媒体查询(处理极端情况)
大屏限制:max-width 容器约束当前项目推荐配置
// vite.config.js
import postcssPxToViewport from 'postcss-px-to-viewport'
export default defineConfig({
css: {
postcss: {
plugins: [
postcssPxToViewport({
viewportWidth: 375,
exclude: [/node_modules/],
minPixelValue: 1,
}),
],
},
},
})// main.less
#app {
min-width: 320px;
max-width: 480px;
margin: 0 auto;
}
body {
font-size: clamp(13px, 3.5vw, 17px);
}三、PC 端适配方案
方案 1:固定宽度居中容器
最常见方案,内容区域固定宽度,两侧留白。
.container {
width: 100%;
max-width: 1200px; /* 或 1440px */
margin: 0 auto;
padding: 0 20px;
}工程化:无需构建插件,配合响应式栅格即可。 兼容性:✅ 所有浏览器
方案 2:百分比 + Flex 布局(响应式栅格)
.row { display: flex; flex-wrap: wrap; }
.col-3 { flex: 0 0 25%; max-width: 25%; } /* 4 列 */
.col-4 { flex: 0 0 33.33%; max-width: 33.33%; } /* 3 列 */
/* 断点切换列数 */
@media (max-width: 768px) {
.col-3 { flex: 0 0 50%; } /* 平板 2 列 */
.col-4 { flex: 0 0 100%; } /* 手机 1 列 */
}兼容性:
✅ iOS Safari 7.1+ / Android 4.4+ / Chrome 29+ / IE 11+
⚠️ IE 10 部分支持(不支持 flex-wrap)
❌ IE 9- 不支持
方案 3:CSS Grid 布局
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}一行代码实现响应式网格。
兼容性:
✅ iOS Safari 10.3+ / Android 61+ / Chrome 57+ / Firefox 52+
⚠️ IE 10/11 部分支持(需 -ms- 前缀)
方案 4:容器查询(Container Queries)
基于父容器尺寸而非视口的响应式方案。
.card-container {
container-type: inline-size;
}
@container (max-width: 400px) {
.card { flex-direction: column; }
}兼容性:
⚠️ Chrome 105+ / Safari 16+ / Firefox 110+
❌ IE 全系不支持
全球覆盖率约 78%
四、各方案兼容性对比总表
五、工程化实施清单
六、调试方法
Chrome DevTools 移动端模拟:
Ctrl+Shift+M切换设备工具栏响应式模式:在 DevTools 中拖拽边角测试不同宽度
真机测试:局域网访问 dev server,在不同真机上验证
常用测试宽度: