移动端前端适配

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mengjavakaifa/article/details/85925915
  1. 什么是前端适配  

从ui展示层面上:

 我们期望不同尺寸的设备,页面可以自适应的展示或者进行等比缩放,从而在不同的尺寸的设备下看起来协调或者差不多。

从代码实现层面上:

 我们希望前端适配可以用用尽可能简洁的代码来实现,最好一套代码实现兼容所有设备,而不是对每个或者每种设备都写一套方案,不是次次都选用最无奈的方案(android和ios分开便编写)

2.关键字

2.1 viewport/视口

 通俗的讲,移动设备上的viewport就是设备的屏幕上能用来显示我们的网页的那一块区域,但不一定是我们可见的区域,具体来说,分为三种。

2.1.1 visual viewport

 visual viewport :可见视口。就是移动设备上可以被我们看见的部分,宽度在移动端通过window.innerWidth

 获得(仅限移动端,pc上哪怕事故chrome模拟也会有不用的结果)。

2.1.2 layout viewpot

 layout viewpot:布局视口

 如果吧pc上的页面放到移动端,以iphone8为例,如果只展示为可见视口的宽度(375px),那么页面会被压缩的特别窄而显示错乱,所以移动浏览器就决定默认情况下吧viewport设为一个较宽的值比如980px,这样的华即使是那些问桌面设计的网站也能在移动浏览器正常显示了

2.1.3 ldeal viewpot

ldeal viewpot:理想视口,其实就是设备的可见区域面和可见视口一致

设置ldeal viewpot 的好处是,只要按照ldeal viewpot  来设计样式搞,用户就不用能最完美的查看网站的内容--既不用左右滑动,也不用放大缩小。

设置理想视口:

<meta name="viewpot" content='width=device-width,inital-scale=1.0 maximun-scale=10,user-scalabie=0'/>

 这段代码的意思是将布局视口的宽度设置为设备宽度 初始缩放比例为1 最大缩放比例为1,用户不能缩放。

2.2

2.2.1 物理像素

物理像素:一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。

2.2.2 设备独立像素

设备独立像素:又称为css像素,就是我们日常代码中使用的像素,浏览器内的一切长度都是以css像素为单位的,css像素的单位是px。

2.2.3 设备像素比 

设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,比如说对于 ios的retina屏,一个设备独立像素就对应4个物理像素,这样的设计可以适应画面更加清晰锐利

3.业界的解决方案

3.1rem的解决方案

 dpr一致时,px在不同的屏幕尺寸上会展示为定宽,这样导致我们的页面可能会出现滚动条或者占不满的情况,而通过rem来设置div的宽高,可以保证页面可以通过调整html的font-size来整体放大或者缩小,从而达到不管屏幕宽度是多少,页面都能完美展示的效果。

例如,针对750*1334的设计搞:

<meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">
<script>
    document.documentElement.style.fontSize = window.innerWidth / 7.5 + 'px';
</script>

这样,所有的设备的宽度都是7.5rem,只需要把设计稿上的px值除于100,就可以得到相应的rem值了,

3.2 flexible.js

flexible.js 是阿里团队开发的前端适配方案,也是用的rem的方案。那么第一种方法其实已经能解决前端适配问题了,为啥阿里还要开发一个flexible?

在第一种方法中,dpr=1时没有问题 但在dpr=2或者更高的手机屏幕上 因为物理像素的增加,存在小于1px的显示空间。如果采用第一种方法,因为它统一对scale设置为1 那么我们想把要实现0.5px,就只能tranform的方式,如果又多个样式,代码就会变得很麻烦。

.scale{
    position: relative;
}
.scale:after{
    content:"";
    position: absolute;
    bottom:0px;
    left:0px;
    right:0px;
    border-bottom:1px solid #ddd;
    -webkit-transform:scaleY(.5);
    -webkit-transform-origin:0 0;
}

阿里的flexible方案充分考虑了这种情况,动态的设置了fontsize和scale,cnger使得css中的1px等于物理像素中的1px,在ios下得到最清晰的体验。


if (!dpr && !scale) {
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
        // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        // 其他设备下,仍旧使用1倍的方案
        dpr = 1;
    }
    scale = 1 / dpr;
}
 
最终在iphone8下页面的header被设置为:
<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no">

具体的大家可以看《使用Flexible实现手淘H5页面的终端适配》

另外需要指出的一点是:Flexible将页面分成了100份,页面的宽度是10rem,对于750的设计稿,我们需要用相应的px数除以75来得到。手动计算是愚蠢的,不同的编译器都可以下载pix2rem插件(可以直接写px然后自动转换为相应的rem值),直接使用sass或者postcss打包也能达到同样的功能。

总结一下上面两种rem方法,

主要思想为: 根据dpr的值来修改html的font-size,从而使用rem实现等比缩放 根据dpr的值来修改viewport实现1px的线 但是Flexible也有它的局限性,

具体表现为: 不能与响应式布局兼容 对Android没有做处理,导致1px和backgroudImage还要额外做处理的问题[4]

所以我们有了第三种解决方案——vw。

3.3 vw

vw是基于Viewport视窗的长度单位,在CSS3中和Viewport相关的单位有四个,

分别为vw、vh、vmin和vmax。

vw: 是Viewport’s width的简写,1vw等于window.innerWidth的1%

vh:和vw类似,是Viewport’s height的简写,1vh等于window.innerHeihgt的1%

vmin: vmin的值是当前vw和vh中较小的值

vmax: vmax的值是当前vw和vh中较大的值

其实vw的方案的写法和flexible方案的写法一致——因为flexible其实就是用hack的手段模拟了vw的实现而已。

具体写法:针对750px的设计稿,将相应的px值除以75就是vw的值。

因为此方法不会改变可见视口的宽度,所以可以和media query通用了,

另外,也支持了Android上高分辨率屏的展示。 尽管在某些Android机型上还存在兼容问题,我们也可以使用Viewport Units Buggyfill,具体见《如何在Vue项目中使用vw实现移动端适配》

猜你喜欢

转载自blog.csdn.net/mengjavakaifa/article/details/85925915