在探讨移动端适配前我们先要了解下面几个概念
像素(Pel,pixel;pictureelement),为组成一幅图像的全部亮度和色度的最小图像单元。电视的图像是由按一定间隔排列的亮度不同的像点构成的,形成像点的单位也就是像素,组成图像的最小单位就是像素。从计算机技术的角度来解释,像素是硬件和软件所能控制的最小单位。它指显示屏的画面上表示出来的最小单位,不是图画上的最小单位。一幅图像通常包含成千上万个像素,每个像素都有自己的颜色信息,它们紧密地组合在一起。由于人眼的错觉,这些组合在一起的像素被当成一幅完整的图像。当修改图像的某区域,实际上是在修改该区域内的像素。对这些像素修改的好与坏将决定最终图片的质量。单位面积内的像素越多,图像的效果就越好。彩色电视图像是由成千个像素点所组成的,而且每个像素都是由红绿蓝三种颜色并排组成的。(注意每个像素的大小是不固定的,他是根据设备的分辨率决定的。
屏幕分辨率是指纵横向上的像素点数,单位是px。屏幕分辨率确定计算机屏幕上显示多少信息的设置,以水平和垂直像素来衡量。就相同大小的屏幕而言,当屏幕分辨率低时(例如 640 x 480),在屏幕上显示的像素少,单个像素尺寸比较大。屏幕分辨率高时(例如 1600 x 1200),在屏幕上显示的像素多,单个像素尺寸比较小。
设备屏幕的物理像素,表示屏幕上可以铺多少个点点,而不是一个绝对长度单位(例如in,mm); 单位是px,比如iPhone6的 (750 x 1334px)
是Web编程的概念,指的是CSS样式代码中使用的逻辑像素, 或者称为设备独立像素, 因为只与设备相关; 1个CSS像素在不同设备上可能对应不同的物理像素数,这个比值是设备的属性(Device Pixel Ratio,设备像素比),比如,iPhone6:375 x 667px。
可以看出CSS像素是一个相对的像素而非绝对像素
案例
在 一个物理像素为 1280x1024 的显示器放置一个宽高100px的容器
.box1{
height: 100px;
width: 100px;
background-color: red;
}用截图工具(截图工具测得的像素等于物理像素)测得CSS中的1px 的等于物理像素1px的 那么他们的比值就是1:1

此时是显示正常,如果我们将浏览器窗口放大两倍,CSS的像素还与物理像素一一对应吗?

答案是否定的,我们在css中只给盒子规定了100x100的像素,而在浏览器放大两倍后盒子变成了200x200
从这里也验证了css中的像素只是一个相对单位,浏览器在对html解析时会将css像素转换为物理像素在进行呈现 但是浏览器是如何将css像素转换为物理像素的呢?他们之间肯定存在着一个比值关系 这里我们就要引申出一个新的概念---视口(Viewport) 我们可以简单的讲视口理解为 屏幕中展示网页的区域。
需要注意的是视口的单位是CSS像素,而非物理像素
如下图

通过查看html的尺寸即可知道视口的尺寸 如图在浏览器大小没有发生改变,没有进行缩放时此时html/视口的尺寸为 1280x116

通过查看视口的大小就可以得出 CSS像素与物理像素的比值关系 如上图视口宽度为 1280 而我们的分辨率,物理像素也是 1280

此时在浏览器窗口未发生改变和缩放时,CSS像素与物理像素的比值是1:1
当我们对浏览器窗口放大二倍时,此时视口的宽度为 640

可以看到,视口变小了缩小为原来的两倍
因为我们将浏览器放大了两倍,原本1CSS像素就可以显示的地方现在需要2个CSS像素展示,所以视口就自然而然的变小了
要知道我们显示器的物理像素为1280 当浏览器窗口放大两倍时,视口宽度变成了640 与物理像素正好是2倍的关系
此时得出结论“ 1CSS像素等于2个物理像素”,这里只是一个单向关系,实际上应该是4个物理像素显示=1个CSS像素
** 设备像素(DP)与CSS像素之间的关系** 获得设备像素比(dpr)后,便可得知设备像素与CSS像素之间的比例。当这个比率为1:1时,使用1个设备像素显示1个CSS像素。当这个比率为2:1时,使用4个设备像素显示1个CSS像素,当这个比率为3:1时,使用9(3*3)个设备像素显示1个CSS像素。 所以,有如下公式:
DPR = 设备像素/CSS像素
了解上面的东西后接下来我们来探讨移动端的适配问题
注意在不同的屏幕,单位像素的大小是不同的,像素越小屏幕越清晰,智能手机的像素点是远远小于显示器的像素点的
以Iphone6为例 他的高宽为 750x1334 也就意味着横向只能展示 750个像素点,如果此时有一个900px的盒子,在Iphone6中会正常显示吗

借助调试工具查看
.box1{
height: 100px;
width: 900px;
background-color: red;
}
可以看到不仅全部展示,居然还有剩余的部分,而整个手机屏幕的宽度只有 357px 这是为什么?
我们当然不能根据手机屏幕的宽度为标准,而是根据视口的宽度

可以看到视口的宽度为980px 那么900px的盒子在750px的盒子正常显示也就不足为怪了,而且每个手机默认的视口宽度都是980px,这是为了让pc端的网页也能在移动端完整展示 如果pc端网页超过了980px那么移动端浏览器会对网页进行缩放以正常显示
通过结合上面的规律我们得出,视口小于物理像素时,页面展示的元素会放大,视口大于物理像素时元素会缩小。
这就是pc端网页没有做移动端适配的情况下,在移动端看上去会非常的小,我们要通过缩放才能正常浏览网页,当然这个体验并不是很好
这也就是我们常说的布局视口
默认情况下 移动端的像素比为 980/移动端宽度
布局视口带来的问题是 如果我们直接在网页中编写移动端代码,在980的视口下像素比是非常不友好的 也就是 1px =0.几物理像素,这样就会导致网页中的内容非常非常小
因此在编写移动端页面时,必须要确保有一个比较合理的像素比 如 1CSS像素对应2/3个物理像素
问题是我们如何去调整移动端的像素比?
我们可以通过改变视口的大小来改变CSS像素和物理像素的比值
如Iphone6 的物理像素是750px这个是固定的,我们要调整像素比,只需将视口调小就可以了如 375,此时正好是1:2
通过meta设置视口大小
<meta name="viewport" content="300"><meta/>当然视口的宽度也不能凭我们想象随便设置,每一款移动设备都会有一个最佳的像素比,我们只需设置成该值即可 在https://material.io/resources/devices/ 我们可以看到一些设备的最佳像素比 如Iphone6的最佳像素比为 2倍

此时我们就可以将 viewport设置为 375
<meta name="viewport" content="375"><meta/>这就是我们的完美视口,移动端有一个最佳的像素比 但是我们不能将像素比写死每个设备的像素比都可能不一样,因此一个完美的视口应该是这样
<meta name="viewport" content="width=device-width, user-scalable=no ,initial-scale=1,maximum-scale=1,minimum-scale=1">width 宽度设置的是viewport的宽度(device-width===设备宽度===完美视口) initial-scale:初始缩放比 maximum-scale:最大缩放比 minimum-scale:最小缩放比 user-scalable 用户是否可以缩放
rem+css预处理+媒体查询与rem+flexible.js做网页适配
1.vw:1vw等于视口宽度的1% 2.vh:1vh等于视口高度的1% 如100vw 在视口宽度为 375px大小时渲染处理的盒子宽度为 375px vw,vh与百分比不同的时vw,vh永远相当于视口的宽度,而百分比是相当于父元素的宽度
开发者拿到设计稿(假设设计稿尺寸为750px,设计稿的元素标注是基于此宽度标注) 开始开发,对设计稿的标注进行转换,把px换成vw。比如页面元素字体标注的大小是32px,转换为vw为 32/750(设计稿)*100vw 对于需要等比缩放的元素,CSS使用转换后的单位 对于不需要缩放的元素,比如边框阴影,使用固定单位
vw示例如下 利用sass自动将px转换为vw
// 设计稿宽度
$vw_base:750;
//将设计稿ps单位转换为vw
@function vw($px){
@return ($px/$vw_base) * 100vw;
}
*{
padding: 0;
margin: 0;
}
a {
text-decoration: none;
color: #707070;
}
.header{
height: vw(86); //86px
line-height: vw(86);
text-align: center;
color:#1c1c1c;
font-size: vw(35);
padding-bottom: vw(26);
border-bottom: 1px solid #eaeaea;
}但是上面的方法还不够完美,我们每次从设计图测得一个单位,都要进行 (实际像素/750)*100vw,而且由于它是利用视口单位实现的布局,依赖于视口大小而自动缩放,无论视口过大还是过小,它也随着视口过大或者过小,失去了最大最小宽度的限制。 如果你了解rem布局就会知道 我们通常给html设置一个字体大小
html{
font-size:100px
}
/*
1rem = 100px
3rem = 300px
*/1rem = html的font-size 这个特性有什么用? 以750px的设计稿为例 vw与1px的关系 0.13333...vw = 1px
上面提到 1rem = html的font-size 那我们将1px对应的vw设置成html的font-size不就可以了吗?
html{
font-size:0.13333333
}
//
.box1{
width:1rem//这里相当于1px的宽度
}这样我们只需算出1px对应的vw值 ,之后我们直接将设计稿的元素大小px换成rem就不可以了吗,这么干是有问题的!
理想很丰满现实很骨感
如果真的向上面那样做是不行的,我们给html设置font-size=0.133333实际上是指定html的font-size=1px,但是浏览器默认将html字体大小设置为12px ,不管你设置多少只要低于12px,浏览器都会将html字体大小设置为12px
这样我们就1rem就等于12px,这就与设计稿非常不符
那就没有解决办法了吗? 当然有,我们将原来的font-szie扩大40倍 也就是 0.1333333333333333 * 40 = 5.3333333333.....vw
扩大40倍后在给html的font-size赋值
html{
font-size: 5.33333vw
}由于我们将1px的vw扩大了40倍在进行元素宽度设置的时候我们要将设计稿测定的px除以40在进行设置
如我们测得设计稿某元素宽度为 48px ,那么他真实的宽度应该是 48/40 = 1.2rem 不一定每次都要我们手动计算,我们可以通过CSS预处理器进行计算
.box{
width:1.2rem
}我们还提到,第一种直接使用vw的方式会导致网页被无限拉伸,达到不好的用户体验,这里我们可以通过rem的特性解决无限拉伸的问题 1.给body规定最大与最小宽度
2.使用媒体查询限制html字体大小的值
另一种实现方式 这里我在网上找到了另一种办法,可以解决上述方法的尴尬处境,而且可以规定body宽度的区间,不至于被无限拉伸!【原文链接】
这样就和设计稿的比例达成一致,这也是京东的做法
更多参照传送门
【移动端布局之postcss-px-to-viewport(兼容vant)】
【自适应布局方案】