前端学习之——h5适配

记得第一次写移动端页面时,本以为就按着效果图就好了,没想到出了很多问题,后来看了网上的一些文章,就试着用媒体查询去各种写样式,但是,总的感觉就是太累,太浪费时间,主要最后出来的效果还不太理想,所以,这种“凭眼神”的方式写页面不是长久之计,决定彻底总结一次,把在各处学到的,自己领悟到的全部清晰罗列,理清思路,这样以后就会越来越专业啦。。。

ps:这是一篇很绕很绕的博客。。

首先,还是要先认识移动端和浏览器端有什么不同?

我们只需要了解:

1、在pc端,css布局窗口尺寸=pc窗口的尺寸,只要效果图设计得好,就按照效果图来就可以了。

需要考虑的是各个浏览器以及浏览器不同版本的兼容。

2、在移动端,由于手机屏幕很窄,如果也让css布局窗口尺寸=手机屏幕窗口尺寸,则在pc端设计的网页,在手机端看起来会很丑。

所以,在移动端,css布局窗口尺寸比手机屏幕尺寸大得多。这样一来,也能避免pc端网页在手机端不会被压扁。

(比如:你写的pc端页面用手机打开来看,会出现横向滚动条,需要左右滑动才能看到整个网页。)

 

但是,如果手机端的页面如果都要左右滑动看的话,并不理想,手机端更适合窄的页面,所以,出现了一个概念——理想视口

理想视口定义了不同移动端设备理想css布局尺寸

 

那理想在哪?举个例子:iPhone6的理想视口尺寸为375*667 。

也就是如果css布局 超出 这个尺寸,你就需要滑动才能看到完整页面,但这不是用户所需要的效果!!

 

在代码中head标签内加上下面的语句,可以将布局尺寸设为理想尺寸

<meta name="viewport" content="width=device-width"/>

device-width就是理想视口宽度。

解决设备像素比带来的问题

有了理想视口概念之后,设计师会设计针对移动端的效果图,我们也不用左右滑动来看完整页面了。

 

但是,问题又出现了:设备的物理像素个数  和 理想视口的像素个数  不总是一致的

 

因为现在手机大部分都是视网膜屏幕,简单来说,视网膜屏幕就是在相同尺寸的屏幕上压缩更多的像素个数

 

这就出现了新的概念——设备像素比。

设备像素比(DPR)=设备物理像素个数 / 理想视口像素个数

比如,早期的iPhone的设备物理像素是320px,理想视口也是320px,所以设备像素比为1。

而iPhone5的设备物理像素是640px,理想视口是320px,所以设备像素比为2。

当然,以上的计算都是基于页面没有 缩放 的情况下 ,缩放是一个改变css像素的过程。所以当你用手指缩放页面的时候就是在增加或减少css像素。

也就是,如果想要让理想视口尺寸在css样式的控制之内,还得控制它的缩放。

 

在head标签中写下面的代码,可以设置初始缩放和最大缩放都为1,且不允许用户对页面进行缩放:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

 >设备像素比,会带来什么问题?

因为设计稿一般是按照设备物理像素尺寸设计的,而且大部分都是按照iPhone6的尺寸:750px。

但是css布局是依据理想视口尺寸

 

所以当设备像素比不为1的时候,依据设计稿尺寸写代码就会出错。

 

就拿iPhone6举个例子:

如果依据750px的尺寸设计了效果图,里面有个宽为375px的盒子,在效果图中它占了一半,但是如果css也写了375px,由于iPhone6的设备像素比为2,即它的理想视口尺寸为375px,所以此时展现出来的效果是占满全屏的。

如下图所示:

可能你会说:那将效果图的尺寸除以2,那不就可以了吗?

重要的是:设计师只会提供一个效果图给我们(一般是iPhone6的),而且并不是所有手机的设备像素比都是2,设备物理像素和理想视口尺寸都各有不同,所以即使将iPhone6的效果图正确展现,也不适配别的手机

>解决设备像素比带来的问题:

在一开始的时候,我们在meta标签中用width=device-width,将css布局尺寸设置成为了理想布局尺寸,对于iPhone6来说,就相当于将布局尺寸设置成了375px。

那么,怎样让设计图375px的尺寸,在css中也写375px,还能在iPhone6上显示375px的物理像素尺寸呢?

此时,我们就想到了之前提到的缩放,meta标签中initial-scale=1.0, maximum-scale=1.0可以设置缩放比例。

那么,在iPhone6的例子中,如果把缩放比例设置为设备像素比的倒数,即0.5,这样,不就可以直接按照设计图来写代码,还能正确显示了。

实验一下:

成功了!!

 

接着,我们又想了:有没有一种方法可以自动知道每种设备的设备像素比呢?答案是:有的。

 

window.devicePixelRatio可以得到设备像素比。所以只要在js中将meta标签里的缩放比例动态设置为window.devicePixelRatio的倒数就可以了。

如下:

