移动端适配真的不难

布局视口、视觉视口、理想视口

布局视口(layout viewport)

布局视口是窗口容许最大的布局尺寸,当页面元素超过布局视图时会出现横向滚动条,浏览器中经过document.documentElement.clientWidth/clientHeight来获取 css

视图对比

视觉视图(visual viewport)

视觉视图是用户可以浏览到的内容的宽和高,网站上不少解释是手机的屏幕大小,经过window.innerWidth/innerHeight获取到的结果代表并不是如此。web

理想视口(ideal viewport)

从上面知道手机可以彻底展现布局视口大小的页面,超过布局大小的页面会出现滚动条,视觉视图则是整个文档的大小。当布局视图容许的页面最大尺寸等于手机屏幕时,网站页面在移动端展现的理想大小即理想视图(设备尺寸)。浏览器

Meta viewport

布局视图等于理想视图(设备尺寸),视觉视图等于布局视图,不会出现滚动条,用户处于最佳的状态。bash

<meta name="viewport" content="width=device-width;initial-scale=1;maximum-scale=1; minimum-scale=1; user-scalable=no;">
复制代码
  • device-width等于理想视口的宽度,设置width=device-width让布局视口等于理想视口。
  • initial-scale = 理想视口宽度/视觉视口宽度,设置initial-scale=1让视觉视口等于理想视口,initial-scale>1页面缩小,initial-scale<1页面放大。

物理像素、逻辑像素、像素比

  • 物理像素(设备像素):和设备相关,分辨率越高,像素点越多,像素越高。
  • 逻辑像素(设备独立像素):和设备无关,用来描述布局,通常为屏幕大小。
  • 像素比(设备像素比):简称为dpr,其定义了物理像素和设备独立像素的对应关系,它决定了一个css像素点是由多少个像素设备像素点来描绘。
型号 iPhone5 iPhone6 iPhone8Plus
逻辑像素 568x320 667x375 736x414
物理像素 1136x640 1334x750 2208x1242
屏幕倍率 @2 @2 @3
dpr 2 2 3

视口和像素

  • 理想视口:分辨率,iPhone6的分辨率 375 * 667,,@2x(Retina)
  • 视觉视口:物理屏幕的可视区域,iPhone6的物理像素 750 * 1334

理想视口的状况下,布局视口大小(设计稿尺寸)逻辑尺寸大小,可是在高清屏幕下,手机会根据dpr对其进行转化,致使CSS中的1px其实对应的两倍屏2px,三倍屏的3px,为了解决这个问题,能够将布局视口 = 逻辑尺寸 * dpr 让高清屏全屏显示大尺寸;或者放大页面app

1px解决方案

  • IOS解决方案
.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
    .border { border: 0.333333px solid #999 }
}
复制代码
  • :before&:after&transform(兼容)
.radius-border{
    position: relative;
}
@media screen and (-webkit-min-device-pixel-ratio: 2){
    .radius-border:before{
        content: "";
        pointer-events: none; /* 防止点击触发 */
        box-sizing: border-box;
        position: absolute;
        width: 200%;
        height: 200%;
        left: 0;
        top: 0;
        border-radius: 8px;
        border:1px solid #999;
        -webkit-transform(scale(0.5));
        -webkit-transform-origin: 0 0;
        transform(scale(0.5));
        transform-origin: 0 0;
    }
}
复制代码
  • viewport缩放
//dpr为2时,安卓下经过flexible.js动态设置无效,initial-scale=0.5始终默认为1
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
复制代码

移动端适配方案

  • 利用viewport进行采用理想视口
  • 利用rem调整不一样设备之间的逻辑尺寸不一致的问题
  1. 使用理想视口,固定高度,宽度自适应:
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
复制代码

垂直方向使用固定的值,水平方向使用弹性布局,元素采用定值、百分比、flex布局等。这种方案相对简单,还原设计稿程度较低,尺寸通常都采用百分比和固定值,不能跟随设备变化而调整,高清屏的设计稿尺寸要缩小1/2或1/3。iphone

  1. 根据不一样屏幕动态写入font-size,以rem做为宽度单位。
