两个viewport的故事-桌面版(译)

在这个系列文章中,我将说明viewports和重要元素的宽度是如何工做的,好比<html>元素、window和 scrren的宽度。css

这篇文章是关于桌面浏览器的,目的是为介绍移动浏览器作好准备。大部分的web开发者已经对桌面浏览器的一些概念很熟悉了。在移动浏览器上咱们会发现一样的概念,只不过要更复杂一些,回顾一下这些熟悉的概念将对咱们理解移动浏览器有很大的帮助。
<!-- more -->html

设备像素和css像素

你须要理解的第一个概念是css像素和设备像素之间的区别。web

设备像素,顾名思义,不管你用什么设备,设备像素都是表示设备的实际分辨率。设备像素能够从screen.width/height读取。数据库

若是你给一个元素widht:128px,你的显示器是1024px宽,你最大化你的浏览器,这个元素能够在屏幕上平铺8个。(大概;忽略一些不肯定因素)浏览器

若是用户缩放了页面,这个值将发生改变。若是用户放大浏览器到200%,你的128px的元素只能在屏幕上平铺4个了。dom

用户缩放在浏览器中是经过拉伸像素实现的。也就是说,元素的宽度并无从128px变成256px,而是像素的尺寸变成了原来的两倍。综上,这个元素仍旧有128px的css像素,可是此时它却占有256px的设备像素。ide

换句话说,放到到200%使一个css像素尺寸了变成了4倍的设备像素的尺寸。(两倍的宽,两倍的高)。布局

下面几个图片能够很清楚的说明这个概念。第一个是缩放为100%,这个没什么可看的。css像素彻底覆盖了设备像素。网站

image

如今咱们缩小页面。css像素开始缩小,意味着一个设备像素能够覆盖若干个css像素。ui

image

若是你放大,相反的事情就发生了。css像素开始变大,如今一个css像素能够覆盖若干个设备像素

image

关键点在于你只须要关系css像素,它决定你的样式如何渲染。

设备像素对于你来讲几乎是无用的。对用户来讲不是,用户会缩放页面直到页面看起来舒服位置。可是这个缩放比对你来讲不重要,浏览器会自动根据缩放比来缩小或者放大的你的css像素。

100% zoom

我上面提到的例子,前提是100%的缩放。如今能够更严格的定义一下:

在100%缩放的状况下,css像素和设备像素是严格相等的。

这100%缩放的概念在咱们的这个解释中是很是有用的,可是咱们在平常开发中不须要过分担忧这个。在桌面浏览器开发中一般你都是在100%缩放的状况下,即便用户缩放页面,css像素的原理也能保证你的布局保持比例,不能打乱。

Screen Size

让咱们来看一下实际的尺寸吧。咱们从screen.widthscreen.height开始。他们表示用户屏幕的总宽度和总高度。他们的单位是设备像素,由于它们历来不会改变:它们是显示器的特性,不是浏览器的特性。

image

颇有意思!可是咱们能用这个信息作什么那?

基本没有用。用户的显示器尺寸对咱们来讲不重要,除非你想作一个web资料数据库。

Window Size

相反,你关心的是浏览器窗口的内部尺寸是什么。那会告诉你用于展现你的css布局的空间是多大。你能够经过window.innerWidthwindow.innerHeight来获取。

image

很明显,窗口的内部宽度的单位是css像素。你须要知道的是你的css布局有多少能够呈如今浏览器窗口中,并且这个呈现的数量会随着用户放大页面而减小(css像素越大,所呈现的内容越少)。所以若是用户放大页面,你可用的空间也就越少,在window.innerWidth/Height反应为值减少。

image

注意!这个宽度和高度包括滚动条。滚动条也被认为是浏览器窗口的一部分。(这个有历史的缘由)

Scrolling offset

window.pageXOffsetwindow.pageYOffset,表示document横向和纵向的滚动偏移。经过这两个属性,你能够知道用户滚动的位置。

image

这两个属性的单位也是css像素。理论上,若是用户向上滚动而后放大,window.pageX/YOffset应该发生改变。可是浏览器作了一些处理,在用户缩放的时候,浏览器试图使同一个元素保持在浏览器窗口的顶部来使页面看起来不会跳动。这意味着window.pageX/YOffset在用户缩放的时候不会改变:被滚动出屏幕的css像素数不会改变。

概念:the viewport

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

viewport的做用是限制<html>元素,是网站的最顶级的块级元素。

这听起来或许有一点模糊,咱们来举一个实际的例子。假设你有一个流体布局,你的侧边栏是width:10%.当你调整浏览器的大小时,侧边栏随着增大或减少。那它究竟是怎么工做的那?

从技术上说,侧边栏在获取它父元素的宽度的10%的时候发生了什么。咱们假定<body>元素为父元素。因此如今问题变成了<body>元素(你没有给<body>赋宽度)的宽度是多少。

一般来讲,全部的块级元素的宽度都是父元素的宽度的100%。所以<body>元素是和它的父元素<html>同样宽的。

如今<html>元素的宽度是多少那?为何它和浏览器同样宽。这也是为何你的width:10%的侧边栏占整个浏览器宽度的10%的缘由。全部的web开发者都知道这个事实。

你或许不知道这其中的工做原理。理论上,html元素的宽度是被viewport的宽度限制的。html元素等于viewport的宽度。

