译---a tale of viewport-part one


 

这一节将解释说明viewport和各类重要元素的宽度是如何工做的,例如元素<html>,以及窗口和屏幕。css

这个页面是关于桌面浏览器的,它的惟一目的是为移动浏览器的相似讨论奠基基础。大多数web开发人员已经直观地理解了大多数桌面概念。在移动设备上,咱们会发现一样的概念,可是更加复杂,而且对每一个人都已经知道的术语进行预先讨论将极大地帮助您理解移动浏览器。html

设备像素和css像素

第一个须要理解的概念是css像素,以及它与设备像素的差别。web

设备像素被直观的认为是“正确”的像素。它给出了咱们正在使用的各类设备的分辨率,能够经过读取screen.width/height获取具体的数值。数据库

若是给一个元素设置宽度width:128px,你的显示器是1024px,最大化你的浏览器,8个给定宽度的元素恰好填满你的显示屏(固然这并不是绝对精确,先忽略那些细节)。浏览器

若是用户使用放大或者缩小功能,填充的数量将会发生变化。若是放大浏览器到200%,那么填充1024宽度的显示器将只须要四个width:128px的元素。ide

在现代浏览器中,缩放只不过是“拉伸”像素。元素的宽度并无从128px变化为256px,可是实际像素翻倍了。形式上,该元素依然具备128个css像素的宽度,可是却占据了256个设备像素。布局

换句话说,缩放到200%,使得CSS像素扩大为设备像素的四倍(宽度两倍,高度两倍,总为四倍)。测试

用几张图来讲明这个概念。这里是一个缩放100%的四个像素。CSS像素与设备像素彻底重叠。网站

如今来缩小,CSS像素就会缩小,也就是一个设备像素与多个CSS像素重叠。ui

再来放大,就会发生相反的状况。CSS像素开始变大,结果一个css像素能够多个设备像素重叠。

这里的重点是,你只须要关注CSS像素,由于它直接影响你如何呈现元素样式。

设备像素对您几乎毫无用处。不是对用户;用户会将页面放大或缩小,直到他可以舒服地阅读为止。然而,缩放级别对您来讲并不重要。浏览器会自动确保你的CSS布局被拉伸或压缩。

100%缩放

最开始假设缩放100%,是时候给出一个确切的定义:

缩放级别100%,一个CSS像素正好等于一个设备像素。

100%缩放的概念对于理解接下来的内容颇有用,但平常工做中,并不须要过多担忧。在桌面,一般都是在100%缩放级别下测试你的网站,即便用户选择放大或者缩小操做,CSS像素的魔法会确保你的网站保持原有的布局。

屏幕尺寸(screen size)

看一看实际的测量。首先,screen.widthscreen.height,它们分别表示用户屏幕的宽度和高度。这个数值大小的单位是设备像素,由于它们不会发生改变:它们是显示器的特征,并不是浏览器的。

PS:IE7和IE8模式下,测量使用的是CSS像素。

Fun!可是咱们用这个信息来作什么呢?

基本上,什么都不作。用户显示器的大小对咱们来讲并不重要——除非你须要将这些数据记录在web统计数据库中。

窗口大小(window size)

相反,你须要知道浏览器窗口的内部尺寸。这个大小就是你能够用来进行CSS布局的空间大小。能够经过window.innerWIdthwindow.innerHeight得出这个数值。

PS:这个尺寸包含滚动条的宽度,单位是CSS像素。IE浏览器不支持。Opera得出的结果是设备像素单位。

显然,这个窗口的内部尺寸测量使用的是CSS像素。你须要知道你的布局有多少能够挤进浏览器窗口,当用户放大时,能够挤进去的内容就会减小。用户放大时,你可利用的窗口空间就会变小。window.innerWidth/Height数值就会反映出来。

Opera浏览器是一个例外。用户进行放大操做时,window.innerWidth/Height数值并不会发生变化。该数值的单位是设备像素。在桌面很烦人,在移动设备上确实很是致命的,下面再议。

记住,这个数值包含滚动条。滚动条也是包含在窗口的尺寸中(因为历史缘由)。

滚动偏移(scrolling offset)

window.pageXOffset和window.pageYOffset表示文档水平和垂直滚动的偏移量。经过这个数值,能够知道用户滚动了多少

