对像素和viewport的理解

字数 2411阅读 627
前言:

本文是在阅读关于viewport的两篇文章后,对于这些常常忘记和混淆的的知识有了一定的理解,为了方便以后查询和使用,以此文记录。如果你在看完此文后还是一知半解,可以点击这里查看原文。

一、设备像素和css像素

设备像素
  对于pc来说,设备像素就是屏幕的分辨率,比如1366*768,就是将屏幕横向分为1366个像素,纵向分为768个像素。一般来说,这个参数是固定不变的,但是你可以通过pc的显示设置去调节它,但没有人会去把分辨率调整到让自己不舒适的状态。
  这个属性可以通过JavaScript的screen.width/height属性得到。

css像素
  当你对某个div块设置width:100px;并设置背景颜色时,在浏览器中这个颜色的区域宽度就是100px的css像素。css像素的大小可以通过浏览器的缩放进行调节的。假设你的浏览器页面缩放为100%,此时一个css像素就对应1个设备像素;如果你将页面放大至200%,那么一个css像素就对应4个设备像素,因为宽和高都被拉伸了1倍。通过几张图片应该能够更好的理解它。

这是100%缩放时,css像素和设备像素完全重合


100%

缩小页面比例,css像素变小,一个设备像素覆盖了多个css像素

小于100%

放大页面比例,css像素变大,一个css像素覆盖多个设备像素

大于100%

二、属性

2.1 screen.width、screen.height
屏幕的分辨率,一般是不变的,度量单位为设备像素。

2.2 window.innerWidth、window.innerHeight
浏览器的内部尺寸,包括了滚动条,度量单位为css像素。
调整浏览器大小会改变值,改变页面的缩放比例也会改变值,因为它是用css度量的。

2.3 window.pageXOffset、window.pageYOffset
页面横向滚动距离和纵向滚动距离,可以理解为当前视口顶部页面顶部的距离,度量单位为css像素。当页面上下或者左右滚动时,相应的值会发生变化。

2.4 document.documentElement.clientWidth / Height
viewport尺寸,用css像素度量,不包括滚动条。即页面目前的可视窗口,调整浏览器大小和进行页面缩放会改变它的大小

2.5 document.documentElement.offsetWidth / Height
<html>元素的尺寸,用css像素度量。是整个页面的大小,如果你对html元素设置了固定的width和height,那么调整浏览器大小和进行页面的缩放不会改变它的大小。

viewport

首先要明确一点关系,屏幕显示器包含了浏览器,浏览器包含了viewport,viewport中包含了<html>元素。并且
document.documentElement.clientWidth / Height 指向viewport的大小
document.documentElement.offsetWidth / Height 指向html元素的大小

虽然viewport包含了html元素,实际上html元素是可以比viewport大的(你需要手动设置这个值)。通常开发者都不会去设定html元素的大小,那么此时html元素的大小时就是viewport的大小,你可以打开控制台,输入下面这条语句,结果一定是返回true。
console.log(document.documentElement.clientWidth===document.documentElement.offsetWidth)
  现在你可以打开编辑器,设置html的宽度为1000px或者其他,只要不等于viewport的宽度就行,再在控制台输入这条语句,结果一定是返回false。

三、事件中的坐标

3.1 pageX、pageY
表示相对于<html>元素的以css像素度量的事件坐标。

3.2 clientX、clientY
表示相对于viewport的以css像素度量的事件坐标。

3.3 screenX、screenY
表示相对于屏幕的以设备像素度量的事件坐标,一般是不会用到的。

四、媒体查询

@media all and(max-width:500px){...}

在媒体查询中,width和height查询的是viewport的宽高,以css像素度量

@media all and(max-device-width:500px){...}

device-width和device-height查询的是屏幕的宽高,是以设备像素作为度量的,这个参数一般是不变的,因此这个参数对于响应式的开发者来说是没有用处的。

五、移动浏览器的viewport

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

