一、方案原理与实现细节
1. rem + lib-flexible(pxtorem)
- 原理:通过 JS(如 lib-flexible)动态设置
<html>的 font-size,PostCSS 插件(如 postcss-pxtorem)将 CSS 中 px 转 rem,实现自适应。 - 实现:
- 引入 lib-flexible,监听页面宽变化,动态调整根字体。
- CSS 书写 px,构建时自动转 rem。
- 适合兼容老设备、字体缩放需求强的场景。
2. vw + postcss-px-to-viewport
- 原理:利用 CSS 的 vw 单位(视口宽度百分比),PostCSS 插件自动将 px 转 vw,无需 JS。
- 实现:
- 配置 postcss-px-to-viewport 插件,无需引入额外 JS。
- CSS 直接写 px,构建时自动转 vw。
- 只需设置好 viewport meta 标签即可。
- 适合现代移动端、响应式需求强的项目。
二、 安装使用步骤
rem 方案详细使用步骤
- 安装依赖
通常需要 postcss-pxtorem 插件:
npm install postcss-pxtorem --save-dev
- 配置 PostCSS
在 postcss.config.js 或 vite.config.js 中添加:
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue: 37.5, // 设计稿宽度375px时,1rem=37.5px
propList: ['*'], // 需要转换的属性
exclude: /node_modules/i // 排除第三方库
}
}
}
- 设置 html 根字体大小
在入口 JS 文件(如 main.js 或 index.js)动态设置:
function setRemUnit() {
const docEl = document.documentElement;
const width = docEl.clientWidth;
docEl.style.fontSize = (width / 10) + 'px'; // 设计稿375px时,1rem=37.5px
}
setRemUnit();
window.addEventListener('resize', setRemUnit);
- 样式书写规范
- 设计稿标注单位全部用 px,开发时直接写 px,插件会自动转换为 rem。
- 字体大小、间距、宽高等都用 px 单位。
- 注意事项
- 需保证所有页面都引用了动态设置 rem 的 JS 代码。
- 适配多端时,需根据不同设计稿宽度调整 rootValue。
vw 方案详细使用步骤
- 安装依赖
推荐使用 postcss-px-to-viewport 插件:
npm install postcss-px-to-viewport --save-dev
- 配置 PostCSS
在 postcss.config.js 或 vite.config.js 中添加:
module.exports = {
plugins: {
'postcss-px-to-viewport': {
unitToConvert: 'px',
viewportWidth: 375, // 设计稿宽度
unitPrecision: 6,
propList: ['*'],
viewportUnit: 'vw',
fontViewportUnit: 'vw',
selectorBlackList: ['.ignore', '.hairlines'],
minPixelValue: 1,
mediaQuery: false,
replace: true,
exclude: [/node_modules/],
landscape: false
}
}
}
- 样式书写规范
- 设计稿标注单位全部用 px,开发时直接写 px,插件会自动转换为 vw。
- 字体大小、间距、宽高等都用 px 单位。
- viewport 设置
在 index.html 的 <head> 中添加:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
- 特殊场景处理
- 某些第三方组件或不希望被转换的样式,加上
.ignore类名或配置selectorBlackList。 - 1px 问题可用伪类或媒体查询单独处理。
- 注意事项
- vw 方案无需 JS 动态设置根字体,纯 CSS 方案,性能更优。
- 设计稿宽度需与
viewportWidth保持一致。
通过上述详细步骤,你可以根据项目需求选择 rem 或 vw 方案,快速实现高效的移动端适配。
三、优缺点深度对比
| 维度 | rem + lib-flexible | vw + postcss-px-to-viewport |
|---|---|---|
| 兼容性 | 优,适合老设备 | 略逊,主流设备无忧 |
| 性能 | JS 参与,略低 | 纯 CSS,极优 |
| 开发体验 | 换算繁琐,维护成本高 | 书写直观,维护简单 |
| 首屏体验 | 可能闪烁/抖动 | 无闪烁,加载即适配 |
| 响应式 | 需配合媒体查询 | 天生响应式,灵活 |
| 字体缩放 | 支持系统缩放 | 不支持,需额外处理 |
| 生态趋势 | 传统方案,逐步被替代 | 新主流,生态持续壮大 |
| 1px 问题 | 需特殊 hack | 依然需特殊 hack |
| 适配第三方库 | 需统一 rem 方案 | 需统一 px 转换 |
rem + lib-flexible 优点
- 兼容性极佳,适合老旧设备
- 字体缩放友好,适合无障碍场景
- 生态成熟,工具链完善
- 灵活性高,可动态调整根字体
rem + lib-flexible 缺点
- 依赖 JS,首屏闪烁风险
- 维护成本高,需关注 JS 逻辑
- rem 计算不直观,易出错
- 性能略逊,1px 问题需特殊处理
vw + postcss-px-to-viewport 优点
- 纯 CSS,无 JS 依赖,性能优
- 开发体验极佳,维护简单
- 响应式更灵活,适合多端适配
- 生态趋势,未来主流
- 特殊处理灵活,支持 selectorBlackList/注释等
vw + postcss-px-to-viewport 缺点
- 极个别老浏览器兼容性略差
- 设计稿需与 viewportWidth 对齐
- 字体缩放不友好,需额外适配
- 1px 问题依然存在
- 第三方组件库适配难度略高
三、配置与实战案例
vw 方案配置示例
import postcsspxtoviewport from 'postcss-px-to-viewport'
css: {
postcss: {
plugins: [
postcsspxtoviewport({
viewportWidth: 375, // 设计稿宽度
selectorBlackList: ['ignore-'], // 忽略转换
})
]
}
}
vw 方案 CSS 示例
.adaptive-box { width: 375px; } /* 自动转为100vw */
.ignore-adaptive-text { font-size: 16px; } /* 不会被转换 */
// 部分代码未展示
组件引入示例
import AdaptiveDemo from './components/AdaptiveDemo'
function App() {
return (
<div className="App">
<AdaptiveDemo />
</div>
)
}
效果展示
四、真实开发案例
- 某大型商城老项目,因需兼容 Android 4.x,采用 rem 方案,维护成本高,后期逐步迁移到 vw。
- 某新零售小程序,直接用 vw 方案,开发效率提升30%,页面性能显著提升。
- 某无障碍阅读类 App,仍坚持 rem 方案,因需支持用户字体缩放。
五、推荐建议与总结
- 老项目、兼容性优先、字体缩放需求强:rem + lib-flexible
- 新项目、追求性能与开发效率、响应式需求强:vw + postcss-px-to-viewport
rem 方案像“老干部”,稳重但啰嗦;vw 方案像“新新人类”,高效又时髦。选谁?看你项目需求和团队风格啦!