关于移动端适配的几个简单解决办法(vue)
对移动端适配原理进行简单介绍,并提供几个适用于 vue 项目的移动端适配解决方案。
基本概念
首先要了解一下关于适配的基础知识。
移动 web 开发之像素和 DPR
适配的基础知识
总结:
- px 又称像素。有两种像素概念,一种是网页设计中使用的 css 像素(逻辑像素),一种是原生移动系统使用的设备像素。一个 CSS 像素对应多少个设备像素是根据当前的缩放比例(dpr)来决定的,即 css 像素可能包含多个设备像素。
- 物理像素的大小在不同设备上不一定相等。体现为屏幕像素密度不同(ppi),可以对比一下电脑和手机上的像素点大小。
- DPR 设备像素比
DPR = 设备像素 / CSS像素(某一方向上)
,dpr 为 2 的设备,一个 css 像素含有 4 个物理像素,dpr 为 3 的设备,一个 css 像素含有 9 个物理像素。 - 我们在 viewport(虚拟布局窗口)上面布局,然后通过 meta 标签
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
做一些设置之后渲染到设备上。 - css 像素数跟设备大小没关系,因为不同的设备单个物理像素是不一样的。css 像素数 = 分辨率宽/dpr。例如 iphone6 dpr=2 分辨率 750x1334,打印它的宽 为 375px。红米 note2A 分辨率 1920x1080 dpr=3 打印为 360px。另外 iphone6plus 分辨率 1920x1080 打印是 414px,原因是它的 dpr=2.6。
- 为什么推荐使用 rem 来做适配单位CSS3 的 REM 设置字体大小
rem 适配方式概念
rem 适配方式并不是只有一种,这种方式的核心理论是 动态计算 页面宽度/一个比例值(比如 10 或者 15)= 1rem。这里放一个 demo,以 iphone6 设计稿里面元素的尺寸除以 100 得到的就是最终的 rem 值。
1 | (function() { |
所以哪怕不是除以 7.5 而是其他的比例转化为 rem 或者不同的页面宽度计算和 js 引入,也是属于 rem 方式的一种。
目标问题
适配需要解决问题:
- 1px 边框问题
- 图片适配
- 字体适配
- 元素自适应
- 横竖屏适配
适配方案
介绍关于像素单位的基本知识,原因在于适配方案大部分都是基于单位来进行适配的。
直接使用 px 方式做适配的方案这里就不说了,重点放在 rem 适配方式和 vw 适配方式上面。同时秉着简单、方便的原则,将会尽量避免与第三方 UI 库发生冲突,以便于开发者借助 UI 库迅速开发。
rem 适配一
第一种 rem 适配,可以参考使用 Flexible 实现手淘 H5 页面的终端适配
这种方式引入lib-flexible这个库,具体适配方法是先根据设备的 dpr 进行页面缩放,然后再使用 rem 进行适配。
这种方式的好处是根据 dpr 进行了缩放,所以 1px 边框以及一些适配问题都迎刃而解,效果显示细腻。
坏处是缩放相当于改变了原先的 css 单位,所以绝大部分 UI 库都无法使用,也即这种方式可能适用于从 0 开始做东西。而且细节部分较多,不留神可能容易出错。这种方式是比较早的方式,淘宝基本已经不用了,部分开发者还是有使用这种方式。
vw 适配方案
后来手淘团队又出了 vw 适配方案。再聊移动端页面的适配
这种方案使用 vw 单位做适配。理论其实跟 rem 方案差不多,区别就是使用了原生支持的 vw 而不用 rem,不过我现在不是很看好它的兼容性问题,手淘团队为了兼容做了一套方案,暂时不过多研究,这种方案以后可能会成为适配主流。
rem 适配二
这个方式其实就是普通的 rem 适配方案在 vue 项目里的应用。秉着前端自动化的原则,使用 postCSS 插件对单位自动做了处理,这样既能与 UI 库和平共存,又能自动 px 转 rem 单位。
- 新建一个 vue 项目
npm i postcss-pxtorem --save-dev
- 在项目根目录下
.postcssrc.js
文件里面添加
1 | module.exports = { |
- 项目根目录 main.js 里面引入一个 js,内容
1 | (function() { |
- 这样 样式单位使用 px 就会被转换成 rem 了。
postcss-pxtorem
而且这个插件也可以做一些配置,例如设置 写 Px 则不会进行转换等。 - 这样基于 vue 的自动化适配基本就完成了。通过设置在 iPhone6 尺寸下 1rem = 16px,不会影响 UI 库的使用(也可以设置为 14px,调节上方 23.4375 即可),也通过 postcss 插件进行了自动转化。
几个适配问题的解决方法
1px 边框问题
移动 web 1 像素边框 瞧瞧大公司是怎么做的
7 种方法解决移动端 Retina 屏幕 1px 边框问题
移动 web 1px 边框解决方案
总结:如果是 ios7 之后的版本,那么可以直接用 0.5px,不过安卓就 emmm。
比较好的几个办法:
- 伪元素缩放
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
27
28
29
30
31
32
33
34#test1 {
margin-top: 30px;
width: 50px;
height: 50px;
position: relative;
}
#test1:before {
position: absolute;
content: "";
width: 200%;
height: 200%;
top: 0;
left: 0;
border: 1px solid #000;
transform: scale(0.5);
transform-origin: 0 0;
box-sizing: border-box;
pointer-events: none;
}
/* 圆角 */
.div::after {
content: "";
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid #bfbfbf;
border-radius: 4px;
-webkit-transform: scale(0.5, 0.5);
transform: scale(0.5, 0.5);
-webkit-transform-origin: top left;
} - 图片替换
- 颜色渐变
- 阴影
图片和字体适配
使用 rem 适配方式二,一般不管 dpr=2 还是 dpr=3,设置图片原先一半的尺寸就是高清。dpr=2 和 dpr=3 差别很小。
字号也是平常的设计稿尺寸除以 2。如果移动设备屏幕太大可能会导致字号显示过大,如有需要单独进行样式设置。
img 标签图片适配
这个方法直接使用 css 的 srcset 和 sizes 属性进行响应式渲染,具体使用:
1 | <img |
一个 src 保底兼容 IE,然后根据 sizes 计算的宽度来命中使用哪个图片。
支持 chrome38+ 但是 IE 不支持
参考响应式图片 srcset 全新释义 sizes 属性 w 描述符
背景图倍图适配
用 stylus 做的例子,使用 css 预编译器的方法,将路径和类型传递过去:
1 | bg(url, type) { |
1 | #test { |
这样就能根据 dpr 选择图片。
横竖屏适配
参考文章
一些参考文章上面已给出链接。
移动端高清、多屏适配方案 - 移动端 H5 - 前端乱炖
掘金 🐂🍺dalao-图文并茂 10 大重点讲解移动端适配必备知识