viewport和浏览器窗口相等的:它就是这么被定义的。viewport不是一个HTML结构,因此你不能靠css影响它。它就是有浏览器窗口的宽度和高度(桌面);在移动浏览器上它是比较复杂的。

结果

这些东西有时候会有一些奇怪的结果。你能这个网站(http://www.quirksmode.org/mob...。滚动到最顶部,而后放大页面2到3倍,使页面内容溢出浏览器窗口。

如今滚动到最右边,你将会看到顶部的蓝色栏再也不被正确的排列。

image

这个行为是viewport被定义的方式致使的。我给了蓝色顶部栏一个width:100%.什么的100%?html元素的100%。<html>元素和viewport是等宽的,因此和浏览器窗口也是等宽的。

重点是:在100%缩放时,它是正常的,如今咱们放大页面,致使viewport变的比咱们页面的总宽度小。对于它本身来讲这不重要,页面的内容溢出了html元素,可是html元素是[overflow](http://www.quirksmode.org/css/overflow.html): visible,这就意味着超出的元素会被显示。

可是蓝色顶部栏没有溢出。我给了它width:100%,浏览器会给它一个viewport的宽度。他们不关心如今的宽度过小了。

image

document width?

我真正想知道的是页面内容的总宽度是多少,包括突出的部分。据我所知,浏览器并未提供这个值。

我开始相信咱们须要一个js属性对来表示我称做"document width"的值。

image

若是咱们真是以为这样不爽,为何不把document width的值暴露给css那?我但愿蓝色顶部栏继承document宽度,而不是html元素的宽度。(这个确实有些棘手,若是不可能实现我也不会以为惊讶)

浏览器厂商,大家怎么认为那?

viewport尺寸

你或许想要知道viewport的尺寸。他们能够经过document.documentElement.clientWidth/clientHeight来获取.

image

若是你了解dom结构,你就知道document.documentElement实际上是<html>元素:<html>文档的根元素。然而,viewport是更高一级的,能够说它是包含<html>元素的元素。若是你给了<html>元素一个宽度,那就变得比较重要了(不推荐这样作,可是这是能够的)。即便在这种状况下,document.documentElement.clientWidth/clientHeight仍旧给出的是viewport的尺寸,而不是html的尺寸。(这是一个只对这个元素和这个属性对起做用的特例。其余状况下clientWidth/clientHeight都是取元素的真实尺寸)。

image

所以document.documentElement.clientWidth/clientHeight老是给出viewport的尺寸,无视html的尺寸。

两对属性值

那么viewport的尺寸是否是也能够由window.innerWidth/Height给出。答案是也不是。

这两对属性值的惟一区别在于,window.innerWidth/Height包括滚动条的宽度,document.documentElement.clientWidth/clientHeight不包括。

咱们之因此有两对属性是浏览器大战的产物。当时Netscape只支持window.innerWidth/Height,而IE只支持document.documentElement.clientWidth/clientHeight。当全部其余浏览器开始支持document.documentElement.clientWidth/clientHeight的时候,IE仍旧不支持window.innerWidth/Height.在桌面浏览器上有两个属性对是一个烦人的事情,可是在移动浏览器上它是一个福音。

html元素的尺寸

document.documentElement.clientWidth/clientHeight在全部的状况下都给出的是viewport的尺寸。那么咱们从哪里获取html元素自身的宽和高那?他们被存在document.documentElement.offsetWidth/offsetHeight里。

image

这两个属性真地给了你一个访问<html>元素做为块级元素的接口。若是你设置width或者offsetWidth将会影响这两个属性。

image

事件坐标

有一些事件坐标值。当一个鼠标事件发生时,很多于5对属性值会被暴露出来给你事件发生的具体位置信息。其中3对是对咱们的讨论来讲重要的:

1. pageX/Y给出相对于html元素的坐标,单位是css像素
2. clientX/Y给出相对于viewport的坐标,单位是css像素
3. screenX/Y给出相对于屏幕的坐标,单位是设备像素

pageX/Y

image

clientX/Y

image

screenX/Y

image

你90%的状况下都会使用pageX/Y;一般你想要知道相对于document的位置。其余的10%你想要用clientX/Y.你基本不须要知道相对于屏幕的尺寸。

媒体查询

最后,说一些媒体查询。这个思想很简单:你能够指定在页面在不一样条件下运行不一样的css,好比页面宽度大于、等于、小于某个尺寸的时候。

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

如今这个sidebar在宽度大于400px的时候宽300px,小于等于400px的时候宽100px;

问题是哪一个宽度和400px比较?

有两个相关的媒体查询:width/heightdevice-width/device-height.

1. `width/height`用的是`documentElement.clientWidth/height`(就是viewport)。单位是css像素。
2. `device-width/device-height`用的是`screen.width/height`.单位是设备像素。

image

应该用哪一个宽度?想都不用想,固然是width。web开发者对设备宽度不感兴趣,只是对浏览器窗口的宽度感兴趣。

在桌面浏览器上使用width,忘记device-width.正如咱们所看到的,这在移动设备上是更复杂的。

总结

这篇文章总结了咱们对桌面浏览器的探索。第二篇文章将介绍这些概念在移动浏览器的应用,并重点说明和桌面浏览器的不一样。

博客地址

相关文章
相关标签/搜索