最近在做屏幕适配,一套代码需要适配不同分辨率和不同缩放比例情况下的样式兼容
在实现的过程中遇到了这样几个问题:
- 为什么要用rem做适配?
- 按照之前vue cli脚手架的配置
pxtorem
方法进行配置,在webpack中不生效? - 配置
postcss-loader
运行时会有报错,怎么解决? - 行内样式写的px单位没有转化为rem,无法适配该怎么解决?
本文将会根据这几个问题进行汇总给出解决方案
为什么要用rem做适配?
要想了解为什么要用rem做适配就要先了解px
、rpx
、rem
的特点和区别:
-
px:
px
(像素) 是一个绝对单位,表示屏幕上的一个物理像素点。- 在不同的设备上,
px
实际表示的大小是固定的,不考虑设备的分辨率或用户缩放设置。 - 由于像素密度的差异,相同数量的
px
在不同的屏幕上可能会显示得更大或更小。
-
rpx:
rpx
(responsive pixel) 是特定于微信小程序的响应式单位,用于适应不同宽度的屏幕。- 在微信小程序中,屏幕宽度为750rpx,因此1rpx等于屏幕宽度的1/750。
rpx
主要用于在不同宽度的手机上保持元素的相对大小一致。
-
rem (根相对长度单位):
rem
是一个相对单位,相对于 HTML 根元素的字体大小。- 使用
rem
可以创建一个基于根元素字体大小的响应式布局,通过改变根元素的字体大小,可以影响整个页面的尺寸比例。 rem
适合用于响应式设计,因为它允许页面布局根据用户的默认字体大小或特定需求进行缩放。
总结:
px
适合用于需要固定像素精度的图像和布局。rpx
特定于微信小程序,用于不同屏幕宽度的响应式设计。rem
适合用于整个页面或组件的响应式布局,基于根元素字体大小。
我们开发的项目主要用在教室大屏和办公室大屏的特殊设备上,系统可以设置2k,3k,4k分辨率,而且还有可能会有缩放,如果要使用px,在设置不同的分辨率下样式会有错误,而使用%或者vw/vh计算会变得更复杂
pxtorem 使用方式
之前使用的是vue cli和vite脚手架搭建的项目,只需要按照官网的配置即可,但是目前做的是老项目,使用的是webpack,所以使用的方式还有些区别
vite/vue cli中的使用方式
安装配置
安装 postcss-pxtorem
npm install postcss postcss-pxtorem --save-dev
如果你是vue cli创建的项目就在 vue.config.js
文件里进行配置;
如果是vite创建的项目就在 vite.config.js
里进行配置
module.exports = {
// 其他配置...
css: {
loaderOptions: {
postcss: {
plugins: [
require('postcss-pxtorem')({
rootValue: 15, // 换算的基数
unitPrecision: 5, // 允许REM单位增长到的十进制数字
propList: ['*'],
selectorBlackList: [], // 要忽略并保留为px的选择器
ignoreIdentifier: false, // 忽略单个属性的方法
replace: true, // 替换包含REM的规则,而不是添加回退。
mediaQuery: false, // 允许在媒体查询中转换px。
minPixelValue: 0 // 设置要替换的最小像素值(3px会被转rem)。默认 0
}),
]
}
}
}
}
动态配置rem基数
动态调整 rem
基数可以根据屏幕宽度自动缩放页面元素,从而保持布局的一致性和适应性
新建rem.js
window.baseRootValue = 15; // 基准大小,作为行内样式rem调整处理。可统一调整
// 配置基本大小
let baseSize = window.baseRootValue || 15;
// 设置 rem 函数
function setRem () {
//当前页面宽度相对于1920px屏幕宽的缩放比例,可根据自己需要修改。
let scale = document.documentElement.clientWidth / 1920;
//设置页面根节点字体大小(“Math.min(scale, 2)” 指最高放大比例为2,可根据实际业务需求调整)
document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px'
}
setRem(); //初始化
// 适配 - 重置函数
function resetRem (num) {
if(num) baseSize = Number(num);
setRem();
}
window.resetRem = resetRem; // 全局可调用(其他方式也可)
// 改变窗口大小时重置 rem
window.onresize = function () {
setRem()
};
在项目入口(一般都是在main.js)引入 rem.js
文件
import './rem.ts';
这样就可以在页面使用px进行写样式了,运行程序会自动转化为rem
webpack中的使用 pxtorem
webpack中的使用 pxtorem 需要先安装postcss-loader和postcss-pxtorem
安装配置
npm install postcss-loader postcss-pxtorem --save-dev
在 webpack.config.js
文件中,配置 postcss-loader
以使用 postcss-pxtorem
插件。这通常在 module.rules
部分进行配置:
const path = require('path');
module.exports = {
// ... 其他配置
module: {
rules: [
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader"
],
},
{
test: /\.less$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-pxtorem')({
rootValue: 15, // 换算的基数
unitPrecision: 5, // 允许REM单位增长到的十进制数字
propList: ['*'],
selectorBlackList: [], // 要忽略并保留为px的选择器
ignoreIdentifier: false, // 忽略单个属性的方法
replace: true, // 替换包含REM的规则,而不是添加回退。
mediaQuery: false, // 允许在媒体查询中转换px。
minPixelValue: 0 // 设置要替换的最小像素值(3px会被转rem)。默认 0
}),
]
}
}
},
{
loader: 'less-loader',
options: {
lessOptions: {
javascriptEnabled: true
}
}
},
]
},
],
},
plugins: [
// ... 可能存在的其他插件
]
};
需要注意的是:因为loader的规则是链式处理,postcss-loader是处理css的,所以放在css之后,而不是less之后 这个顺序很重要,如果顺序错了,运行时就会报错
动态配置rem基数
动态配置rem基数和上面的一样,这里就不再废话
行内样式px转rem
postcss-pxtorem
插件无法处理 HTML 文件中的行内样式。postcss-pxtorem
主要是在构建过程中处理 CSS 文件和 <style>
标签中的样式。为了解决这个问题,可以手动计算rem值
- 通常,HTML 根元素(
<html>
)的字体大小被设置为一个基准值,比如16px
。这个值将作为1rem
的基准。 - 要将
px
转换为rem
,你需要将px
值除以根元素的字体大小(以px
为单位)。例如,如果根元素的字体大小是16px
,则1rem = 16px
。 - 对于任何给定的
px
值,使用上述比例进行转换。例如,如果一个元素的行内样式是font-size: 32px;
,则转换为rem
是font-size: 2rem;