移动端适配解决方案(二)
「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
前言
前段时间我的移动端适配解决方案一文在评论区引发了激烈的讨论。其中讨论最多的就是,移动端rem的适配已经淘汰了,目前大家使用的都是viewport
。lib-flexible
作者也在github明确的表示lib-flexible
这个解决方案可以放弃使用了。
由于
viewport
单位得到众多浏览器的兼容,lib-flexible
这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport
来替代此方案。
看到大家的讨论,我受益匪浅。在这里也向那些阅读过我之前那篇移动端适配解决方案文章的同行们说一声对不起。rem适配方案确实是已经淘汰了。
本文带大家一起来看看评论区所说的viewport
适配解决方案。
什么是viewport
viewport
翻译成中文的意思大致是视图、视窗。在移动端设备中,整块显示屏就相当于视图、视窗。
但这种说法也并不完全正确。因为在移动端设备中,浏览器视图并不是整个屏幕。因此viewport
又被分为了3种 layout viewport
、visual viewport
、ideal viewport
为了能够适配到pc端开发页面中,大部分浏览器把viewport
的宽度设为了980px
这个浏览器默认设置的视图被称为 layout viewport
。我们可以使用document.documentElement.clientWidth
来获取。
由于 layout viewport
的宽度是远大于浏览器宽度的,因此我们需要一个新的viewport
来代表浏览器的可视区域宽度,这个视图则被成为visual viewport
我们可以使用window.innerWidth
来获取。
现在我们已经有两个viewport
了,layout viewport
和 visual viewport
。但浏览器觉得还不够,因为现在越来越多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的ideal viewport
。
ideal viewport
并没有一个固定的尺寸,不同的设备拥有有不同的 ideal viewport
。比如iphone5
的 ideal viewport
是 320px 而 iphone6s
的 ideal viewport
却是 375px
viewport
的单位vw、vh
vw、vh
将viewport
分成了一百份。vw即 viewport width
vh即viewport height
- 1vw等于视图单位的1%的宽度
- 1vh等于视图单位的1%的高度
如果设计稿的视图为375px 那么1vw 等于 3.75px
在配置开始之前 我们依然需要一个vue-cli项目 在项目的index.html
我们需要在head
标签中添加如下代码
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
viewport
适配解决方案
之前的文章,我们用到了阿里巴巴手淘团队出品的amfe-flexible
这个库。目的是为了获取到不同移动端设备下的像素比。对于rem
的适配该库是至关重要的。本篇文章使用viewport
适配则不再需要。
要使用viewport
适配 我们必须安装postcss-px-to-viewport
这个包。这包名是不是有一种似曾相识的感觉。
没错,上篇文章中我们使用过postcss-pxtorem
。这两个包不仅名字相似,功能也有相似的地方。
postcss-pxtorem
是将 px
单位转换为rem
单位。 postcss-px-to-viewport
则是将px单位转换为vw、vh
//引入 postcss-px-to-viewport
npm install postcss-px-to-viewport --save-dev
安装完成后 我们需要进行postcss
插件相关的配置 在根目录新建一个名为postcss.config.js
的文件,如果项目中已包含该文件则无需新建。 在文件中写入如下代码:
//postcss.config.js
module.exports = {
plugins: {
'postcss-px-to-viewport': {
unitToConvert: "px", // 要转化的单位
viewportWidth: 375, // 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/], // 设置忽略文件,用正则做目录名匹配
}
}
}
在配置上这两个包也有相似的功能。大家可以去参考一下postcss-px-to-viewport
作者的github
值得注意的是:postcss-px-to-viewport
同样存在第三方组件库兼容性的问题。比如在设计稿为750px时使用vant组件库会将vant组件的样式缩小。
解决第三方组件库兼容问题
vant组件库的设计稿是按照375px来开发的。因此在viewportWidth
为750px
时会出现转换问题。
// postcss.config.js
const path = require('path');
module.exports = ({ webpack }) => {
const viewWidth = webpack.resourcePath.includes(path.join('node_modules', 'vant')) ? 375 : 750;
return {
plugins: {
autoprefixer: {},
"postcss-px-to-viewport": {
unitToConvert: "px",
viewportWidth: viewWidth,
unitPrecision: 6,
propList: ["*"],
viewportUnit: "vw",
fontViewportUnit: "vw",
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: true,
exclude: [],
landscape: false
}
}
}
}
如果读取的node_modules
中的文件是vant
,那么就将设计稿变为375px。如果读取的文件不是vant
的文件,那么就将设计稿变为750px。这样就可以避免vant
组件在750px下出现样式缩小的问题了。
同理 这对于其他的移动端UI组件库同样有效果。我们只需要改动这行代码即可
const viewWidth = webpack.resourcePath.includes(path.join('node_modules', 'vant')) ? 375 : 750;
至此,我们的viewport的适配就做好了,只需要按照设计稿的比例进行开发就可以了。
最后
文章若有不足之处,还请大家批评指出。
感谢您观看此篇文章 希望能给个👍评论收藏三连!你的点赞就是我写作的动力。
转载自:https://juejin.cn/post/7061866685166256142