postcss-px-to-viewport它是 PostCSS 插件 ,核心作用:编译时把 CSS 里的 px 自动转成 vw/vh 等视口单位,实现移动端 "一套设计稿、全设备自适应"。
一、诞生背景:移动端适配的痛点
- 传统 px 硬写:不同手机宽度(320/375/414px),元素要么挤要么空,无法等比缩放。
- 早期 rem + flexible 方案 :
- 依赖 JS 动态改 html 字体大小,可能闪屏、布局抖动。
- 媒体查询、CSS 变量、Grid 等新特性兼容差。
- vw 原生方案崛起 :
- CSS3 原生单位:
1vw = 视口宽度的 1%,纯 CSS、无 JS、适配精准。 - 但手动把设计稿 px 算成 vw(如 750px 稿 → 100px = 13.333vw),重复易错。
- CSS3 原生单位:
→ 于是出现:用工具自动做 px → vw 计算 ,postcss-px-to-viewport 是其中最主流的一款。
二、核心原理
-
工具定位:PostCSS 是 CSS 编译工具链(类似 Babel 对 JS),插件在编译阶段处理 CSS 文本。
-
转换公式 :
plaintext
vw 值 = px 值 / 设计稿宽度 × 100例:设计稿 750px,
width: 375px→ 375 / 750 × 100 = 50vw。 -
开发 / 编译分离 :
- 开发:按设计稿直接写 px(如 750px 稿写 32px 字体),不用管适配。
- 编译:插件自动转 vw,浏览器直接识别 vw,自动适配屏幕。
三、插件发展与版本
- 原版(2017 年):evrone/postcss-px-to-viewport,不再维护,仅支持 PostCSS 7 及以下。
- 社区 fork 版(常用) :
postcss-px-to-viewport:wangjinyang 维护,Vue2 常用。postcss-px-to-viewport-8-plugin:适配 PostCSS 8,解决 Vue3 / 新版 CLI 报错。cnjm-postcss-px-to-viewport:增强版,支持 include/exclude 更灵活。
四、与 rem 方案对比(为什么选它)
表格
| 对比项 | postcss-px-to-viewport(vw) | rem + flexible |
|---|---|---|
| 依赖 JS | ❌ 纯 CSS | ✅ 需头部 JS 改根字体 |
| 适配精度 | 高(原生视口单位) | 一般(依赖字体计算) |
| 媒体查询 | 原生支持 | 计算复杂 |
| 新特性兼容 | 好(CSS 变量 / Grid) | 差 |
| 开发体验 | 直接写 px,无感知 | 需换算 rem,易出错 |
→ 结论:vw 方案是现在移动端适配的主流首选。
五、Vue2 中的定位
Vue2(Webpack/Vue CLI)项目中,它是 CSS 编译链的一环:
- 配置:
postcss.config.js或vue.config.js里声明插件。 - 流程:
.vue文件<style>→ PostCSS → 插件转 px 为 vw → 浏览器渲染。 - 优势:不侵入业务代码,仅影响编译阶段,Vue2/Vue3 通用。
六、一句话总结
它是解决移动端适配的 "编译期神器":把设计师给的 px 设计稿,自动转成浏览器能理解的 vw,告别手动计算、告别 JS 依赖,一套代码适配所有手机电脑。
使用步骤
1.首先安装依赖
postcss-px-to-viewport@1.1.1 --save-dev
npm install postcss --save-dev //Vue 2 项目中,其实不需要手动 `npm install postcss`,因为 @vue/cli-service 内部已经依赖了 postcss。
2.进行配置
vue.config.js 补充配置(Vue CLI 必配)
css: {
loaderOptions: {
less: {
// ... 你的 less 配置
},
postcss: {
plugins: [
require('postcss-px-to-viewport')({
unitToConvert: 'px', // (字符串)需要转换的单位,默认为 'px' viewportWidth: 1920, // (数字|函数)设计稿宽度,请根据实际填写 unitPrecision: 5, // (数字)转换后的值保留的小数位数 propList: ['*'], // (数组)能转换为 vw 的属性列表,['*'] 代表全部 viewportUnit: 'vw', // (字符串)转换后使用的视口单位 fontViewportUnit: 'vw', // (字符串)字体转换后使用的视口单位 selectorBlackList: [], // (数组)需要忽略的 CSS 选择器,保留 px minPixelValue: 1, // (数字)小于或等于该值,不进行转换 mediaQuery: false, // (布尔值)是否在媒体查询中也进行转换 replace: true, // (布尔值)是否直接替换原值,而非添加备用值 exclude: undefined, // (正则|数组)忽略某些文件夹,如 /node_modules/ include: undefined, // (正则|数组)只对匹配到的文件进行转换 landscape: false, // (布尔值)是否自动添加横屏 (@media) 样式 landscapeUnit: 'vw', // (字符串)横屏时使用的单位 landscapeWidth: 1920 // (数字)横屏时使用的视口宽度 }) ] } } }
3.项目中使用
直接在样式写设计稿 px,打包自动转 vw,切记不要写行内样式
.box1{
width: 100px;
height: 100px;
background-color: red;
}
这样就能直接在项目中使用了,检查方法,设置完元素px,在审查中如果是vw就是成功了

4.常见问题
- 不生效:重启项目、删除 node_modules/.cache 缓存
- 字体错乱:
fontViewportUnit: 'vw'不要改 rem - 边框 1px 异常:
minPixelValue: 2
5.额外提示:行内忽略转换
如果某一行或某一个样式不想被这个插件转换(例如需要保留原始的 px 作为特殊边界),可以使用特殊注释:
-
/* px-to-viewport-ignore-next */:放在单独一行,让它下一行的样式不被转换。 -
/* px-to-viewport-ignore */:放在样式属性后面,让这一条属性不被转换。