文章目录
简介
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中,会导致无法获取浏览器实际宽高而导致页面缩放不正常,解决方案待补充。