咱们一般在写移动端页面时,每每都会在html页面中加入这样一段话css
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
可能咱们只知道这三个字段的含义(视口宽度等于设备宽度,屏幕缩放为1,禁止用户缩放),可是为何要这么写,其原理又是什么呢?html
咱们先看一个简单的demo吧。ios
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test 02</title> </head> <style> body{ margin: 0; } .pic{ width: 320px; height: 568px; background-color: #72DFFF; color: white; font-size: 60px; text-align: center; line-height: 568px; font-family: cursive; } </style> <body> <div class="pic"> 320*568 </div> </body> </html>
该demo展现一个宽度为320px的div,咱们在iphone5上面打开看一下。浏览器
有没有感受很诡异?明明iphone5的分辨率是320px*568px(我使用的是谷歌的mobile模拟),可是只显示了三分之一左右。iphone
在回答此问题以前,咱们须要先普及一下一些移动端的概念。布局
px:逻辑像素优化
dp:设备像素(物理像素)网站
dpr:设备像素缩放比spa
(某一方向上-->计算:dpr = 设备像素/逻辑像素,平面上-->计算:1px = (dpr)² *dp)scala
ppi:屏幕每英寸的像素数量,即单位英寸内的像素密度(计算:分辨率平方后开跟/屏幕尺寸)
ppi与dpr的关系表
ldpr | mdpr | hdpr | xhdpr | |
ppi | 120 | 160 | 240 | 320 |
默认缩放比 | 0.75 | 1.0 | 1.5 | 2.0 |
咱们得知iphone5的尺寸为4英寸,设备分辨率为1136dp*640dp,由此咱们能够得出iphone5的分辨率为320px*568px,以下图(retina为高清)。
该页面展现三分之一的缘由是ios中默认的布局viewport是980px,而后根据刚才的计算的iphone5分辨率才会出现此状况。
逻辑像素(css pixels)与设备像素(device pixels)的区别------------
咱们姑且认定设备的pixels为正确(标准)的pixels宽度。这些pixels决定了你工做所用的那些设备上正式的分辨率。
若是用户缩放(zoom)了浏览器,固然必须改变计算方式。
现代浏览器上的缩放,是基于“伸展”pixels。结果是,html元素上的宽度并无由于缩放200%而由128pix变成256px,而是真实的pixels的被计算成了双倍。html元素在形式上依然是128CSS的pixels,即使它占用了256设备的pixels 。
换言之,缩放200%将一个单位的CSS的pixels变成了4倍的设备的pixels那么大,即宽度 * 二、高度 * 2,面积扩大了2 * 2.
下列图片将清楚的解释这个概念。如图1-1.有4个1像素,缩放为100%的html元素,CSS的pixels完整的和设备的pixels重叠
当咱们缩小浏览器时,CSS的pixels开始收缩,致使1单位的设备的pixels上重叠了多个CSS的pixels,如图1-2
同理,放大浏览器时,相反的事情发生了,CSS的pixels开始扩大,致使1单位的CSS的pixels上重叠了多个设备的pixels,如图1-3
整体而言,你只须要关注CSS的pixels,这些pixels指定你的样式被如何渲染。
就像刚开始的那个小demo,在pc以及iphone5上展现是两种彻底不一样的效果。
在这里我普及一个知识点,对于viewport,苹果手机浏览器默认作了两件事——
1.页面渲染在一个980px(IOS)的viewport(安卓viewport宽度不固定)
2.缩放
说的详细一些,viewport,就是手机浏览器把页面放到一个虚拟的窗口中,窗口可大于或小于手机的可视区域,通常会大于可视区域。这样不会破坏没有针对手机浏览器优化的网页的布局,用户能够经过平移或缩放来看网页的其它部分。
这也就是为何咱们没写viewport,手机会默认将布局宽度置为980px的缘由。
为何要有viewport?
一个300多像素的屏幕,放一个1000多像素的页面,会混乱,因此要先虚拟一个980像素的页面,而后进行缩放。
为何不使用默认980px的布局viewport
1.宽度不可控,不一样设备(安卓)默认值可能不一样
2.页面缩小版展现,交互不友好
3.有缩放,缩放后有滚动
4.font-size 可能要设置40px才等于pc上12px,不规范
而后为了在iphone5上正常展现,咱们须要写这样一个viewport
<meta name="viewport" content="width=320">
这样效果ok,可是若是咱们的设备是iphone6,iphone6s呢?
<meta name="viewport" content="width=375">
显然是不符合规定的,因此咱们须要设置
<meta name="viewport" content="width=device-width">
可是每一个不一样的设备都会有不一样的缩放比
window.innerWidth/document.body.clientWidth 为 initial-scale
度量viewport/布局viewport [Layout Viewport(布局视口)]
好比若是要让iphone6展现1000px的页面,只设置"width=device-width",确定都会挤在一块儿。
因此须要让缩放比为1,设置initial-scale=1,因此最终版本是这样
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
最后总结一下移动端中的三个viewport——
1.布局视口
document.body.clientWidth 为手机浏览器viewport宽度(布局viewport),默认980
跟width=device-width相关,其值等于meta标签中的width
initial-scale = 2 ,它会跟着缩小一倍
当你须要使用js而不是媒体查询来编写业务逻辑的时候,这颇有帮助
if(document.body.clientWidth >= 400){
.class{...}
}
等价于
@media all and (max-width>=400){
.class{...}
}
咱们用到的vw,vh尺寸单位表明视口的百分比,好比width:50vh,这里的视口就是指布局视口,由于若是是视觉视口,每次用户缩放都会致使元素狂傲发生变化,先不说这个变化带来的大计算量,这种设计对用户来讲自己就是毫无心义的。
2.视觉视口
window.innerWidth
屏幕上显示的网站区域尺寸,会受缩放的影响
3.理想视口
screen.width
它是对设备来讲最理想的布局视口尺寸。
-----------------------------------------------------------------------------------------------------------------------
在手机上,桌面视口被拆分红两个——布局视口限制你的css布局,视觉视口决定用户能看到什么。
其实这么多的viewport看起来可能会乱一点,但事实并非这样。最佳实践就是让浏览器直接使用它的理想视口,即把布局视口设置为理想视口,而后使用媒体查询来响应不一样的理想视口就OK。
响应式设计的核心—— width和height的媒体查询设置了当前布局视口的宽高。 使用最佳mate标签后,就能够放心的抛开布局视口的宽度,只专一于理想视口 @media all and (max-width:400) { .class { ... } }