对postcss-pxtorem的理解

1,748 阅读7分钟

插入一个题外bug

问题一:在vite + vue3 + postcss-pxtorem + vant 中,在本地运行时样式正常,提交代码到测试分支之后,样式错乱,vant组件的字体都大了一倍。

查阅了vant的官方文档,在浏览器自适应中看到vant推荐使用 postcss-px-to-viewport 进行转换。 vant的作者设计稿是按照375来的,我们公司的设计稿尺寸一般都是750,所以需要做一个配置

image.png

正题

一、单位:

相对单位:

相对单位
缩写px(pixel)emrem%
释义px是css的像素单位,是一个相对单位,相对的是设备像素单位(物理像素),在不同设备之间1个px所代表的的物理学像素是可变的1em相当于当前的字体尺寸,如果当前元素的父元素设置了font-size,则em参考元素为其父元素,若没有,则逐渐向上找,若果一直找不到,则默认是浏览器的大小就是root rem, 1rem = 根html的字体大小,块级元素默认宽度100%,height 0,不设置宽会自动铺满,浏览器则不计算高度,当不设置高度时,height: 100% 是相对父元素来说的,因为找不到父元素高度,所以100%不起作原因

html、body的宽度则是指网页正文内容的实际宽度,浏览器窗口宽度是滚动条 + 浏览器边框之和

二、当前移动端比较流行的适配方式有:

1、postcss-pxtorem + amfe-flexible

postcss-pxtorem用于将px转rem,amfe-flexible用来动态设置HTML的字体大小,去适配不同大小的屏幕。

第一步: 先安装postcss-pxtorem,然后在根目录建立一个文件名为postcss.config.js的文件,加入以下配置, rootVlue可以随意设置

搭配amfe-flexible插件来使用的话,rootValue是值就是设计稿的尺寸除以10,我们公司设设计稿一般是750,所以这里设置75

image.png

第二步:配置好之后上面的文件,在main.ts文件引入amfe-flexible这个插件就可以啦

第三步: 开始在less文件中编写样式

@bg: black;
.text1{
    font-size: 36px;
    color:@bg
}

运行之后:

@bg: black;
.text1{
    font-size: 0.48rem;
    color:@bg
}

这里展示一下amfe-flexible的源码,他是以10作为基数来计算

当设计稿为750的时候,把设计稿分成10份,那么根html的节点1rem = 75px, 这里html根字体大小不管怎么改变,都是初始值75的倍数

核心代码就是这段

image.png

假如设备窗口是393px,amfe-flexible的源码是 393/10 = 39.3,也可以这么计算, (393/750)* 75 = 39.3(不管怎么改变,都是初始值75的倍数)

image.png

举例 n = 16,设置rootValue 为16

假设n = 16

如果n设置为16,不是一个倍数关系,那么就不能使用amfe-flexible来动态改变html根节点的大小。

在postcss.fonfig.js中把rootValue设置为16

image.png

新建一个flexible.js文件,在main.ts中引入,这个文件的作用和amfe-flexible的作用想通,用来动态设置html字体大小。 其实核心原理就是比例相同,通过动态设置html的字体大小去达到自适应的效果

image.png

也可以这样写 更容易理解一些(就是去更改16倍数,不管html根字体大小怎么变,都是16的倍数):

image.png 按照750的设计稿尺寸,代码正常编写px,编译运行之后会自动转为rem

@bg: black;
.text1{
    font-size: 36px;
    color:@bg
}

运行之后:

@bg: black;
.text1{
    font-size: 2.25rem;
    color:@bg
}

不管视口宽度怎么变化,在运行之后,px转rem的数值都是一样的,变量是根html font-size的大小。

初始值设置的16,即1rem = 16px, 1rem = a px,随着视口的放大,缩小,a一定是16的倍数。

下面两个图展示了,视口宽度为375和750时,fong-size大小始终都是2.25rem

image.png