var scale = 1 / window.devicePixelRatio;
$("[name='viewport']").attr('content', 'width=device-width,initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

这样,不仅可以直接根据设计图尺寸写代码,而且还能在不同的机型上看到同样大小的尺寸

实验一下:

 

 

这样真的完美了吗?

折腾半天,终于完美了!??

从上面的图,我们也看到了:确实是不同尺寸手机上都展现了同一个尺寸的红色长方形盒子,但这真的是我们想要的吗?

我们更希望看到的应该是:同一个盒子在不同尺寸的手机上所占比例都是一样的,那样才完美!

用rem解决比例问题:

rem和em:(对比一下~)

rem是相对于html标签字体大小的相对尺寸单位。例如:html的font-size=12px; 则1rem=12px。

em是相对于父元素标签字体大小的相对尺寸单位。例如:<div style="font-size:12px;"><span class="font-size:2em;"></span></div>; 则span标签中字体大小就为24px。

那怎样用rem解决比例问题呢?

试想:如果页面中的尺寸单位都用rem代替,也就是不再以px为单位。然后html的字体大小如果可以设置一个动态生成的值(每个机型不同)。

这样,比例问题不就解决了吗?

 

索性,我们就将html的字体大小设为设备像素大小的 1 / 10(iPhone6上就是75px),此刻1rem就相当于75px,5rem就相当于375px。

【在实际写样式的时候就需要用设计图尺寸375除以75,得到5,以rem为单位,即5rem】

也就是:

$('html').css('font-size', document.documentElement.clientWidth / 10 + 'px');

来看最后的效果:

 

 

我们通俗理解一下上面这种方法:

就相当于将不同机型尺寸都等分为10份,而那个红盒子在里面都占5份,所以用这种方法可以让盒子在不同机型中所占比例相同。

麻烦在于:就拿iPhone6的设计图来说,html的字体大小算出来是75px,所以每次将效果图上量到的尺寸转化为rem为单位都要除以75,这样会花费很多计算的时间。

都分析到这份上了,那就应该把更好的方法也总结出来:

如果是计算麻烦,那我们就从后往前推:怎样计算比较简单,或者说不用计算器,口算也行呢?

上面的除数是75,比较困难,你就想:如果是100,那就不困难了!

那怎样可以让除数为100呢?(iphone6为设计图尺寸情况下)

那就让设计图所对应的 1rem=100,就可以了

(ps:必须迁就设计图,因为我们是要照着设计图写代码的,对吧?)

即:(750/100) * 各个设备不同的1rem = 各个设备布局尺寸

 》》》也就是把所有尺寸手机都等分为7.5份,每一份是多少是动态计算的,由此来保证在每个机型中尺寸所占比例相同!!

还有很重要的一点是:document.documentElement.clientWidth得到的是css布局宽度(理想视口),那在改进方法中,还需要知道设备像素比,然后再控制缩放比吗?

其实,此刻我们只需要知道 等分成几份 的时候计算较方便而已,不是吗?

所以缩放比也不用动态设置了,就按原来1:1就可以了。

 

改进方法的总代码为:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <div style="width:3.75rem; height:1rem;background:red;"></div>
</body>
<script src="js/jquery.js"></script>
<script>
    $('html').css('font-size', document.documentElement.clientWidth / 7.5 + 'px');
    console.log(document.documentElement.clientWidth / 7.5);
</script>

</html>

之前的代码为:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <div style="width:5rem; height:1.333333rem;background:red;"></div>
</body>
<script src="js/jquery.js"></script>
<script>
    var scale = 1 / window.devicePixelRatio;
    $("[name='viewport']").attr('content', 'width=device-width,initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
    $('html').css('font-size', document.documentElement.clientWidth / 10 + 'px');
</script>

</html>

所以,改进之后,计算方便了(此处讲的是基于iPhone6效果图的情况)。

那字号也要全部用rem控制吗?

单独把字号拿出来说的原因是:对文字来说,在页面中所占比例不是最重要的,字儿看得清才最重要。

此刻咱们就借鉴一下大公司是怎么做的吧!

淘宝、网易等都是用媒体查询的方式来控制字体大小:

@media screen and (max-width: 321px) {
    body {
        font-size:16px
    }
}
 
@media screen and (min-width: 321px) and (max-width:400px) {
    body {
        font-size:17px
    }
}
 
@media screen and (min-width: 400px) {
    body {
        font-size:19px
    }
}

可以由上面的代码总结出:

1、将尺寸分为三个区间:321px以下,321px~400px,400px以上;

2、第一个区间与第二个区间之间字体大小相差1px,第二个区间与第三个区间之间相差2px;

3、具体每个区间字体设为多少像素,要看效果图。

 

举例:如果使用iPhone6的效果图,且效果图中字体大小为20px。

 

由于iPhone6尺寸为375px,在321px~400px区间,所以媒体查询应该写为:

@media screen and (max-width: 321px) {

    body {

        font-size:19px

    }

}

@media screen and (min-width: 321px) and (max-width:400px) {

    body {

        font-size:20px

    }

}

@media screen and (min-width: 400px) {

    body {

        font-size:22px

    }

}

 

 

终于总结完了,这下脑子清晰多了,再也不用“凭眼神”了。

posted @ 2018-02-07 18:26  程序员冒冒  阅读(539)  评论(0编辑  收藏  举报