之前提起移动端适配,都是一些视口的概念,包括物理像素和逻辑像素,理想视口,dpr等等等。利用 media query 和 rem 是最常见的移动端适配方案。如下代码:
const deviceWidth = document.documentElement.clientWidth || document.body.clientWidth;
document.querySelector('html').style.fontSize = deviceWidth / 7.5 + 'px';
在移动端UI稿尺寸为 7501334 满天飞的时代,这两句代码确实给开发者带来了很大的方便,这样设置根font-size后,px 和 rem 的转换比例成了100, 为比如UI稿一个长宽分别为 120px40px,那么开发者对应的写成1.2rem*0.4rem就可以了。后面,甚至诞生了 px-to-rem 或者 px2rem 等开发插件来帮助我们更便捷的做出计算。
**flexible.js是手淘开发出的一个用来适配移动端的js框架。**手淘框架的核心原理就是根据制不同的width给网页中html根节点设置不同的font-size,然后所有的px都用rem来代替,这样就实现了不同大小的屏幕都适应相同的样式了。其实它就是一个终端设备适配的解决方案,也就是说它可以让你在不同的终端设备中实现页面适配。
VSCode 安装插件:
在setting.json中修改cssrem中默认的字体大小,这里以屏幕为750px为例(因为flexible.js默认将屏幕分成十份,所以我们将cssrem.rootFontSize修改为75)
保存之后重新打开vscode
再当我们输入宽度的时候,我就可以看到vscode自动帮我们计算好了对应的rem值,我们只要点击使用就可以了。
可是,随着技术的发展,人们希望有这样一种方案:不想换算,也不想考虑转换系数,更不想借助开发插件转换,就想简简单单的使用一种单位 px,使得 CSS 代码足够简洁。
postcss-px-to-viewport就是这样一款优秀的插件,它将 px 转换成视口单位 vw。众所周知,vw本质上还是一种百分比单位,100vw即等于100%,即 window.innerWidth。
- vw 视口的最大宽度,1vw等于视口宽度的百分之一
- vh 视口的最大高度,1vh等于视口高度的百分之一
安装 postcss-px-to-viewport 插件
yarn add postcss-px-to-viewport -D
Node 版本 v14.18.1
注:Vite 中已经内联了 postcss,所以并不需要额外的创建 postcss.config.js文件。如果是 Webpack ,则需要在项目根目录下添加.postcssrc.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 // 是否处理横屏情况
}
}
};
Vite 项目,直接在 vite.config.js 中配置如下:
import { fileURLToPath, URL } from 'url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import postcsspxtoviewport from "postcss-px-to-viewport" //插件
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
css: {
postcss: {
plugins: [
postcsspxtoviewport({
unitToConvert: 'px', // 要转化的单位
viewportWidth: 750, // UI设计稿的宽度
unitPrecision: 6, // 转换后的精度,即小数点位数
propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: ['ignore-'], // 指定不转换为视窗单位的类名,
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否转换后直接更换属性值
landscape: false // 是否处理横屏情况
})
]
}
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
代码案例: