移动端适配原理

1.Web app/混合app/native app

web app

web app是前端人员接触的最多的东西,wep app要部署html,css,js等静态文件。页面和数据都存放在服务端,用户需要通过网络访问web app。wep app开发快成本低,版本迭代快。web app只需要更改服务端的数据和页面,不需要让用户重新安装app。wep app性能低,页面都要通过网络去访问和加载。

混合app

既有web app,也有native app。混合app将不需要更改的页面写死,经常需要改变的页面放在服务器端。

native app

指的是Android和ios,native app是原生app,性能比较快。Android和ios将文件打包成apk格式的文件,页面放到用户的本地,数据存放在服务端,页面不需要通过网络的形式访问。native app开发慢成本高,版本迭代慢,如果换个样式,需要重新打包成apk,让用户下载。native app性能高,固定的东西不需要通过网络访问。

2.像素理论

css像素是浏览器中的最小单位(即web前端开发中的最小单位),物理像素是最终呈像的最小单位。位图像素是图像的最小单位。

屏幕尺寸

在这里插入图片描述

屏幕分辨率

指的是物理像素
在这里插入图片描述

在这里插入图片描述

苹果4和苹果3的屏幕尺寸一样,但是苹果4的分辨率要高,所以一块同样大小的区域,苹果4的物理像素要多,显示的更高清。

不能用屏幕分辨率的大小比较两块屏幕的大小。屏幕分辨率的大小指的是横纵方向上有多少个物理像素,不是指的是屏幕的尺寸大小。
在这里插入图片描述

屏幕像素密度

在这里插入图片描述

物理像素

屏幕的分辨率代表的就是物理像素
在这里插入图片描述

css像素

css像素和设备没有关系,它是一种逻辑像素。当我们写html页面的时候会用到css像素,css像素和浏览器有关系。css像素最终要转成物理像素去显示给用户。css像素转成物理像素显示的时候要占据多少个英寸或多少个厘米,要看css像素转换成了多少个物理像素。物理像素去呈现画面的时候和屏幕尺寸有关系,最终呈像的单位是英寸。
在这里插入图片描述

物理像素和css像素的关系

在这里插入图片描述

设备独立像素

在这里插入图片描述

在这里插入图片描述

设备独立像素是css像素和物理像素之间转换的很重要的一个环节。
在这里插入图片描述

位图像素

一个位图像素对应着一个物理像素,才能清晰的展示图片。
在这里插入图片描述

像素比

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

默认情况下,设备独立像素和css像素没有扯上关系,所以设备独立像素、像素比和浏览器没有一点关系,都是设备上的概念。写上meta标签和width=device-width时,这个时候设备独立像素才和css像素扯上了关系。

3.视口理论

在pc端,默认情况下,一个css像素等于一个物理像素。

视口是浏览器中的概念,布局视口决定的是页面的布局,视觉视口决定用户看到的内容。pc端只有布局视口,pc端缩放改变的是布局视口的尺寸(css像素的个数),改变的是css像素的面积,页面布局发生变化。移动端有布局视口,视觉视口,理想视口。移动端浏览器缩放的时候改变的是视觉视口的尺寸(css像素的个数),改变的是css像素的面积,但是布局视口的尺寸(css像素的个数)没有发生变化,页面布局没有发生变化。默认情况下,布局视口的尺寸等于视觉视口的尺寸,因为默认情况下,视觉视口会尽可能的包住布局视口。视觉视口包含的css像素的个数和用户缩放有关,默认情况下视觉视口的尺寸等于布局视口的尺寸。如果用户缩放了,那么视觉视口的尺寸不等于布局视口的尺寸。 不写上meta标签和wdith=device-width,那么布局视口默认是980px,写上之后就等于该移动设备的理想视口的尺寸。视觉视口维护了css像素和物理像素之间的比例关系。进行放大操作后,视觉视口包含的css像素比布局视口的要少;进行缩小操作后,视觉视口包含的css像素比布局视口的要多。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

移动端的视觉视口包含垂直滚动条

screen.width,pc端返回的是分辨率,移动端部分返回的是理想视口大小,部分返回的是分辨率的大小。

移动端用户缩放

放大:

​ 一个 css像素的面积变大,视觉视口内css像素的个数变少,视觉视口的尺寸变小

缩小:

​ 一个css像素的面积变小,视觉视口内css像素的个数变多,视觉视口的尺寸变大

系统缩放

系统缩放是基于理想视口进行操作的,改变的是布局视口和视觉视口。

initial-scale=1.0,布局视口和视觉视口等于理想视口。

initial-scale=2.0,布局视口和视觉视口基于理想视口放大两倍,原来的尺寸基于理想视口缩小了1/2。

如果只写上width=device-width,那么视觉视口会尽可能的包含所有的内容,不会出现滚动条,如下图:
在这里插入图片描述

写上initial-scale=1.0以后,多于的内容会出现滚动条。

完美视口

meta标签,具有width=device-width和initial-scale两个属性时才是完美视口。只有其中之一只是理想视口。完美视口解决了当出现多于的内容时,会出现滚动条显示,不会让视觉视口包含整个的内容。

width与initial-scale的冲突

width只改变布局视口的尺寸,initial-scale改变的是布局视口的尺寸和视觉视口的尺寸,如果两个都写上,布局视口的大小谁大听谁的,而视觉视口的大小只受initial-scale的属性影响。
在这里插入图片描述

上图中的200px并没有超过布局视口的尺寸(理想视口375px),但是超过了视觉视口的尺寸(此时的视觉视口的尺寸基于理想视口缩小到了187.5px),所以出现了滚动条。出不出现滚动条和视觉视口有关系。
在这里插入图片描述

meta标签

在这里插入图片描述

在这里插入图片描述

总结:四个像素(css、物理、位图、设备独立像素),四个视口(布局、视觉、理想、完美视口),两个操作(用户缩放,系统缩放),1个比例(像素比)

图问题

由于一个位图像素对应着一个物理像素,图片才能清晰的展示,而且加上meta标签后,设配的像素比也不一样,所以一般移动端会装备1X图,2X图,3X图。
在这里插入图片描述

等比问题

不加meta标签,布局视图默认是980px,同样大小的div,在不同的设备上的大小不一样(因为设备的分辨率不一样),但等比。

加上meta标签但未适配,同样大小的div,在像素比一样的设备上大小一样,但不等比(因为理想视口不一样)。

虽然不加meta标签,已经实现了等比,但是元素和字显示的太小了(因为此时一物理像素对应多个css像素)。又因为meta标签里的width写上px不容易兼容,所以要用理想视口。

适配:我们希望加上meta标签后,100%还原设计图里元素的比例,即等比。

复习

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.rem适配

优化之前

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* 
        rem 相当于根标签的fontsize
        根标签的fontSize=1rem
        适配,实现页面在不同设配上等比
         */
         *{
             margin:0;
         }
         #test{
             width:8rem;/*占据页面的一半大小*/
             height:8rem;
             background: pink;
         }
    </style>
</head>
<body>
    <div id="test"></div>
</body>
<script>
    // 思考1:如何实现1rem大小的元素,占满整个视口大小
    //思考2:如何写出的元素以rem单位并且没有小数进行适配
    //1rem=html.style.fontSize
    //布局视口的宽度就是16rem;
    //设计图的高宽就是16rem,比如640*1334的设计图,元素大小为100px,适配:100/640*16rem;
    var html=document.querySelector("html");
    html.style.fontSize=document.documentElement.clientWidth/16+"px";
</script>
</html>

优化之后

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* 
        rem 相当于根标签的fontsize
        根标签的fontSize=1rem
        适配,实现页面在不同设配上等比
         */
         *{
             margin:0;
         }
         #test{
             width:8rem;/*占据页面的一半大小*/
             height:8rem;
             background: pink;
         }
    </style>
</head>
<body>
    <div id="test"></div>
</body>
<script>
    //rem适配优化
    //rem适配原理,改变了一个元素在不同设配上占据的css像素的个数,从而实现等比
    //rem适配的优缺点
        //优点:没有破坏完美视口
        //缺点:px值到rem的转换太复杂(可用less解决)
    (function () {
            var styleNode = document.createElement("style");
            var w = document.documentElement.clientWidth / 16;
            styleNode.innerHTML = "html{font-size:" + w + "px!important}";//提升html字体样式的权重
            document.head.appendChild(styleNode);
        })();
</script>
</html>

5.viewport适配

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
     <meta name="viewport" content="width=device-width, initial-scale=1.0"><!--先将布局视口设置为理想视口的值-->
    <title>Document</title>
    <style>
         *{
             margin:0;
         }
         #test{
             width:320px;/*占据页面的一半大小*/
             height:100px;
             background: pink;
         }
    </style>
</head>
<body>
    <div id="test"></div>
