移动端适配

移动端适配

本文来一起探讨一下移动端有哪些比较好的适配方案。

1.postCSS

在做移动端适配的时候,避免不了这个插件的使用。如果你使用的是vite进行构建的话,则直接在根目录创建一个postcss.config.js即可。

2.方案一:VW

vw方案使用 postcss-px-to-viewport 插件将 px 单位转化为 vw/vh 单位

npm i postcss-px-to-viewport -D
// postcss.config.cjs

module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375,
    },
  },
};

别急,你以为就这样完事了吗,并没有。上面只是对设计稿尺寸为 375 的进行转换( vant 设计稿尺寸是 375 🤦‍♂️),但是我们大部分设计稿尺寸都是 750 ,所以需要额外对 750 尺寸的进行处理。

那么问题来了,怎么配置多个尺寸呢,postcss-px-to-viewport 文档并没有指明,自己尝试解决吧🤷‍♂️

由于 postcss-px-to-viewport 没有提供类似 postcss-pxtoremrootValue({ file }) {} 的方法,即便使用 module.exports = (param) => {} 这种方式导出postcss配置,也拿不到当前转换文件的信息,所以无法根据文件路径动态设置 viewportWidth

有一种hack方式:通过多次 px2viewport() 处理不同文件来设置viewportWidth😎

// postcss.config.cjs

const px2viewport = require('postcss-px-to-viewport');

plugins: [
  px2viewport({
    // vant
    viewportWidth: 375,
    exclude: [/^(?!.*node_modules\/vant)/],
    // include: [/node_modules\/vant/],
  }),
  px2viewport({
    // 非vant
    viewportWidth: 750,
    exclude: [/node_modules\/vant/],
  }),
],

第一个处理 vant 的 px2viewport 为什么不用include选项呢?

因为 postcss-px-to-viewport v1.1.1 不支持 include 配置项,v1.2.0 开始加入include,但是并没有发布到npm仓库🤦‍♂️

并且由于 postcss-px-to-viewport 不支持 postcss 8.x ,而vite内置postcss 8.x,所以使用postcss-px-to-viewport会抛出警告🤦‍♂️

改用 postcss-px-to-viewport-8-plugin 替代,既支持 include 配置项,也支持postcss 8.x

我太难了兄弟萌😭

最终完整的postcss.config代码为:

// postcss.config.cjs

const autoprefixer = require('autoprefixer');
const px2viewport = require('postcss-px-to-viewport-8-plugin');

const basePx2viewport = {
  unitToConvert: 'px', // 需要转换的单位,默认为 px
  // viewportWidth: 750, // 设计稿的视口宽度
  unitPrecision: 3, // 单位转换后保留的精度(很多时候无法整除)
  propList: [
    '*',
    //  '!font-size'
  ], // 能转化为vw的属性列表,!font-size表示font-size后面的单位不会被转换
  viewportUnit: 'vw', // 指定需要转换成的视口单位,建议使用 vw
  fontViewportUnit: 'vw', // 字体使用的视口单位
  // 指定不转换为视口单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
  // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
  // 下面配置表示类名中含有'keep-px'以及'.ignore'类都不会被转换
  selectorBlackList: ['.ignore', 'keep-px'],
  minPixelValue: 1, // 设置最小的转换数值,这里小于或等于 1px 不转换为视口单位
  mediaQuery: false, // 媒体查询里的单位是否需要转换单位
  // exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件
  // include: [/src/], // 如果设置了include,那将只有匹配到的文件才会被转换
};

module.exports = {
  plugins: [
    autoprefixer(),
    // vant
    px2viewport({
      ...basePx2viewport,
      viewportWidth: 375,
      exclude: [/^(?!.*node_modules\/vant)/],
      // include: [/node_modules\/vant/],
    }),
    // 非vant
    px2viewport({
      ...basePx2viewport,
      viewportWidth: 750,
      exclude: [/node_modules\/vant/],
    }),
  ],
};

3.方案二:rem方案

rem方案使用 postcss-pxtorem 插件将 px 单位转化为 rem 单位,并且用 lib-flexible 设置rem基准值

尽管连 lib-flexible 自己都建议使用vw方案:

由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。

但 vw 方案 还是有缺点的。如 vw 方案不适合大屏,因为 vw 是一个比例单位,随着屏幕尺寸变大,使用vw单位的元素、字体也越来越大。但我们肯定是希望在大屏上展示更多的内容,而不是更大的文字、图标。

由于我们的产品使用场景包括手机和平板等设备,所以必须考虑大屏的适配。我曾经尝试过使用 scalezoom 的方式,将大屏上的元素按比例缩小,但是效果都不太理想。最后还是选择 rem方案,因为 rem方案 可以通过媒体查询来限制基准值(根字体)大小。

配置rem方案就简单多了😅

  1. 引入 lib-flexible
npm i amfe-flexible
// src/main.ts

import 'amfe-flexible';
  1. 引入 postcss-pxtorem
npm i postcss-pxtorem -D
// postcss.config.cjs

const autoprefixer = require('autoprefixer');
const pxtorem = require('postcss-pxtorem');

module.exports = {
  plugins: [
    autoprefixer(),
    pxtorem({
      rootValue({ file }) {
        return file.indexOf('node_modules/vant') !== -1 ? 37.5 : 75;
      },
      unitPrecision: 5,
      propList: ['*'],
      selectorBlackList: ['.ignore', 'keep-px'],
      minPixelValue: 1,
      mediaQuery: false,
    }),
  ],
};

特别注意:

如果用vant官网示例 file.indexOf('vant') 来匹配文件,请==确保你的项目名或文件名==没有包含’vant’
建议改为 file.indexOf('node_modules/vant')

一开始写这篇文章时写的demo项目我没注意,用的vant官网示例 file.indexOf('vant') 匹配文件,后来发现怎么转换 rem 单位不对劲,找了半天才发现原来我项目命名为 vue3-vant-mobile,导致 rootValue 一直为 37.5 😓

  1. 创建 response.less 文件,限制根字体最大值
// src/styles/response.less

// prettier-ignore 忽略prettier对 PX 的自动格式化
// !important 提高权重,使其覆盖 lib-flexible 设置的font-size

@media screen and (min-width: 768px) {
  html {
    /* prettier-ignore */
    font-size: 50PX !important;
  }
}
超过了768px就写死字体大小。

这里只是由于插件问题导致vw方案比rem方案配置起来麻烦许多,本身vwrem方案没有偶孰强孰弱之分,大家看自己需求选择即可✌️

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值