移动端适配

移动端适配的目的是在不同尺寸的手机设备上,页面自适应或者保持统一效果的等比缩放;

先来明确几个概念

 viewport

移动设备默认的viewport是layout viewport,也就是那个比屏幕要宽的viewport,但在进行移动设备网站的开发时,我们需要的是ideal viewport。那么怎么才能得到ideal viewport呢?这就该轮到meta标签出场了;meta标签的作用是让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放。

meta viewport 标签首先是由苹果公司在其safari浏览器中引入的,目的就是解决移动设备的viewport问题。后来安卓以及各大浏览器厂商也都纷纷效仿,引入对meta viewport的支持,事实也证明这个东西还是非常有用的。
在苹果的规范中,meta viewport 有6个属性(暂且把content中的那些东西称为一个个属性和值),如下:
width:设置layout viewport 的宽度,为一个正整数,或字符串"device-width";
initial-scale:设置页面的初始缩放值,为一个数字,可以带小数;
minimum-scale:允许用户的最小缩放值,为一个数字,可以带小数;
maximum-scale:允许用户的最大缩放值,为一个数字,可以带小数;
height:设置layout viewport 的高度,这个属性对我们并不重要,很少使用;
user-scalable:是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许;

  设置理想视口:把默认的layout viewport的宽度设为移动设备的屏幕宽度,得到理想视口(ideal viewport):

  <meta name="viewport" content="width=device-width,initial-scale=1">


物理像素又被称为设备像素,他是显示设备中一个最微小的物理部件,每个像素可以根据操作系统设置自己的颜色和亮度,所谓的一倍屏、二倍屏(Retina)、三倍屏,指的是设备以多少物理像素来显示一个CSS像素,也就是说,多倍屏以更多更精细的物理像素点来显示一个CSS像素点,在普通屏幕下1个CSS像素对应1个物理像素,而在Retina屏幕下,1个CSS像素对应的却是4个物理像素,关于这个概念,看一张“田”字示意图就会清晰了;

CSS像素是一个抽象的单位,主要使用在浏览器上,用来精确度量WEB页面上的内容,一般情况下,CSS像素称为与设备无关的像素(device-independent pixel),简称DIPs,CSS像素顾名思义就是我们写CSS时所用的像素;
 

设备像素比dpr(device pixel ratio):设备像素比简称dpr,其定义了物理像素和设备独立像素的对应关系,它的值可以按下面的公式计算得到:

设备像素比=物理像素/设备独立像素

Retina屏的iphone上,devicePixelRatio的值为2,也就是说1个css像素相当于2个物理像素,通常所说的二倍屏(Retina)的dpr是2,三倍屏是3;

安卓设备根据屏幕像素密度可分为ldpi、mdpi、hdpi、xhdpi等不同的等级,规定以160dpi为基准,1dp=1px;如果密度为320dpi,则1dp=2px,以此类推;

IOS设备:从iphone4开始Retina屏;

 

rem定义:font size of the root element,这个单位的定义和em类似,不同的是em是相对于父元素,而rem是相对于根元素,rem定义是根元素的font-size,以rem为单位,其数值与px的关系,需相对于根元素<html>的font-size计算,比如设置根元素font-size=16px,则表示1rem=16px;根据这个特点,可以根据设备宽度动态设置根元素的font-size,使得以rem为单位的元素在不同终端上以相对一致的视觉效果呈现;

 

移动端适配方案:

viewport适配

这种适配方案原理比较简单:实际上就是通过动态设置meta标签的viewport让css中的1px等于设备的1px。

js伪代码:

const scale = 1 / devicePixelRatio

head.appendChild(`<meta name='viewport' content='width=device-width, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable='no'>`)

body.setAttribute('data-dpr', devicePixelRatio)

css伪代码

[data-dpr='3'] {
    property: value * 3
    ...
}

[data-dpr='2'] {
    property: value * 2
    ...
}

 

大家可以用不同手机进入这里,或者用浏览器模拟。

优点:简单易于理解

缺点:不能涵盖所有dpr的机型,即使能,也会造成代码臃肿。

 

rem布局

首先我们需要知道

  1. rem的大小是基于页面根元素的font-size
  2. rem的本质是等比缩放。

通常我们拿到的设计图宽度的是750也就是基于iphone6/7/8的设计图,我们如果要想让1px像素等于设计图的1px该怎么做呢?

其实很简单,直接让根元素的font-size: 0.5px即可(因为是2倍图,1px等于2实际像素,所以为0.5px)。

别忘了,平时我们开发都是在chrome下开发的。chrome并不支持font-size小于12的字体,那怎么办呢?

还能怎么办,为了方便计算,让font-size大于12呗,在以上基础上将结果放大100倍,然后写样式的时候再除以100

优点: 易于理解,且兼容性好,能够很好地解决适配问题。

缺点:

  1. 需要用js额外设置字体大小,强制设置根元素的字体大小,剥夺了用户的自由
  2. 在webview中,部分机型下用户设置系统默认字体大小会造成布局错乱

 

vw布局

  • vw(view-width), vh(view-height) 这两个单位是CSS新增的单位,表示视区宽度/高度,视区总宽度为100vw, 总高度为100vh;
  • 视区指浏览器内部的可视区域大小:window.innerWidth/Height;

 

解决移动端的1px问题?

1、通过viewport + REM的方式来兼容。

目前这种兼容方案相对比较完美,适合新项目(老项目改用REM单位成本会比较高)。 淘宝M首页 就是这种方案。

在devicePixelRatio = 2 时,输出viewport

<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

在devicePixelRatio = 3 时,输出viewport

<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">

同时通过设置对应viewport的rem基准值,这种方式就可以像以前一样轻松愉快的写1px了。

2、 box-shadow

实现方式

利用css 对阴影处理的方式实现0.5px的效果

底部一条线

-webkit-box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);

优点基本所有场景都能满足,包含圆角的button,单条,多条线,

缺点

颜色不好处理, 黑色 rgba(0,0,0,1) 最浓的情况了。有阴影出现,不好用。


链接:https://www.jianshu.com/p/b13d811a6a76
posted @ 2020-03-08 19:58  Lorasysu  阅读(96)  评论(0)    收藏  举报