// 屏幕的布局视口宽度(理想视口) 
var width = document.documentElement.clientWidth;
//750px设计稿将布局视口分为7.5份
var rem = width / 7.5;
//1rem等于设计稿上的100px
rem = px * 0.01;    

在ipone6上: 
width = document.documentElement.clientWidth    //375px;
rem = 375px / 7.5                               //50px; 
0.75rem = 37.5px;  
在任意其余机型上:
width = document.documentElement.clientWidth    //420px;
rem = (375px / 7.5)*(420/375)                   //56px; 
0.75rem = 42px
复制代码

利用rem来消除高清屏倍率的问题,利用rem调整不一样设备之间的逻辑尺寸不一致的问题,利用百分比还原设计图,可是没法消除1px的影响ide

  1. 以rem做为宽度单位,利用缩放比例消除1px影响。
// 屏幕的布局视口宽度
var width = document.documentElement.clientWidth;
// 将布局视口分为10份
var rem = width / 10;                               

var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale; 
if (isIPhone) { 
    if (devicePixelRatio >=3) { 
    dpr = 3; 
    } else if (devicePixelRatio >=2) { 
    dpr = 2; 
    } else { 
    dpr = 1; 
    } 
} else { 
    dpr = 1; 
} 
scale = 1 / dpr; 

在ipone6上: 
width = document.documentElement.clientWidth    //750px;
rem = 750px / 10                                //75px; 
1rem = 75px; 
在任意其余机型上:
width = document.documentElement.clientWidth    //840px;
rem = (840px / 10)*(420/375)                    //94.08px; 
1rem = 94.08px   
复制代码

利用viewport进行缩放来消除高清屏倍率的问题,能消除1px的问题,利用rem调整不一样设备之间的逻辑尺寸不一致的问题,利用百分比还原设计图,可是其1rem等于75px或者其余不固定尺寸不方便计算。布局

  1. vw和viewport放缩
var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale; 
if (isIPhone) { 
    if (devicePixelRatio >=3) { 
    dpr = 3; 
    } else if (devicePixelRatio >=2) { 
    dpr = 2; 
    } else { 
    dpr = 1; 
    } 
} else { 
    dpr = 1; 
} 
scale = 1 / dpr; 

100vw = 100%width 
复制代码

使用放缩消除1px的影响,用vw来替代了rem,将rem解放出来,因此rem用来设置字体的大小,在移动端能够兼容用户设置字体大小的影响。字体

  1. 根据不一样屏幕动态写入font-size和viewport,以rem做为宽度单位。为了消除这种不利的影响将上面进行修改:
// 屏幕的布局视口宽度
var width = document.documentElement.clientWidth;   
//750px设计稿将布局视口分为7.5份
var rem = width / 7.5;
//1rem等于设计稿上的100px
rem = px * 0.01;                

var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale; 
if (isIPhone) { 
    if (devicePixelRatio >=3) { 
    dpr = 3; 
    } else if (devicePixelRatio >=2) { 
    dpr = 2; 
    } else { 
    dpr = 1; 
    } 
} else { 
    dpr = 1; 
} 
scale = 1 / dpr; 

在ipone6上: 
width = document.documentElement.clientWidth    //750px;
rem = 750px / 7.5                               //100px; 
0.75rem = 75px; 
在任意其余机型上:
width = document.documentElement.clientWidth    //840px;
rem = 56px; 
0.75rem = 84px  
复制代码

利用viewport进行缩放来消除高清屏倍率的问题,能消除1px的问题,利用rem调整不一样设备之间的逻辑尺寸不一致的问题,利用百分比还原设计图,方便计算。flex

结语

终于揭开了移动端布局的面纱,错误的地方望指正。

相关文章
相关标签/搜索