移动端适配
移动端适配的目的是在不同尺寸的手机设备上,页面自适应或者保持统一效果的等比缩放;
先来明确几个概念
viewport
移动设备默认的viewport是layout viewport,也就是那个比屏幕要宽的viewport,但在进行移动设备网站的开发时,我们需要的是ideal viewport。那么怎么才能得到ideal viewport呢?这就该轮到meta标签出场了;meta标签的作用是让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放。
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">
设备像素比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布局
首先我们需要知道
rem
的大小是基于页面根元素的font-size
。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
优点: 易于理解,且兼容性好,能够很好地解决适配问题。
缺点:
- 需要用js额外设置字体大小,强制设置根元素的字体大小,剥夺了用户的自由
- 在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