Rem + PostCSS插件
使用PostCSS插件将项目中的px单位自动转换为rem,搭配JS动态设置根字体大小(监听window.resize)。
vite配置
json
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import pxtorem from 'postcss-pxtorem'
// https://vite.dev/config/
export default defineConfig({
plugins: [vue()],
css: {
postcss:{
plugins: [
pxtorem({
rootValue: 75,//根据设计稿进行配置,如果设计稿宽度为750则配置75
propList: ['*'],
unitPrecision: 5,
minPixelValue: 2,
exclude: /node_modules/i,
}),
],
}
},
})
配合的js代码,监听视口变化改变根元素大小
js
// 处理各机型适配的fontsize
function handleRem() {
const baseSize = 75;// 与postcss配置中的rootValue保持一致
const scale = document.documentElement.clientWidth / 750;
document.documentElement.style.fontSize =
baseSize * Math.min(scale, 2) + 'px';
}
// 初始化设置根元素的值
handleRem()
// 监听窗口变化,根据窗口变化来改变根元素的值
window.addEventListener('resize', handleRem)
Viewport单位
使用纯CSS的视口单位(vw, vh)进行布局,视口变化时元素尺寸自动缩放
vite配置
json
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import postcsspxtoviewport from 'postcss-px-to-viewport'
export default defineConfig({
plugins: [vue()],
css: {
postcss: {
plugins: [
postcsspxtoviewport({
unitToConvert: 'px', // 要转换的单位
viewportWidth: 750, // 设计稿的视口宽度,一般是375
unitPrecision: 5, // 转换后的精度,即小数点位数
propList: ['*'], // 指定转换的CSS属性的单位,*代表全部css属性都转换
viewportUnit: 'vw', // 指定需要转换成的视口单位,建议使用vw
fontViewportUnit: 'vw', // 字体使用的视口单位
selectorBlackList: ['.ignore-'], // 指定不转换为视口单位的类名
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
mediaQuery: false, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否直接更换属性值,而不添加备用属性
exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件
})
]
}
}
})
Flexible / Rem
淘宝旧方案,通过JS模拟viewport和rem,主要解决过去移动端高清屏的适配问题。没有具体实践过
针对特殊情况进行处理
以下两种方案均适配上面的Rem + PostCSS插件和Viewport单位 比如场景:滚动到遮住头部组件的位置,头部位置在设计稿上是150px,这种怎么实现
- 方案1:就是通过offsetHeight,直接获取到针对于不同机型上真实的px值
- 方案2:使用方法进行转,直接传入设计稿上的高度就完事,会自动适配出对应px然后进行scrolltop的赋值即可
js
// 根据设计稿上的px,计算出当前设备真实适配的 px 值
/**
* @param px 设计稿的px值
* @param isFormat 是否返回带px单位的字符串,默认true
* @param designWidth 设计稿的宽度,默认750px,根据实际情况修改
* @returns 适配后的px值
* */
export const pxValueToPx = (px: number, isFormat: boolean = true, designWidth: number = 750) => {
// 基准设计稿宽度(通常为 750px)
const _designWidth = designWidth;
// 获取当前设备的屏幕宽度
const windowWidth = document.documentElement.clientWidth;
// 计算缩放比例
const scale = windowWidth / _designWidth;
// 返回自适应后的 px 值
return isFormat ? `${px * scale}px` : px * scale;
}