精通移动端布局 - 概念篇 -

本文大多数的内容基本都是从多篇博客或相关文章中进行筛选,提炼出来,原本我也想用我匮乏的语言来描述,但是发现别人已经总结的更好了,所以...我还是乖乖的站在巨人的肩膀上吧~~


完整目录:

基本概念
    物理像素
    设备独立像素
    CSS 像素
    PPI的概念
    DPR的概念
    缩放的概念
    viewPort 的概念
    viewport 渲染流程
    Meta 标签说明

移动端布局实践
    混合方式
    REM 方式
        响应式
        JS自动换算
    缩放方式
        CSS3 缩放
        viewport 缩放

相关补充
    为什么需要meta标签?
    传统响应式布局与移动端响应式的区别
    移动端字体以及大小的设置
    移动端背景图缩放设置
    使用Sass提高px与rem转换效率
    通过Chrome进行真机调试
    weinre 远程调试


基本概念

物理像素

物理像素又叫“设备像素”,他是显示设备中最微小的物理部件,每个像素可以根据操作系统设置自己的颜色和亮度,正是这些微小距离欺骗我们的眼睛从而看到图像效果。
物理像素也是厂商在出厂时就设置好了的————即一个设备的分辨率是固定不变的。

设备独立像素

也叫“密度无关像素”,可以认为是计算机坐标系统中的一个点,这个点代表一个可由程序使用的虚拟像素(比如CSS像素),然后由相关系统转换为物理像素。

CSS 像素

CSS像素是一个抽象单位,主要使用在浏览器上,用来精确度量(浏览器层面而言)WEB页面上的内容,一般来说CSS像素也被称之为设备无关像素(device - independent pixel) 简称DIPS。
在不同的屏幕上,CSS像素所呈现的物理尺寸实质上都是一样的,而不同的是CSS像素与所对应的物理像素具数是不一致的,在普通屏幕下,1个css像素对应的就是1个物理像素,而 retina 屏幕下,1个 css 像素对应的却是多个物理像素。这一点在移动端上会更加的明显,而在100%缩放模式下PC端上,我们就可以认为 1物理像素就等于1css像素。

总的来说,物理像素是设备在物理层面上不可再分割的最小单元,而“设备独立像素”则是一个统称的概念,它主要指的是应用软件在应用层面上如何度量内容,可以这么说,CSS像素就是设备独立像素中的一种,是WEB浏览器主要采用的度量单位。

PPI的概念

PPI 就是屏幕密度,它是指显示设备上每英寸(1英寸约等于2.54厘米)长度内存在的像素数量,单位即PPI。

其换算公式如下:

PPI最直观的的效果可以参考下图:
PPI

按照苹果公司的技术营销宣传,在 320PPI 以上的屏幕都可以被称之为retina屏幕。

DPR的概念

DPR 便是 device Pixel Ratio 的简称,即设备像素比,它反映了设备上的物理像素与设备独立像素对应关系,也就是说 DPR 可以让我们知道当前设备下逻辑像素与物理像素的对应情况。
它的值可以按照下面的公式计算出来:

设备像素比 = 物理像素 / 设备独立像素

在JavaScript中我们可以直接通过以下window上的属性获取设备像素比

    window.devicePixelRatio

而在CSS中,可以通过以下属性获得:

-webkit-device-pixel-ratio;
-webkit-min-device-pixel-ratio;
-webkit-max-device-pixel-ratio; 

缩放的概念

在说缩放之前,我们先定义一个略微严格的规定:

100% 缩放情况下:1css像素 == 1物理像素

带着这个定义我们来看页面在浏览器中的缩放情况:
首先我们假如有一个2px * 2px 宽高的盒子。根据定义在100%缩放情况下 2px * 2px 是完全等同于 2px * 2px的物理像素。
如果现在去缩放浏览器,我们会发现2px*2px的尺寸会随着缩放而发生变化。实际上现代浏览器的缩放功能就是通过拉伸像素的方式实现的。而这种拉伸像素的方式也更能够让我们清晰了解独立像素与物理像素之间的差异。
首先,我们可以很明确的知道,浏览器不管怎么拉伸像素它也不可能改变物理层面上的像素(物理像素),所以它能也只能够改变自己的逻辑像素 - CSS像素,在放大的情况下 1css像素 会占据多个物理像素,从而在应用层面上使显示区域宽度变小,浏览器为了能够显示完整的内容从而出现滚动条,而缩小的情况下,多个css像素会被合并在一个1个物理像素中去显示。但是这种方式实际上是一种有损的过程,因为用1个物理像素去表示多个CSS像素,会导致内容丢失更多的细节。正是因为css像素的丢失,才导致内容变的更小。
更直观的了解可以看下图:
100%模式下 1css像素就等于 1物理像素

在放大的情况下,1css像素会占据多个物理像素

在缩小的情况下,多个css像素会被合并在物理像素中

viewPort 的概念

桌面环境下 viewport
viewport 实际上在桌面浏览器中就已经存在,让我们回忆下一下,如果现在页面上有一个空的 div ,其宽度默认是100%,那么这个100%的宽度是怎么产生的呢?我们可以知道它是继承其父元素 body,而body的宽度又是继承其父元素 html。所以 body 元素和它的父元素 html 一样宽。

那么 html 元素的宽度是多少?它的宽度和浏览器窗口宽度一样。你可能不知道的是这个行为在理论上是如何工作的。理论上, html 元素的宽度是被viewport的宽度所限制的。 html 元素使用viewport宽度的100%。
在桌面环境下,viewport 实际上就等于浏览器窗口,拥有浏览器窗口的宽度和高度,但viewport并不是一个HTML结构,所以你不能用CSS来改变它。

在桌面环境下我们可以很容易的理解viewport,但是在移动浏览器环境下它会有一些复杂。

