本文介绍常用的5种适配方案
1. 百分比适配
在 CSS 中盒子的宽度可以设置为一个百分比值,表示根据父级宽度的百分比来计算宽度。因此我们可以通过百分比的方式让一个盒子在任何设备中宽度占比都是一样的。
2. viewport缩放适配
viewport 缩放适配原理就是把所有机型的 CSS 像素(设备宽度)设置成一致的
var curWidth = document.documentElement.clientWidth;
// 以iphone6/7/8为例,计算缩放的尺寸
var targetWidth = 375;
var scale = curWidth / targetWidth;
view.content = 'initial-scale=' + scale + ',user-scalable=no,minimum-scale=' + scale + ',maximum-scale=' + scale + '';
iphone6,7,8
iphone6,7,8/plus
当然这种方案也有他的缺点,比如
1.就像在viewport设置宽度的时候,可以把宽度设置成一个固定值一样,会出现所有的手机看上去都是同样的大小,没有分别了,不太好,厂商特意做出各种大小的手机,还要弄成一样,那人家买大屏机有什么意义
2.算出的的值在一些有小数的情况下可能会出现误差(无关紧要),因为设备独立像素不能有小数
3.对设计稿的测量存在问题
3 DPR缩放适配
原理就是将把 CSS 像素缩放成与设备像素一样大的尺寸。
// 核心代码
var scale = 1 / window.devicePixelRatio;
view.content = 'initial-scale=' + scale + ',user-scalable=no,minimum-scale=' + scale + ',maximum-scale=' + scale + '';
iphone6,7,8
iphone6/7/8/plus
纳尼?按照 DPR 缩放为 700px 后,反而占不满了,因为我们给的宽度为 375px,因此只占了一半。
那么这种缩放方式有啥意义呢?
实际上这种方式最大的意义就是开发者和设计者的像素都是统一的,因为设计者是按照 750px 来设计的(iPhone 6/7/8 为例),那么我们前端在量图的时候,也是以 750px 为基准。通过 DPR 缩放,我们量出来是多少,在写代码时就可以设置多少。
但是这种方案好像并没有解决适配的问题,假设设计稿给的是 750px 像素,我测量出来也的确是 750px,但是如果此时我将宽度设置为 750px,只能保证在 iPhone 6/7/8 中没有问题,如果换成 iPhone 6/7/8 Plus,仍然存在适配问题,那么怎么解决呢?
此时就需要我们使用 rem 适配了。
4. rem适配
rem 适配的原理,就是把所有的设备都分成相同的若干份,再计算元素宽度所占的份数
// 核心代码
(function () {
var html = document.documentElement; // HTML 根元素
var width = html.clientWidth; // CSS 像素(设备宽度)
html.style.fontSize = width / 16 + 'px'; // 把屏幕分成了 16 列
})();
假设我们把屏幕分成16份
iPhone6 375px. 每一份宽度:375 / 16 = 23.4375
iPhone6/plus 414px。每一份宽度:414 / 16 = 25.875
现在设计师按照 750px 起稿,有一个元素,我们测量出来是 375px(物理像素)
换算成设备宽度就是 375 / 2 = 187.5
接下来计算列数:187.5 / 23.4375 = 8
之后,我们只需要设置该元素的宽度为 8 * 一列宽度即可
在 iPhone5 中:8 * 23.4375 = 187.5
在 iPhone6 中:8 * 25.875 = 207
iphone6,7,8
iphone6,7,8plus
目前一种比较流行的方式如下:
(function (doc, win, designWidth) {
var html = doc.documentElement;
function refreshRem() {
var clientWidth = html.clientWidth;
if (clientWidth >= designWidth) {
// 如果设备宽度都大于设计稿了,那么测量出来是多少就是多少
html.style.fontSize = '100px';
} else {
// 计算出比例
// 拿 iPhone6 为例,375/750=0.5
// 相当于每一列的宽度为 0.5px,分成了 750 列
// 但是浏览器是不允许这么小的字体大小的,因此乘上一个 100
// 变成每一列的宽度为 50px
// 之后在将设计稿尺寸转换为列数时,也不需要繁杂的计算
// 假设设计稿量出来为 375px => 187.5(CSS像素) => 187.5/50(每一列宽度) = 3.75(所占列数)
html.style.fontSize = 100 * (clientWidth / designWidth) + 'px';
}
};
doc.addEventListener('DOMContentLoaded', refreshRem);
})(document, window, 750);
5. vw,vh适配
vw 相当于直接将屏幕分为了 100 列,1vw 就是 1 列。
以iphone6,7,8为例,1vw = 3.75px
假设设计稿宽度为750px
那么设置html的font-size为50px,
转换成vw就是50/3.75=13.333333333333334vw
:root {
font-size:13.33333333vw;
}