vue移动端布局适配方案之postcss-px-to-viewport

vue移动端布局适配方案之postcss-px-to-viewport_vue postcss-px-to-viewport-优快云博客

一、前言
在项目中本地开发时使用px,但是界面上线以后,样式需要根据视口大小来调整宽度,我们可以用viewport单位,现在viewport单位越来越受到众多浏览器的支持。它可以将CSS中的px单位转化为视口单位vw,众所周知,vw本质上还是一种百分比单位,100vw即等于100%(1vw等于1/100视口宽度),即window.innerWidth。

二、postcss-px-to-viewport 使用
1、安装
npm install postcss-px-to-viewport --save-dev
1
或者使用yarn进行安装

$ yarn add -D postcss-px-to-viewport
1
2、在项目根目录下添加.postcssrc.js文件或postcss.config.js文件中进行如下配置
module.exports = {
  plugins: {
    autoprefixer: {}, // 用来给不同的浏览器自动添加相应前缀,如-webkit-,-moz-等等
    "postcss-px-to-viewport": {
      unitToConvert: "px", // 要转化的单位
      viewportWidth: 750, // UI设计稿的宽度
      unitPrecision: 6, // 转换后的精度,即小数点位数
      propList: ["*"], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
      viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw
      fontViewportUnit: "vw", // 指定字体需要转换成的视窗单位,默认vw
      selectorBlackList: ["wrap"], // 指定不转换为视窗单位的类名,
      minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
      mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
      replace: true, // 是否转换后直接更换属性值
      exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配
      landscape: false // 是否处理横屏情况
    }
  }
};


项目中用过的配置

// eslint-disable-next-line no-undef
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375
    }
  }
}

3、然后重新运行项目,使配置文件生效。
三、需要注意的配置
propList: 当有些属性的单位我们不希望转换的时候,可以添加在数组后面,并在前面加上!号,如propList: [“*”,“!letter-spacing”],这表示:所有css属性的属性的单位都进行转化,除了letter-spacing的
selectorBlackList:转换的黑名单,在黑名单里面的我们可以写入字符串,只要类名包含有这个字符串,就不会被匹配。比如selectorBlackList: [‘wrap’],它表示形如wrap,my-wrap,wrapper这样的类名的单位,都不会被转换
四、可能遇到的问题
@keyframes 和media查询里的px默认是不转化的,设置mediaQuery: true则媒体查询里也会转换px
@keyframes可以暂时手动填写vw单位的转化结果
五、关于兼容第三方UI库
参考:https://blog.youkuaiyun.com/sinat_17775997/article/details/127101451
当我们引入一些第三方库的时候,比如vant,上面配置的exclude去掉,表示全部内容进行vw转换,会遇到这样的问题,这个TabBar,变得非常的小,被压扁了。
 解决思路:如果读取的是vant相关的文件,viewportWidth就设为375,如果是其他的文件,我们就按照我们UI的宽度来设置viewportWidth,即750。
改写.postcssrc.js文件或者是postcss.config.js文件配置如下:

const path = require('path');
 
module.exports = ({ webpack }) => {
  const designWidth = webpack.resourcePath.includes(path.join('node_modules', 'vant')) ? 375 : 750;
 
  return {
    plugins: {
      autoprefixer: {},
      "postcss-px-to-viewport": {
        unitToConvert: "px",
        viewportWidth: designWidth,
        unitPrecision: 6,
        propList: ["*"],
        viewportUnit: "vw",
        fontViewportUnit: "vw",
        selectorBlackList: [],
        minPixelValue: 1,
        mediaQuery: true,
        exclude: [],
        landscape: false
      }
    }
  }
}


注意:这里使用path.join(‘node_modules’, ‘vant’)是因为适应不同的操作系统,
在mac下结果为node_modules/vant,而在windows下结果为node_modules\vant
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.youkuaiyun.com/HanYaLi39/article/details/136186480