手机端 viewport
在手机端上viewport类似于一个虚拟的视口,通常情况下这个虚拟的视口要比设备屏幕宽。
将网页放入到虚拟的视口(viewport)中去显示,是为了解决过小的屏幕在显示过大的网页(如专为桌面浏览器设计的网页)时,导致出现滚动条从而影响在移动设备上的浏览体验,但同时也会导致页面整体布局的缩小,文字不清晰,链接不方便点击等问题,而且viewport也会破坏专门针对手机浏览器设计的网页布局。
所以在对于专门为手机端制作的网页,建议将viewport设置如下:

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

若按照PPK大神的理论,可将viewport分为三种,而前文我们所说的用来显示页面的viewport,我们称之为 layout viewport,即布局 viewport,layout viewport 随着浏览器厂商的不同,其默认的尺寸也不尽相同,但常用的有 980px 1024px 等,除了layout viewport,还有 visual viewport,即视觉viewport,也就是我们设备屏幕的物理尺寸,它也是物理实际存在的,例如:iphone5 是 320 * 568 。
若就嵌套关系来说 layout viewport 是嵌入在 visual viewport 中的,具体关系可以参照下图:

visual viewportlayout-viewport

现在我们已经有两个viewport了:layout viewport 和 visual viewport。但开发者觉得还不够,因为现在越来越多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的viewport。所谓的完美适配指的是:

· 首先不需要用户缩放和横向滚动条就能正常的查看网站的所有内容;
· 其次显示的内容大小是合适的。

比如一段14px大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段14px的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的。当然,不只是文字,其他元素像图片什么的也是这个道理。ppk把这个viewport叫做 ideal viewport,也就是第三个viewport——移动设备的理想 viewport。
ideal viewport 并没有一个固定的尺寸,不同的设备拥有有不同的 ideal viewport
但一般来说,ideal vieport 就等于 visual viewport

viewport 渲染流程

不确保正确,但以下内容至少是我对一个页面在被载入到手机浏览器中渲染过程的猜想。
示例手机:

分辨率:1920*1080
屏幕尺寸:640 * 360
设备像素比: 3

示例站点:
12306,年关将至想必也是大家比较常上一个网站

内容:
layout viewport在渲染页面之前,会根据自身的宽度(默认或者meta指定)来设定CSS像素与 物理像素的占比。通过占比来决定内容的缩放程度,而这个缩放值,则是由 visual viewport 与 layout viewport决定的,其换算公式如下:

    scale = layout viewport / visual viewport

在正常情况下比较好理解,就如我手机分辨率宽度是1080来算,此时 我默认的viewport是980,现在基本上就是1css像素 == 1物理像素,但因为 PPI 的原因,单位物理像素要更加的小,所以整体页面被缩小的形式显示在我的手机屏幕中,而且,12306默认的宽度是960,所以这960相对于我viewpot还剩有20px的左右边距。因为我的物理像素是大于vieport默认的尺寸的,所以逻辑像素并没有缺省,但是如果在比较老的iphone5上面,其实际分辨率是 640*1136,而viewport也默认为980,实际上在展示页面的时候逻辑像素会超出物理像素300多,因此逻辑像素有缺省,整个页面是以一种牺牲部分细节有损的方式去展示的。

如果我指定了viewport的宽度为 width = device-width 。那么此时 1css像素 == DPR * 物理像素,同时这个值也是当前的缩放值。但是我若指定了 initial-scale = 1 时,则强制了 css像素 与 物理像素为1:1的对比关系。

这些还都是简单的渲染流程,如果涉及到缩放,实际上手机端在去渲染网页时,其情况可能会更加的复杂,而且,不同的手机厂商,不同的浏览器厂商,其实现的方式都是有差异的,如果想制定一套统一的标准去试图阐述移动端网页渲染流程,我个人认为实际上也是没有意义的。我们只需要知道大致常规的渲染流程,就可以更好的帮助我们进行移动端的网页开发。

Meta 标签说明

meta标签首先是由苹果公司在其safari浏览器中引入的,目的就是解决移动设备的viewport问题。后来安卓以及各大浏览器厂商也都纷纷效仿,引入对meta viewport的支持,事实也证明这个东西还是非常有用。

在苹果的规范中,meta viewport 有6个属性(暂且把content中的那些东西称为一个个属性和值),如下:

AttributeValueDescription
width num 设置layout viewport 的宽度,为一个正整数,或字符串"width-device"
initial-scale num 设置页面的初始缩放值,为一个数字,可以带小数
minimum-scale num 允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale num  允许用户的最大缩放值,为一个数字,可以带小数
height num 设置layout viewport 的高度,这个属性对我们并不重要,很少使用
user-scalable str 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许

这些属性可以同时使用,也可以单独使用或混合使用,多个属性同时使用时用逗号隔开就行了。
此外,在安卓中还支持 target-densitydpi 这个私有属性,它表示目标设备的密度等级,可以自动设定css中的1px代表多少物理像素,开发者无需考虑换算的过程
target-densitydpi 值可以为一个数值或 high-dpi 、medium-dpi、low-dpi、device-dpi 这几个字符串中的一个,特别说明的是,当 target-densitydpi=device-dpi 时, css中的1px会等于物理像素中的1px。

因为这个属性只有安卓支持,并且安卓已经决定要废弃target-densitydpi 这个属性了,所以这个属性我们要避免进行使用 。


参考链接:
http://blog.csdn.net/aiolos1111/article/details/51967744
http://www.cnblogs.com/Mrs-cc/p/5329545.html
http://www.cnblogs.com/2050/p/3877280.html

posted @ 2019-03-21 21:27  啊睦  阅读(277)  评论(0编辑  收藏  举报