</body>
<script>
   //将所有设配布局视口的宽度调整为设计图的宽度
   //获取理想视口,计算缩放比,创建meta标签
   /*
   var targetW=640;
   var scale=screen.width/targetW;//获取缩放的比例,screen.width的兼容性不好
   var meta=document.createElement("meta");
   meta.name="viewport";
   meta.content="initial-scale="+scale+",minimun-scale="+scale+",maximum-scale="+scale+",user-scalable=no";//不能加上width=device-width,如果initial-scale大于1.0,width=device-width会覆盖设计好的布局视图的尺寸
   document.head.appendChild(meta);*/
   //优化viewport适配(先用meta标签将布局视口设置为理想视口的值,然后获取布局视口的值,计算缩放比,覆盖原先的content属性)
    /*
        viewport适配的原理:
            viewport适配方案中,每一个元素在不同适配上占据的css像素的个数是一样的,,等比的。但是css像素和物理像素的比例是不一样的
        优点:所量即所得
        缺点:没有使用完美视口
    */
   (function () {
        var targetW = 640;
        var scale = document.documentElement.clientWidth / targetW;//获取布局视口,并计算缩放比
        var meta = document.querySelector("meta[name='viewport']");//取得页面上的meta标签
        meta.content = "initial-scale=" + scale + ",minimum-scale=" + scale + ",maximum-scale=" + scale + ",user-scalable=no";//覆盖原先的content属性
    })();
    
</script>
</html>

6.vw适配

vw单位

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin:0;
            padding:0;
        }
        .box1{
            width: 6.4vw;
            height: 4.667vw;
            background-color: #bfa;
        }
    </style>
</head>
<body>
    <!-- 
        不同的设备完美视口的大小是不一样的
            iphone6 --375
            iphone6plus --414
        
        由于不同设备视口和像素比不同,所以同样的375个像素在不同的设备下意义是不一样,
            比如在iphone6中 375就是全屏,而到了plus中375就会缺一块

        所以在移动端开发时,就不能再使用px来进行布局了

        vw表示的是视口的宽度(viewport width)
            -100vw = 一个视口的宽度
            - 1vw=1%视口宽度

            vw这个单位永远相等于视口宽度进行计算

            设计图的宽度
                750px 1125px

            设计图
                750px

            使用vw作为单位
                100vw
            
                创建一个 48px * 35px 大小的元素(注意:48px和35px指的是设计图上的大小,而在移动端实现的是这么一个的比例的关系)
                100vw=750px(设计图的像素)0.133333333333333vw=1px
                6.4vw=48px(设计图像素)
                4.667vw=35px
               
     -->
     <div class="box1"></div>
</body>
</html>

vw适配(配合rem)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin:0;
            padding:0;
        }
        html{
            /* 
                网页中字体大小最小是12px,不能设置一个比12像素还小的字体
                    如果我们设置了一个小于12px的字体,则字体自动设置为12px
                设计图750px
                0.1333333333vw=1px
                5.3333vw=40px
            */
            font-size: 5.33333vw;
        }
        .box1{
            /* 
                rem
                    -1 rem =1 html的字体大小
                    -1 rem=40px(设计图)
            */
            width: 1.2rem;/*48rem/40*/
            height:0.875rem;/*35rem/40*/
            background-color: #bfa;
        }
    </style>
</head>
<body>
    <!-- 
        48 * 35
     -->
    <div class="box1">

    </div>
</body>
</html>

7.实现一物理像素

淘宝方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
         *{
             margin:0;
             padding:0;
         }
         #test{
             width:16rem;/*rem没有受到initial-scale缩放的影响*/
             height:1px;/*因为initial-scale按照像素比进行缩小了,所以布局视图的尺寸(css像素的个数)依据理想视口放大了,但是元素缺缩小了,因为原先物理像素和css像素的比是像素比,但是元素按照像素比缩小了,所以就实现了1物理像素*/
             margin-top: 1rem;
             background: black;
         }
        

    </style>
</head>
<body>
    <div id="test"></div>
</body>
<script>
   //更改适配方案,实现1物理像素的大小
   window.οnlοad=function(){
       (function(){
        debugger;
        var dpr=window.devicePixelRatio||1;//获取像素比,不支持的浏览器为1
        var styleNode=document.createElement("style");
        var w=document.documentElement.clientWidth*dpr/16;//因为后面会将整个的布局视口按照像素比缩小,所以这里先将适配方案*dpr
        styleNode.innerHTML="html{font-size:"+w+"px!important}";
        document.head.appendChild(styleNode);
        var scale=1/dpr;
        var meta=document.querySelector("meta[name='viewport']");
        meta.content="width=device-width,initial-scale="+scale;//因为scale小于1.0,所以写上width=device-width也没有影响,还是以initial-scale为准的。而且此时也是完美视口
       })();
   }
</script>
</html>

普遍方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
         *{
             margin:0;
             padding:0;
         }
         #test{
             width:100%;
             height:1px;
             margin-top: 50px;
             background: black;
         }
         @media only screen and (-webkit-device-pixel-ratio:2){
             #test{
                 transform: scaleY(.5);
             }
         }
         @media only screen and (-webkit-device-pixel-ratio:3){
             #test{
                 transform: scaleY(.33333333333333);
             }
         }
    </style>
</head>
<body>
    <div id="test"></div>
</body>
<script>
  
</script>
</html>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值