屏幕适配方案 - postcss-pxtorem

简介

postcss-pxtorem是一个PostCSS插件,用于将CSS中的像素值转换为rem单位,已实现响应式布局和适配不同屏幕尺寸的需求。
它的适配原理是将CSS中的像素值除以一个基准值,通常是设计稿的宽度,然后将结果转换为rem单位。这样,不同屏幕尺寸下,rem单位的大小是相同的,从而实现了响应式布局和适配的效果。

安装和配置

安装插件

// npm
npm install postcss-pxtorem --save-dev

// yarn
yarn add postcss-pxtorem --save-dev

配置插件

1、配置postcss.config.js

在项目根目录创建文件postcss.config.js ;
按需输入以下内容:

export default {
  plugins: {
    ...,    // 其他配置
    'postcss-pxtorem': {
      rootValue: 16, // 根元素字体大小,rem相对px转换的基准值,通常为16px
      propList: ['*'], // 需要转换的属性,* 表示对所有属性都进行转换,支持数组、正则等方式
      unitPrecision: 5, // 允许REM单位增长到的最接近的小数点精度
      selectorBlackList: [], // 排除不进行转换的类名
      replace: true, // 是否直接替换(默认为true)
      mediaQuery: false, // 是否转换媒体查询中的px(默认为false)
      exclude: (path) => { // 不进行转换的文件路径(根据返回值判断,返回值为false则此文件不进行转换)
        // return !path.includes('/views/system-dashboard')
      },
    },
  },
}

2、配置vue.config.js / vite.config.js
export default ({ mode }: ConfigEnv): UserConfigExport => {
  ..., // 其他配置
  css: {
    loaderOptions: {
      postcss: {
        config: {
          path: './postcss.config.js',
        }
      }
    }
  }
}


3、新建文件 utils/rem.js
/** 基准大小 */
const baseSize = 16

function setRem() {
  const scale = document.documentElement.clientWidth / 1920
  const fontSize = baseSize * Math.min(scale, 2) > 12 ? baseSize * Math.min(scale, 2) : 12
  document.documentElement.style.fontSize = `${fontSize}px`
}

// 初始化
setRem()

// 改变窗口大小时重新设置rem
window.onresize = function () {
  setRem()
}

main.js中引入文件

...
import '@/utils/rem'

配置以后,项目中CSS文件的px单位就会自动转换为rem单位。

缺陷和补充

此插件不会自动转换以下样式:

1. 行内样式

<div style="width: 100px;"></div>

2. js中手动添加的样式

// js中为元素添加的样式
const el = document.querySelector('.test');
el.style.width = '100px'; // 不转换

// echarts图表配置中的字号、元素大小等
chartObj.setOption({
    ...,
    label: {
        fontSize: 16, // 不转换
    },
    symbolSize: [20, 20], // 不转换
})

3.属性值在配置项的 selectorBlackList 中

// postcss.config.js
plugin: [
  'postcss-pxtorem': {
      selectorBlackList: ['.ignore', /^body$/] // 忽略 .ignore 类和 body 元素
  }
]
.ignore { width: 100px; }  /* 不转换 */
body { font-size: 16px; }   /* 不转换 */

4.大写的px单位

body { font-size: 16PX; }   /* 不转换 */

对于js中手动添加的样式,可以使用工具函数进行处理:

/**
 * @description: 将px转换为rem值
 * @param {number} px
 * @return {*}
 */
export function pxToRem(px: number) {
  // 获取根元素的字体大小(默认16px)
  const rootFontSize = 16/**
 * @description: 将px转换为rem值
 * @param {number} px
 * @return {*}
 */
export function pxToRem(px: number) {
  // 获取根元素的字体大小(默认16px)
  const rootFontSize = 16

  // 计算rem值(可保留4位小数)
  return `${Number((px / rootFontSize).toFixed(5))}rem`
}


// 使用
const el = document.querySelector('.test');
el.style.width = pxToRem(100); // 将宽度100px转换为rem单位


  // 计算rem值(可保留4位小数)
  return `${Number((px / rootFontSize).toFixed(5))}rem`
}


// 使用
const el = document.querySelector('.test');
el.style.width = pxToRem(100); // 将宽度100px转换为rem单位

对于echarts中添加的样式,可以使用工具函数进行处理:

/**
 * @description: echart字体大小转换工具函数,适配不同屏幕尺寸的图表字体大小调整。

 * @param {number} size
 * @return {*}
 */
export function chartpxToRem(size: number) {
  const clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
  if (!clientWidth) { return size }
  const fontSize = clientWidth / 1920
  return size * fontSize
}

// 使用
chartObj.setOption({
    ...,
    label: {
        fontSize: chartpxToRem(14), // 使用工具函数处理图表的字号
    },
    symbolSize: [chartpxToRem(20), chartpxToRem(20)], // 使用工具函数处理图表元素的宽高
    ...
});

若页面被嵌入到iframe中,会导致无法获取浏览器实际宽高而导致页面缩放不正常,解决方案待补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值