PostCSS CSS转换工具插件:postcss‑px‑to‑viewport‑8‑plugin 作者:马育民 • 2026-08-10 08:35 • 阅读:10000 # 介绍 `postcss‑px‑to‑viewport‑8‑plugin` 是 **[PostCSS 8](http://www.malaoshi.top/show_1GW3pq6XVrx9.html "PostCSS 8") 专用的 px 转视口单位插件**,用于 H5/移动端自适应,编译阶段把 CSS 里的 `px` 自动转为 `vw/vh/vmin/vmax`,实现一套设计稿多设备适配。 ### 背景 原版 `postcss‑px‑to‑viewport` 只支持 PostCSS7,升级 PostCSS8 会报 `postcss.plugin was deprecated` 废弃警告;本插件就是为兼容 PostCSS8 重写,**API 和原版完全一致,可以直接替换**。 **适用场景**:Vue3 + Vite、React + Vite、Webpack5 现代前端项目。 > ⚠️版本要求:`postcss >= 8.3.8`,低版本不会转换单位。 # 安装 ### npm ```bash npm install postcss-px-to-viewport-8-plugin -D ``` ### pnpm ``` pnpm add postcss-px-to-viewport-8-plugin -D ``` # 全部配置参数对照表 | 参数 | 类型 | 默认值 | 说明 | |---|---|---|---| | `unitToConvert` | string | `px` | 需要转换的单位,一般就是px | | `viewportWidth` | number\|Function | `320` | **设计稿宽度**(750/375/1920);支持函数,传入文件路径,返回数值;返回`undefined`跳过该文件转换 | | `unitPrecision` | number | `5` | 转换后保留小数位数 | | `propList` | string[] | `['*']` | 需要转换的属性;`*`全部;`!xxx`排除;例:`['*','!border']` | | `viewportUnit` | string | `vw` | 转换目标单位:`vw/vh/vmin/vmax` | | `fontViewportUnit` | string | `vw` | 字体单独使用的视口单位 | | `selectorBlackList` | string[] | `[]` | 类名黑名单,匹配的类不转换;写完整类名,支持前缀匹配 | | `minPixelValue` | number | `1` | 小于等于该值的px不转换;`1px`边框场景常用 | | `mediaQuery` | boolean | `false` | 是否转换媒体查询内部的px | | `replace` | boolean | `true` | true直接替换px;false保留原px,追加转换后属性 | | `exclude` | RegExp\|RegExp[] | `undefined` | 排除哪些文件不处理,正则匹配文件路径 | | `include` | RegExp\|RegExp[] | `undefined` | 只处理匹配的文件;`exclude`优先级高于`include` | | `landscape` | boolean | `false` | 是否生成横屏媒体查询 | | `landscapeUnit` | string | `vw` | 横屏使用单位 | | `landscapeWidth` | number | `568` | 横屏基准视口宽度 | ### propList 语法规则 1. `['*']` → 所有属性都转换 2. `['width','height']` → 只转换width、height 3. `['*','!font-size']` → 全部属性,排除font‑size # 两种配置方式 ### 方式1:postcss.config.js(推荐) 独立配置文件,推荐 ```js module.exports = { plugins: { autoprefixer: {}, 'postcss-px-to-viewport-8-plugin': { unitToConvert: 'px', viewportWidth: 750, // 设计稿750 unitPrecision: 4, propList: ['*'], viewportUnit: 'vw', fontViewportUnit: 'vw', selectorBlackList: ['.no‑convert'], // class="no‑convert"不转换 minPixelValue: 1, mediaQuery: false, replace: true, exclude: [/node_modules/] // 不转换第三方组件库 } } } ``` ### 方式2:Vite 内联配置 vite.config.ts ```ts import { defineConfig } from 'vite' import postcsspxtoviewport8plugin from 'postcss-px-to-viewport-8-plugin' export default defineConfig({ css: { postcss: { plugins: [ postcsspxtoviewport8plugin({ viewportWidth: 750, unitPrecision:4, propList:['*'], exclude:[/node_modules/] }) ] } } }) ``` # 代码忽略转换 局部不转换px ### 1. 当前属性不转换 ```css .box { width:100px; /* px-to-viewport-ignore */ } ``` ### 2. 下一行不转换 ```css .box { /* px-to-viewport-ignore-next */ height:200px; } ``` ### 转换示例 输入: ```css .demo { width:750px; font-size:28px; } ``` 输出(viewportWidth=750): ```css .demo { width:100vw; font-size:3.73333vw; } ``` # 常见坑与最佳实践 1. **第三方UI库单位错乱** - 方案:`exclude:[/node_modules/]`;如果UI库设计稿基准是375,利用`viewportWidth`函数动态返回不同设计稿宽度。 ```js viewportWidth: (file)=>{ if(file.includes('node_modules/vant')) return 375 return 750 } ``` 2. **1px边框被转成vw,边框过细** - 设置`minPixelValue:1`,≤1px不做转换。 3. **字体跟随屏幕无限放大缩小** - 方案1:`propList:['*','!font‑size']`字体不转换,写死px; - 方案2:`fontViewportUnit:'rem'`字体使用rem。 4. **媒体查询内部px不转换** - 将`mediaQuery:true`开启。 5. **vite不生效排查** - postcss版本必须≥8.3.8;确认配置文件位置;缓存清除重启dev服务。 原文出处:/show_1GW3pqC6SmvL.html