<think>我们被要求比较两个PostCSS插件:postcss-px-to-viewportpostcss-pxtorem 在移动端适配中的优缺点。 根据引用[1][2][3][4],我们可以总结如下: 1. postcss-pxtorem(px转rem): - 原理:将px单位转换为rem单位,依赖于根元素(html)的字体大小(如37.5px,即1rem=37.5px)[^2]。 - 优点: - 兼容性好,支持老版本浏览器。 - 配置相对简单,通过rootValue设置基准值。 - 缺点: - 无法转换内联样式和JS中动态设置的样式(需要额外手动处理)[^1]。 - 需要配合flexible.js等动态设置根字体大小的库(如amfe-flexible)来实现不同设备的适配。 - 多层嵌套时计算rem可能会复杂。 2. postcss-px-to-viewportpx转vw): - 原理:将px单位直接转换为vw单位(1vw等于视口宽度的1%)[^3]。 - 优点: - 直接相对于视口宽度,无需额外JS库(纯CSS方案)。 - 能够避免多层嵌套带来的计算问题。 -移动端适配中更直观,设计稿通常以750px宽度(即100vw=750px,1px=0.1333vw)[^3]。 - 缺点: - 兼容性不如rem(vw单位在部分老浏览器不支持,如iOS 8以下、Android 4.4以下)。 - 无法转换内联样式和JS动态样式(同样需要手动处理)。 共同点: - 两者都是PostCSS插件,配置方式类似。 - 都支持通过exclude选项排除特定文件或目录(如排除node_modules中的第三方库)[参考之前讨论]。 - 都无法处理内联样式和JS中设置的样式,需要开发者额外处理(如使用全局函数转换)[^1]。 针对内联样式和JS动态样式的解决方案(两者都需要): 如引用[1]所示,可以定义一个全局函数(例如px2rem或px2vw)在JS中进行转换,并在需要的地方调用。 总结: - 如果项目需要支持老版本浏览器,选择rem方案(postcss-pxtorem)更稳妥。 - 如果项目面向现代浏览器,追求简洁和未来趋势,vw方案(postcss-px-to-viewport)是更好的选择。 配置示例: postcss-pxtorem (rem方案): ```js "postcss-pxtorem": { rootValue: 37.5, // 设计稿宽度/10(如设计稿750px,则750/10=75;但vant推荐37.5,因为vant基于375设计) propList: ['*'], // 需要转换的属性,*表示所有 exclude: /node_modules\/vant/i // 排除vant,因为vant有自己的适配方案 } ``` postcss-px-to-viewport (vw方案): ```js "postcss-px-to-viewport": { unitToConvert: 'px', // 要转换的单位 viewportWidth: 750, // 设计稿的视口宽度(如果是750px的设计稿) unitPrecision: 5, // 转换后的单位精度 propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换 viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw fontViewportUnit: 'vw', // 字体使用的视口单位 selectorBlackList: [], // 指定不转换为视窗单位的类名 minPixelValue: 1, // 最小转换数值,小于1px不转换 mediaQuery: false, // 媒体查询里的单位是否需要转换单位 replace: true, // 是否直接更换属性值,而不添加备用属性 exclude: [/node_modules\/vant/], // 排除vant include: undefined, // 包含某些文件 landscape: false, // 是否添加根据landscapeWidth生成的媒体查询条件 landscapeUnit: 'vw', // 横屏时使用的单位 landscapeWidth: 1334 // 横屏时使用的视口宽度 } ``` 注意:在配置中排除第三方库(如vant)非常重要,因为它们可能已经做了适配处理,避免重复转换。 相关问题: 1. 如何解决内联样式和JS动态样式的单位转换问题? 2.移动端适配中,如何选择rem和vw方案? 3. 如何配置postcss-px-to-viewport来适配750px设计稿? 4. 为什么需要排除node_modules中的某些库(如vant)? 根据以上分析,我们可以生成相关问题。</think>### postcss-px-to-viewport vs postcss-pxtorem:移动端适配对比 #### 1. 核心原理对比 | **特性** | **postcss-px-to-viewport** | **postcss-pxtorem** | |------------------------|-----------------------------------------------|----------------------------------------------| | **转换单位** | px → vw/vh(视口单位) | px → rem(相对根字体单位) | | **依赖关系** | 纯CSS实现,不依赖JS | 需配合`amfe-flexible`等JS库动态计算根字体大小[^1] | | **设计稿基准** | 直接基于视口宽度(如750px设计稿=100vw)[^3] | 基于rootValue(如37.5px = 1rem)[^2] | | **计算方式** | `px值 / (设计稿宽度/100)` → vw | `px值 / rootValue` → rem | #### 2. 优点对比 **postcss-px-to-viewport优势**: ```js // 配置示例(750px设计稿) { viewportWidth: 750, // 设计稿宽度 viewportUnit: 'vw', // 输出单位 unitPrecision: 5, // 小数精度 selectorBlackList: ['.ignore'] // 忽略选择器 } ``` - ✅ **纯CSS方案**:无需JS运行时计算,减少性能开销 - ✅ **精确视口适配**:元素大小严格比例于屏幕宽度 - ✅ **简化嵌套计算**:避免rem多层嵌套导致的复合计算问题 **postcss-pxtorem优势**: ```js // 配置示例 { rootValue: 37.5, // 1rem = 37.5px propList: ['*'], // 转换所有属性 minPixelValue: 2 // 最小转换值 } ``` - ✅ **兼容性更好**:支持iOS 8+/Android 4.4+等老设备[^4] - ✅ **动态调整灵活**:JS可实时修改根字体大小 - ✅ **社区方案成熟**:长期使用的稳定方案(如vant组件库默认方案) #### 3. 缺点对比 **共同缺点**: - ❌ **无法转换内联样式**:JS中`style="width:100px"`需手动处理[^1] - ❌ **第三方库适配问题**:需排除已适配的UI库(如vant)[参考正则方案] **postcss-px-to-viewport局限**: - ❌ 兼容性问题:vw单位在iOS 8以下不支持 - ❌ 横屏适配复杂:需额外配置`landscapeWidth` **postcss-pxtorem局限**: - ❌ **JS依赖**:必须引入`flexible.js`等脚本 - ❌ **字体缩放问题**:系统字体设置会影响布局 - ❌ **计算复杂度**:嵌套元素需叠加计算(如rem×rem) #### 4. 最佳实践场景 | **场景** | **推荐方案** | **原因** | |---------------------------|---------------------------|---------------------------------------------| | 新项目(无需兼容老设备) | postcss-px-to-viewport | 简洁高效,符合未来标准 | | 老项目维护/兼容低端设备 | postcss-pxtorem | 兼容性保障,平滑过渡 | | UI组件库开发 | postcss-pxtorem | 避免vw单位被外部覆盖 | | 全屏响应式页面 | postcss-px-to-viewport | 精确响应视口变化 | #### 5. 配置注意事项 1. **通用排除规则**(两者都需要): ```js exclude: [ /node_modules[\\/]vant/, // 排除vant /\.min\.css$/ // 排除压缩文件 ] ``` 2. **内联样式解决方案**: ```js // 全局添加转换方法(main.jsVue.prototype.$px2vw = (px) => { return `${(px / 750 * 100).toFixed(5)}vw` } // 使用: <div :style="{ width: $px2vw(100) }"></div> ``` 3. **1px边框特殊处理**: ```css /* 在配置中添加忽略 */ selectorBlackList: ['.hairline'] ``` ```html <div class="hairline">/* 物理像素边框 */</div> ``` #### 总结建议 - **追求现代化和性能** → 选择`postcss-px-to-viewport` - **需要广泛兼容性** → 选择`postcss-pxtorem` - **混合使用策略**:核心布局用vw,字体大小用rem(通过`propList`控制) > 两种方案都需配合`postcss.config.js`配置和设计稿规范(推荐750px宽度)[^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值