这些测量数值是CSS像素单位的。不管缩放程度如何,你均可以知道文档被滚动了多少。

理论上,若是用户滚动了页面,而后再放大。window.pageX/YOffset会发生变化。事实上,浏览器试图经过在用户缩放时保持可见页面顶部的相同元素来保持web页面的一致性。虽然实际效果并不完美,可是重要的是window.pageX/YOffset并不会发生改变——滚动超出窗口的部分的CSS像素数值并不会发生改变。(通过测量,实际数值会发生很是微小的差距)

the viewport

在继续介绍更多JavaScript属性以前,咱们必须引入另外一个概念:viewport。

 viewport是用来约束<html>元素,该元素是网站页面最外层的包含块。

这样说可能仍是以为不太好理解吧。来举一个例子。假设你有一个流布局页面,页面中有一个宽度width:10%的侧边栏。当你调整浏览器窗口大小时,侧边栏会整洁的放大或者缩小。这是怎么回事呢?

从技术上来讲,侧边栏宽度就是其父元素宽度的10%。假设其父元素是<body>(你并无给body一个固定的宽度),那么问题就变成了<body>元素的宽度从何而来?

一般,全部块级元素会填充其父元素,也即宽度为父元素的宽度(固然也有例外,先忽略)。因此<body>和它的父元素宽度同样,也就是<html>元素。

那么,<html>的宽度呢?它和浏览器窗口同样宽,这就是为何侧边栏老是会占据浏览器窗口的10%。全部web开发人员都知道并在使用这个事实。

可是你可能想要知道这其中的原理。理论上,元素<html>的宽度是由viewport的宽度约束的。<html>获取viewport宽度的100%。

反过来,viewport与浏览器窗口彻底同样,由于它是被这样定义的。viewport并非HTML结构,不能够经过CSS影响它。在桌面系统,viewport的宽高就是浏览器窗口的宽高。可是在移动设备上略微复杂一点。

意外(consequences)

这种状况产生了一些奇怪的后果。你能够在这个网站上看到其中一个。滚动到顶部,并放大页面,以便该站点的内容溢出浏览器窗口。

如今向右滚动,您将看到站点顶部的蓝色栏再也不正常对齐。

 

 这就是viewport定义带来的意外。我给顶部的蓝色条设置width:100%,可是100%是相对于谁呢?是<html>元素,它和viewport具备同样的宽度,和浏览器窗口宽度同样。

 重点是,页面内容在100%缩放时彻底可以正常显示。当进行放大操做时,viewport变得比网站宽度要小了。对于它自己,这并无什么影响,内容从<html>中溢出了,可是因为设置了overflow:visible,溢出的内容都会显示出来。

顶部的蓝色条并无溢出。我设置了width:100%,因而浏览器给了它跟viewport同样的宽度。他们并不关心宽度是否是过小。

 

(这个图应该是带有水平滚动条的,可是图片看不出来)

文档宽度(document width?)

我真正须要知道的是页面的总内容有多宽,包括“突出”的部分。就我所知,要找到这个值是不可能的(嗯,除非您计算页面上全部元素的单独宽度和页边距,但这很容易出错)。

我开始相信,咱们须要一个JavaScript属性对来提供我称之为“文档宽度(document width)”(显然是CSS像素)。

若是咱们真的感受很时髦,那为什么不把这个值暴露给CSS呢?我很愿意将个人蓝色条宽度设置为100%的document  width,而不是<html>的宽度。(实现起来大概很棘手吧,即便没法实现,我也不会意外)

浏览器供应商们,大家怎么想呢?

测量viewport

你也许想要知道如何测量viewport。document.documentElement.clientWidth/Height提供了这样的功能。

若是你了解DOM,你就会知道document.documentElement其实就是<html>元素:HTML文档的根元素。然而,能够说,viewport更高一层。它是包含元素<html>的元素。这会影响到也许你会给<html>一个宽度(虽然我不推荐,可是这是可能并容许的)

在下面这种状况下,document.docuemntElement.clientWidth/Height依然会给出了viewport的数值,而非<html>元素。(这是一个特殊的规则,只适用于这个元素,只适用于这个属性对。在全部其余状况下,都使用元素的实际宽度)

document.documentElement.clientWidth/Height老是给出viewport的大小,不管<html>的多大多小

属性对

