在说到postcss-px-to-viewport插件之前,先来了解几个概念

什么是视口?

在桌面端,视口指的是在pc端浏览器的可视区域;而在移动端,它涉及3个视口:Layout Viewport(布局视口),Visual Viewport(视觉视口),Ideal Viewport(理想视口)。

视口单位中的“视口”,pc端指的是浏览器的可视区域;移动端指的就是Viewport中的Layout Viewport

1.布局视口

布局视口是指网页的宽度,一般移动端浏览器都默认设置了布局视口的宽度。根据设备的不同,布局视口的默认宽度有可能是768px980px1024px等,这个宽度并不适合在手机屏幕中展示。移动端浏览器之所以采用这样的默认设置,是为了解决早期的PC端页面在手机上显示的问题。

布局视口

当移动端浏览器展示PC端网页内容时,由于移动端设备屏幕比较小,不能像PC端浏览器那样完美地展示网页,这正是布局视口存在的问题。这样的网页在手机的浏览器中会出现左右滚动条,用户需要左右滑动才能查看完整的一行内容。

js获取布局视口:

1
document.documentElement.clientWidth | document.body.clientWidth

2. 视觉视口

视觉视口是指用户正在看到的网站的区域,这个区域的宽度等同于移动设备的浏览器窗口的宽度。

视觉视口

需要注意的是,当我们在手机中缩放网页的时候,操作的是视觉视口,而布局视口仍然保持原来的宽度。

js获取视觉视口:

1
window.innerWidth

3. 理想视口

理想视口是指对设备来讲最理想的视口尺寸。采用理想视口的方式,可以使网页在移动端浏览器上获得最理想的浏览和阅读的宽度。

理想视口

从图中可以看出,在理想视口情况下,布局视口的大小和屏幕宽度是一致的,这样就不需要左右滚动页面了。

在开发中,为了实现理想视口,需要给移动端页面添加标签配置视口,通知浏览器来进行处理。

  • 布局视口宽度 = 视觉视口宽度 = 设备宽度

js获取理想视口:

1
window.screen.width

视口单位

根据CSS3规范,视口单位主要包括以下4个:

1.vw1vw等于视口宽度的1%

2.vh1vh等于视口高度的1%

3.vmin:选取vwvh中最小的那个。

4.vmax:选取vwvh中最大的那个

vhvw与百分比的区别:

1.% 是相对于父元素的大小设定的比率,vwvh 是视窗大小决定的。

2.vwvh 优势在于能够直接获取高度,而用 % 在没有设置 body 高度的情况下,是无法正确获得可视区域的高度的

3.vmax相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax

4.vmin相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin

postcss-px-to-viewport

一、什么是postcss-px-to-viewport

postcss-px-to-viewport是一个将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的 PostCSS 插件.

如果你的样式需要做根据视口大小来调整宽度,这个脚本可以将你CSS中的px单位转化为vw1vw等于1/100视口宽度。示例如下:

输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.class {
margin: -10px .5vh;
padding: 5vmin 9.5px 1px;
border: 3px solid black;
border-bottom-width: 1px;
font-size: 14px;
line-height: 20px;
}

.class2 {
padding-top: 10px; /* px-to-viewport-ignore */
/* px-to-viewport-ignore-next */
padding-bottom: 10px;
/* Any other comment */
border: 1px solid black;
margin-bottom: 1px;
font-size: 20px;
line-height: 30px;
}

@media (min-width: 750px) {
.class3 {
font-size: 16px;
line-height: 22px;
}
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.class {
margin: -3.125vw .5vh;
padding: 5vmin 2.96875vw 1px;
border: 0.9375vw solid black;
border-bottom-width: 1px;
font-size: 4.375vw;
line-height: 6.25vw;
}

.class2 {
padding-top: 10px;
padding-bottom: 10px;
/* Any other comment */
border: 1px solid black;
margin-bottom: 1px;
font-size: 6.25vw;
line-height: 9.375vw;
}

@media (min-width: 750px) {
.class3 {
font-size: 16px;
line-height: 22px;
}
}

vue项目中使用

1.安装

1
npm install postcss-px-to-viewport --save-dev

2.在项目根目录下添加postcss.config.js

3.添加以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module.exports = {
plugins: {
'postcss-px-to-viewport': {
unitToConvert: 'px', // 需要转换的单位,默认为"px"
viewportWidth: 750, // 设计稿的视口宽度
unitPrecision: 5, // 单位转换后保留的精度
propList: ['*'], // 能转化为vw的属性列表
viewportUnit: 'vw', // 希望使用的视口单位
fontViewportUnit: 'vw', // 字体使用的视口单位
selectorBlackList: [], // 需要忽略的CSS选择器 '.el','el'
minPixelValue: 1, // 最小的转换数值,如果为1的话,只有大于1的值会被转换
mediaQuery: false, // 媒体查询里的单位是否需要转换单位
replace: true, // 是否直接更换属性值,而不添加备用属性
exclude: [/node_modules/,/\/pages\/mobile\//], // 忽略某些文件夹下的文件或特定文件
include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换,例如只转换 'src/mobile' 下的文件 (include: /\/src\/mobile\//)
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
landscapeUnit: 'vw' // 横屏时使用的单位
}
}
}

postcss-px-to-viewport的优点:

1.我们不需要再去根据不同的屏幕分辨率写媒体查询,造成代码臃肿

2.我们只需要去关心设计稿的宽度,严格按照设计稿给的宽度编写页面,就能在不同的分辨率上看到很不错的效果

3.css代码足够简洁,只会看到一种单位,那就是px

postcss-px-to-viewport的缺点:

无法把行内样式中的px转换成视口单位(vw, vh, vmin, vmax

探索

vue行内样式px转换vw插件,虽然这个插件在一定程度上补充了postcss-px-to-viewport无法转换行内样式的痛点,但不够完善,建议不要使用行内样式,全部改用内嵌样式。