在移动web的开发中,常常可以看到这个标签,要了解这个各个参数的含义,首先要明白两个移动浏览器中的两个viewport:layout viewport和visual viewport。

layout viewport

这是 stack overflow上的George Cummins解释:

把layout viewport想像成为一张不会变更大小或者形状的大图。现在想像你有一个小一些的框架,你通过它来看这张大图。(译者:可以理解为「管中窥豹」)这个小框架的周围被不透明的材料所环绕,这掩盖了你所有的视线,只留这张大图的一部分给你。你通过这个框架所能看到的大图的部分就是visual viewport。当你保持框架(缩小)来看整个图片的时候,你可以不用管大图,或者你可以靠近一些(放大)只看局部。你也可以改变框架的方向,但是大图(layout viewport)的大小和形状永远不会变。

visual viewport

手机屏幕的大小就是visual viewport,即手机屏幕能显示的大小。
看看Chris给出的解释

visual viewport是页面当前显示在屏幕上的部分。用户可以通过滚动来改变他所看到的页面的部分,或者通过缩放来改变visual viewport的大小。

本人的理解是:想象你在高空中俯瞰大地,投入你视野的便是visual viewport,可以通过调整你的高度来调整你的visual viewport大小,高度越低,看到的范围越小(放大),高度越高,看到的范围越大(缩小);而整个大地,即layout viewport的大小和形状是不会变的。
  假设用css单位来衡量的话,那么layout viewport大小不变,即它的css像素大小不变,在手机屏幕上可以通过缩放来调节visual viewport的大小,当放大时,单位css像素所占的屏幕像素变大,因此整个屏幕的所占有的css像素变少,于是visual viewport变小;同理,当缩小时,visual viewport会变大。

两个viewport的关系:
通常来说,pc的显示器都远远大于手机,因此能显示的内容更多,可以认为在桌面浏览器中的html元素的大小即是整个layout viewport的大小。而在移动设备上,如果不对页面进行缩小,那么屏幕上只能看到layout viewport的一部分,就像这样

想要看到更多的layout viewport,那么就只能进行缩小。当layout viewport完全缩小在手机屏幕中时,此时两个viewport的大小时相等的。

度量layout viewport

同桌面浏览器一样,可以用document.documentElement.clientWidth / Height,这个属性指向了layout viewport的尺寸

度量visual viewport

window.innerWidth/Height可以用来度量visual viewport的尺寸,当用户缩小或者放大的时候,度量的尺寸会发生变化,因为屏幕上的CSS像素会增加或者减少。这和上面关于css的关于visual viewport的假设一致。

媒体查询

width和height使用layout viewport作为参照物,device-width和device-height仍然以设备像素作为参照,换句话说,
width和height以document.documentElement.clientWidth/Height为参照
device-width和device-height以screen.width/height为参照

meta标签

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
现在可以对meta标签来进行解释了
width=device-width:表示layout viewport大小为设备像素大小
initial-scale=1.0:表示初始缩放为1
minimum-scale=1.0:表示最小缩放为1
maximum-scale=1.0:表示最大缩放为1
user-scalable=no:表示不允许用户缩放

对于不同的手机浏览器,其规定的layout viewport大小不一,Safari iPhone为980px,Opera为850px,Android WebKit为800px,最后IE为974px。可以通过width来重置其大小。

假设你在一台iPad设备(设备像素为768*1024)上运行如下标签
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=yes">
那么其layout viewport即document.documentElement.clientWidth/Height为768,就算缩放也不会改变大小;
而其visual viewport :window.innerWidth/Height则会随着缩放而改变大小。

因此,当设置layout viewport为设备像素大小且禁止缩放时,就能使两个viewport的大小相等,从而使设置了媒体查询样式的页面适应手机屏幕。

结语

初次在简书写文章,语言组织混乱,有错误的地方还望原谅并指出。另外,对于物理像素和逻辑像素,本人还存在着疑问,希望能在下篇文章中得出答案。

推荐阅读更多精彩内容