可是viewport宽度的大小不是也由window.innerWidth/Height给出的吗?是也不是。

有一个形式上的差异,那就是window.innerWidth/Height包含了滚动条,可是document.documentElement.clientWidth/Height没有包含。这有点吹毛求疵。

事实上,这两对属性是浏览器战争的遗留问题。当时Netscape只支持window.innerWidth/Heigh,IE只支持document.documentElement.clientWidth/Height。从那时起,全部其余浏览器都开始支持clientWidth/Height,但IE没有选择window.innerWidth/Height。

在桌面上有两个可用的属性对是一个小麻烦,但咱们将会看到,在移动端倒是一个福音。

测量html大小(page)

clientWidth/Height不管在设么状况下均可以给出viewport的大小。但,咱们从哪里能够知道<html>元素的大小呢 。该数值存储在document.documenElement.offsetWidth/Height

这些属性使您可以以块级元素的形式访问<html>元素;若是设置宽度,offsetWidth将会反映出这个数值。

事件坐标

接下来讲说事件坐标。当一个鼠标事件触发时,公开的属性对很多于5对,以提供有关事件确切位置的信息。在咱们的讨论中,其中三个问题很重要:

  1. pageX/Y可以给出相对于<html>元素的坐标(CSS像素)
  2. clientX/Y给出相对于viewport的坐标(CSS像素)
  3. scrrenX/Y给出相对于屏幕的左边(设备像素)

 

90%你都会使用pageX/Y,大多状况下,你须要知道事件相对于文档的坐标。剩下的10%,你会须要clientX/Y。而相对于屏幕的坐标几乎历来不用。

媒体查询

最后是一些关于媒体查询的单词。这个想法很是简单:能够定义特殊的CSS规则,只有当页面的宽度大于、等于或小于必定的值时才执行这些规则。例如:

div.sidebar {
    width: 300px;
}

@media all and (max-width: 400px) {
    // styles assigned when width is smaller than 400px;
    div.sidebar {
        width: 100px;
    }

}

侧边栏的宽度是300px,除非宽度小于400px时,侧边栏将会变成100px.

有一个问题:这里的宽度是什么宽度呢?

这里有两个媒体查询:width、height 和device-width/device-height

  1. width/height 使用的是document.docuemntElement.clientWidth/Height(也就是viewport),使用的CSS像素单位
  2. device-width和divece-height使用的是screen.width和height(也就是屏幕),使用的设备像素

咱们应该使用哪一个呢?显而易见,固然是:width。web开发者们对设备宽度(device width)不感兴趣,重要的是浏览器窗口的宽度。

因此使用width,忘记device-width吧——在桌面系统中。就如咱们所知,在移动设备中会复杂的多。

总结

设备像素与CSS像素是不一样的,web开发者基本上只须要关注CSS像素便可,css设置的值直接影响页面元素的CSS像素大小。

 

window.pageX/YOffset表示页面滚动偏移量。(滚动隐藏起来的部分CSS像素)

window.pageX/YOffset与document.docuemtnElement.scrollTop/Left获得的都是滚动偏移量。前者只读,后者能够读写。前者主要应用在现代浏览器中(IE8及其如下不兼容),后者几乎兼容全部浏览器(混杂模式的IE浏览器下,使用document.body代替document.docuemntElement)

 

document,docuemntElement,clientWidth/Height——viewport的大小

window.innerWIdth/Height表示浏览器窗口(标签页)的大小,包含滚动条。(CSS像素)

innerWidth/Height 和clientWidth/Height差别在包不包含滚动条(浏览器战争的遗留问题,IE不支持innerWidth)。

document.docuemntElement.offsetWidth/Height表示<html>大小,也就是页面的总大小。IE浏览器中获得的是viewport的大小,而非<html>的大小。

 

document.documentElement.clientX/Y——鼠标相对于视口(viewport)的位置。(10%)

document.documentElement.pageX/Y——鼠标相对于页面(page)的位置。(90%)

document.documentElement.screenX/Y——鼠标相对于屏幕的位置。(几乎不用)

 

媒体查询中用来的width/height是viewport的大小,也就是document.docuemntElement.clientWidth.Height.

 

有关移动浏览器的请看下一篇翻译

参考

  1. a tale of viewport -part one
  2. a tale of viewport -part two
  3. meta viewport
相关文章
相关标签/搜索