image.png```

下面两个图展示了,视口宽度为375和750时,fong-size大小始终都是2.25rem


`插入一个题外bug`

问题一:在vite + vue3 + postcss-pxtorem + vant 中,在本地运行时样式正常,提交代码到测试分支之后,样式错乱,vant组件的字体都大了一倍。

查阅了vant的官方文档,在浏览器自适应中看到vant推荐使用 [postcss-px-to-viewport](https://github.com/evrone/postcss-px-to-viewport) 进行转换。 vant的作者设计稿是按照375来的,我们公司的设计稿尺寸一般都是750,所以需要做一个配置

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/04ae1152185846f282ea4a3a34b681c6~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=898&h=604&s=51722&e=png&b=f7f8fa)

# `正题`

##### **当前移动端比较流行的适配方式有:**

##### 1、postcss-pxtorem + amfe-flexible

postcss-pxtorem用于将px转rem,amfe-flexible用来动态设置HTML的字体大小,去适配不同大小的屏幕。

> `第一步: 先安装postcss-pxtorem,然后在根目录建立一个文件名为postcss.config.js的文件,加入以下配置, rootVlue可以随意设置`

**搭配amfe-flexible插件来使用的话,rootValue是值就是设计稿的尺寸除以10,我们公司设设计稿一般是750,所以这里设置75**

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c3ff1716dd294bd7bcedd44f308214eb~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=910&h=488&s=122727&e=png&b=f7f7f7)

> 第二步:配置好之后上面的文件,在main.ts文件引入amfe-flexible这个插件就可以啦

> 第三步: 开始在less文件中编写样式

css @bg: black; .text1{ font-size: 36px; color:@bg }


运行之后:

css @bg: black; .text1{ font-size: 0.48rem; color:@bg }


这里展示一下amfe-flexible的源码,他是以10作为基数来计算

当设计稿为750的时候,把设计稿分成10份,那么根html的节点1rem = 75px, 这里html根字体大小不管怎么改变,都是初始值75的倍数

**核心代码就是这段**

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e961898e9f174d1ca13244c0bcf12675~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=404&h=151&s=12866&e=png&b=1e232f)

假如设备窗口是393px,amfe-flexible的源码是 `393/10 = 39.3`,也可以这么计算, `(393/750)* 75 = 39.3`(不管怎么改变,都是初始值75的倍数)

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f5ed2e9d6deb42d58581fdeec0e6f2ae~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=979&h=1251&s=157701&e=png&b=1f242f)

> **举例 n = 16,设置rootValue 为16**

`假设n = 16`

> 如果n设置为16,不是一个倍数关系,那么就不能使用amfe-flexible来动态改变html根节点的大小。

**在postcss.fonfig.js中把rootValue设置为16**

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8584ae1784f14363a4bacd6206549db8~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=861&h=374&s=100211&e=png&b=f5f5f5)

`新建一个flexible.js文件,在main.ts中引入,这个文件的作用和amfe-flexible的作用想通,用来动态设置html字体大小。 其实核心原理就是比例相同,通过动态设置html的字体大小去达到自适应的效果`

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ec903c745a004135ac3f68675c1a0c38~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1066&h=583&s=220937&e=png&b=201d20)

也可以这样写 更容易理解一些(`就是去更改16倍数,不管html根字体大小怎么变,都是16的倍数`):

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b9d822c860f240eeb17da1f8ab6929b5~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=795&h=331&s=42143&e=png&b=1e232e)按照750的设计稿尺寸,代码正常编写px,编译运行之后会自动转为rem

css
@bg: black;
.text1{
    font-size: 36px;
    color:@bg
}

运行之后:

```css
@bg: black;
.text1{
    font-size: 2.25rem;
    color:@bg
}

不管视口宽度怎么变化,在运行之后,px转rem的数值都是一样的,变量是根html font-size的大小。

初始值设置的16,即1rem = 16px, 1rem = a px,随着视口的放大,缩小,a一定是16的倍数。

2、vw方案 postcss-px2vp
npm i -D postcss-px2vp类似

根目录创建postcss.config.js 文件:

module.exports = {
    plugins: {
        'postcss-px2vp': {
            viewportWidth(rule) { // 1. 如果设计稿宽度是750px + 使用Vant
                const file = rule.source?.input.file
                return file?.includes('vant') ? 375 : 750;
            },
            // viewportWidth: 750, // 2.如果设计稿宽度是 750px + 不适用Vant
            // viewportWidth: 375, // 3.如果设计稿宽度是 375px + 无论是否使用Vant
            propList: ['*','!font*','!line-height','!letter-spacing'],
        },
    },
};

修改postcss.config.js文件,需要重启

3、postcss-px-to-viewport插件,和postcss-px2vp类似

image.png

参考资料:

react项目适配postcss-pxtorem插件

了解postcss-pvtorem

移动端适配方案