Viewports介绍

       A tale of two viewports — part one

In this mini-series I will explain how viewports and the widths of various important elements work, such as the <html> element, as well as the window and the screen.
This page is about the desktop browsers, and its sole purpose is to set the stage for a similar discussion of the mobile browsers. Most web developers will already intuitively understand most desktop concepts. On mobile we’ll find the same concepts, but more complicated, and a prior discussion on terms everybody already knows will greatly help your understanding of the mobile browsers.
                                                        双口记 1
            在这部微系列中,我将详细解释 viewports 以及网页设计中其他重要的元素的度量设定,比如 html, 比如 window screen.
            本卷内容是关于桌面浏览器的,目的只有一个:为下章的手机浏览器讨论做准备。各种桌面网页设计者们耳熟能详的概念 , 在手机上面也有,但是更复杂。这里先讨论大家都熟悉的桌面电脑,有助于更好的理解手机下的场景。

Concept: device pixels and CSS pixels

The first concept you need to understand is CSS pixels, and the difference with device pixels.
Device pixels are the kind of pixels we intuitively assume to be “right.” These pixels give the formal resolution of whichever device you’re working on, and can (in general) be read out from screen.width/height .
If you give a certain element a width: 128px , and your monitor is 1024px wide, and you maximize your browser screen, the element would fit on your monitor eight times (roughly; let’s ignore the tricky bits for now).
If the user zooms, however, this calculation is going to change. If the user zooms to 200%, your element with width: 128px will fit only four times on his 1024px wide monitor.
Zooming as implemented in modern browsers consists of nothing more than “stretching up” pixels. That is, the width of the element is not changed from 128 to 256 pixels; instead the actual pixels are doubled in size. Formally, the element still has a width of 128 CSS pixels, even though it happens to take the space of 256 device pixels.
In other words, zooming to 200% makes one CSS pixel grow to four times the size of one device pixels. (Two times the width, two times the height, yields four times in total).
A few images will clarify the concept. Here are four pixels on 100% zoom level. Nothing much to see here; CSS pixels fully overlap with device pixels.
Now let’s zoom out. The CSS pixels start to shrink, meaning that one device pixel now overlaps several CSS pixels.
If you zoom in, the opposite happens. The CSS pixels start to grow, and now one CSS pixels overlaps several device pixels.
The point here is that you are only interested in CSS pixels . It’s those pixels that dictate how your style sheet is rendered.
Device pixels are almost entirely useless to you. Not to the user; the user will zoom the page in or out until he can comfortably read it. However, that zooming level doesn’t matter to you. The browser will automatically make sure that your CSS layout is stretched up or squeezed in
概念:设备像素和CSS像素
首先你要明白, CSS 中使用的像素,和设备的像素是不一样的
设备像素是我们最能理解的像素,或者可以说是“真实”的像素,它描述了一个设备的分辨率。 可以通过 screen.width/height 来获取
假如你设计了一个 128px CSS 像素)的元素, 而你电脑显示屏的大小是 1024px( 设备像素 ) ,在正常显示下,即没有放大和缩小的情况下 , 那么该元素是你屏幕的 1/8 大小,也就是说在没有放大和缩小的情况下, 1 CSS 像素的大小等同于 1 个设备像素
OK, 现在用户开始缩放,比如用户把网页放大到 200% 。由于显示屏的大小不会变大缩小,依然是 1024 像素,网页放大到 200% 的时候,你所设计的 128px 元素就会是屏幕的 1/4 大小了,被“放大”了两倍。
这里面就有问题了,屏幕的 1/4 ?, 1024 1/4 就是 256 个像素大小,也就是说该元素的 CSS 定义从 128px 变成了 256px 吗?答案是“ No ”,该元素的 CSS 定义依然是 128 个像素,但是, 每个像素的大小变了。 也就是说在没有放大以前 , 一个 CSS 像素的大小等同于一个设备像素,在放大以后,一个 CSS 像素的大小已经是两个设备像素的大小了。
换句话说,放大到 200% 之后,设备像素不变, 1024px. CSS 像素不变, 128px. 但是 CSS 像素的大小变了。长宽都被放大了两倍。
下面我们用一些图例来说明。
在不放大缩小的情况下, 4 个设备像素和 4 CSS 像素一一对应,完全重合

这是开始缩小网页时的情况, CSS 像素的长宽变小了。一个设备像素大于一个 CSS 像素

这是放大网页时的情况, 1 CSS 像素要大于 1 个设备像素

可以这样理解,我们在网页设计的时候, 只需要关心CSS像素 。设备像素完全无用。但是对于用户来说,设备像素很有用。设计者不一样,你设计出来的网站会自动被拉伸或者缩小,以适应设备屏幕。当然,你如果想设计一个不拉伸或者缩小的网页,自然要了解下目标屏幕。
100% zoom
I started the example by assuming a zoom level of 100%. It’s time to define that slightly more strictly:

At zoom level 100% one CSS pixel is exactly equal to one device pixel.

The concept of 100% zoom is very useful in the explanations that are going to follow, but you shouldn’t overly worry about it in your daily work. On desktop you will generally test your sites in 100% zoom, but even if the user zooms in or out the magic of CSS pixels will make sure that your layout retains the same ratios.
100%缩放
为了方便后续的讨论,我们来定义一下 100% 缩放的含义。 100% 缩放就是指: 1 CSS 像素大小完全等同于一个设备像素的情况

Screen size

Let’s take a look at some practical measurements. We’ll start with screen.width and screen.height. They contain the total width and height of the user’s screen. These dimensions are measured in device pixels because they never change: they’re a feature of the monitor, and not of the browser.


显示器尺寸(用设备像素定义)
让我们继续用图示来给一些实际的说明。从 screen.width, screen.height 开始。这两个描述了用户显示屏幕的宽度和高度,对于网页设计者而言,其值固定不变,决定于显示器设置而不是浏览器设定。

Fun! But what do we do with this information?
Basically, nothing.  The user’s monitor size is unimportant to us — well, unless you want to measure it for use in a web statistics database.
不错!但是要这个信息来有鸟用?
一般说来,没鸟用。如前所述,用户的显示屏幕大小对我们无关紧要。当然,除非你有特别的想法

Window size

dimensions of the browser window. That tells you exactly how much space the user currently has available for your CSS layout. You can find these dimensions in window.innerWidth and window.innerHeight .
Note that the measured widths and heights include the scrollbars. They, too, are considered part of the inner window. (This is mostly for historical reasons.)

窗口尺寸(用 CSS 像素定义)
指的是浏览器窗口尺寸。对于网页设计者而言,就是说可以供你显示内容的空间大小。用 window.innerWidth and window.innerHeight 来定义。
需要注意的是这个大小居然是用 CSS 像素定义的,额滴神啊,我也是才知道。也就是说,用户在不改变浏览器窗口大小的情况下,放大和缩小网页, window.innerWidth window.innerHeight所返回的值也会不同。在放大时候,这个值就会变小。这个非常重要,在放大的时候,CSS就会明白,可供显示的空间变小了,因为像素变大了。
(当然也有例外,Opera浏览器使用设备像素来衡量该值的,并不会随着用户的缩放而改变,设备像素总是固定的,这个特别的浏览器。。在电脑上处理他的时候你会很纠结,当你在手机上处理他的时候,你会崩溃)
需要注意的是该宽度和高度包括滚动条哦,滚动条应该被包括进来吗?显然不应该,显示内容跟它没鸟关系。但是你懂的,任何不合理的理由只有一个:历史原因。

Scrolling offset(用CSS像素定义)

window.pageXOffset and window.pageYOffset , contain the horizontal and vertical scrolling offsets of the document. Thus you can find out how much the user has scrolled.
These properties are measured in CSS pixels, too. You want to know how much of the document has already been scrolled up, whatever zoom state it’s in.
In theory, if the user scrolls up and then zooms in, window.pageX/YOffset will change. However, the browsers try to keep web pages consistent by keeping the same element at the top of the visible page when the user zooms. That doesn’t always work perfectly, but it means that in practice window.pageX/YOffset doesn’t really change: the number of CSS pixels that have been scrolled out of the window remains (roughly) the same.
window.pageXOffset window.pageYOffset用来描述该网页被水平/垂直滚动了多少。如图所示。
同样,该属性是用CSS像素定义的。那就是说,会随着缩放而改变大小。But,真的吗?理论上,应该是,但是,NO, 这个大小并不会总是随着网页的缩放而改变。当缩放的时候,你会注意到,当前网页最顶端的元素往往还会是在最顶端,浏览器尝试着不改变用户当前所浏览的内容,目的是更好的用户体验。当然,这只是一种尝试,也有改变的时候。但不管怎么说,这套逻辑的结果就是,无论如何缩放,window.pageXOffset window.pageYOffset都不会改变,至少,不会改变太多。

Concept: the viewport

Before we continue with more JavaScript properties we have to introduce another concept: the viewport.
The function of the viewport is to constrain the <html> element, which is the uppermost containing block of your site.
That may sound a bit vague, so here’s a practical example. Suppose you have a liquid layout and one of your sidebars has width: 10% . Now the sidebar neatly grows and shrinks as you resize the browser window. But exactly how does that work?
Technically, what happens is that the sidebar gets 10% of the width of its parent. Let’s say that’s the <body> (and that you haven’t given it a width ). So the question becomes which width the <body> has.
Normally, all block-level elements take 100% of the width of their parent (there are exceptions, but let’s ignore them for now). So the <body> is as wide as its parent, the <html> element.
And how wide is the <html> element? Why, it’s as wide as the browser window. That’s why your sidebar with width: 10% will span 10% of the entire browser window. All web developers intuitively know and use this fact.
What you may not know is how this works in theory. In theory, the width of the <html> element is restricted by the width of the viewport. The <html> element takes 100% of the width of that viewport.
The viewport, in turn, is exactly equal to the browser window: it’s been defined as such. The viewport is not an HTML construct, so you cannot influence it by CSS. It just has the width and height of the browser window — on desktop. On mobile it’s quite a bit more complicated.
在继续前进之前我们先介绍一个重要的概念: Viewport. 今天的主角。
Viewport 有什么 用?我们来一个例子吧,加入你定义了一个工具条,宽度为 10% 。那么,在你缩放窗口的时候,它会永远 10% 。请问,它是怎么动态计算宽度的呢?
从技术上讲, 10% 的工具条,该百分比是相对于其父节点的,这个工具条是定义在 body 里面的,那么父节点就是 body, OK, 现在的问题变成了,计算 Viewport 的宽度只需要知道 body 的宽度就好, body 的宽度又是多少呢?
其实一样的道理,一个 block 类型的元素,它的宽度就等同于 100% 父节点的宽度(特殊情况除外),所以,要知道 body 的宽度,只需要知道 html 的宽度。
Html 的宽度又是多少?很显然了,就等于浏览器窗口的宽度
更专业的讲, html 的宽度是 Viewport 规定的, Viewport 的宽度和浏览器的宽度完全相等,它的值不属于 html 管理,用 CSS 无法改变。其大小完全等同于浏览器窗口的大小。当然,切记本片讨论的是桌面浏览器,对手机而言,又是另外一回事。
所以总结如下:
            Viewport 规定了 html 的大小, html 的大小又影响了它所有 child 的大小。在电脑浏览器上, Viewport 完全等同于浏览器的尺寸
Consequences

后果。后果很严重, Viewport 的这种特性会带来一些负面效果,加入你设计了一个宽度为 100% 的元素,当你把网页放大到最大,再把滚动条往右边拖的时候,你会发现该元素的后面没了,也就是说,该元素的宽度并没有完全的填满页面,只是填满了浏览器窗口。原因?原因很简单,宽度为 100% ,也就是说宽度等同于 Viewport 的大小,等同于浏览器窗口的大小,当放大的时候,浏览器窗口并不会改变,所以,该 100% 也不会变。
document width?

What I really need to know is how wide the total content of the page is, including the bits that “stick out.” As far as I know it’s not possible to find that value (well, unless you calculate the individual widths and margins of all elements on the page, but that’s error-prone, to put it mildly).
I am starting to believe that we need a JavaScript property pair that gives what I’ll call the “document width” (in CSS pixels, obviously).
And if we’re really feeling funky, why not also expose this value to CSS? I’d love to be able to make the width: 100% of my blue bar dependent on the document width, and not the <html> element’s width. (This is bound to be tricky, though, and I wouldn’t be surprised if it’s impossible to implement.)
Browser vendors, what do you think?
很显然,有时候是需要知道页面的整体宽度的,也就是浏览器内的宽度加上浏览器外的宽度。遗憾的是,现在还没有现成的值。我们需要一个 javascript 属性对来提供该值。这个值用 CSS 像素衡量,那是必须的。各位浏览器厂商们,听到群众的呼声了吗?

Measuring the viewport

You might want to know the dimensions of the viewport. They can be found in document.documentElement.clientWidth and -Height .
Viewport 的宽度等同于浏览器的宽度,是否 window.innerWidth window.innerHeight 可以得到? NO, 从下面的图片可以看出来,准确的应该是 window.innerWidth window.innerHeight 再减去滚动条的长度和宽度。 那要怎么得到呢?
实际上,用 document.documentElement.clientWidth document.documentElement.clientHeight 可以得到 viewport 的尺寸。如果你了解 DOM ,就会知道 document.documentElement 其实就是指的html对象,第一眼的印象就是, document.documentElement 既然是指 html 元素,那么 document.documentElement.clientWidth/Height 就应该是 html 的长度和宽度。
其实不然,viewport不属于html管理,比html节点更为高级。即使你设置了 html 的宽度和高度, document.documentElement.clientWidth/Height 也是指 viewport 的长度和高度,如下图
(作者本节的分析是基本上扯淡的,经过本人测试, document.documentElement.clientWidth/Height 会返回 HTML 的长宽而不是 viewport 的值,怎么样才能得到 viewport 的值?我也还不知道。)

Measuring the <html> element


So clientWidth/Height gives the viewport dimensions in all cases. But where can we find the dimensions of the <html> element itself? They’re stored in document.documentElement.offsetWidth and -Height .
那怎么样才能得到 html 的长宽呢?通过 document.documentElement.offsetWidth - Height. 可以得到,(当然,如前面测试,通过 document.documentElement.clientWidth/Height 也能得到,这两个值在 safari firefox chrome 上测试是一样的,但是在 IE 上面,则都返回为很奇怪很奇怪的值。)
继续上图,说明 document.documentElement. offsetWidth /Height 的取值范围。

Event coordinates

Then there are the event coordinates. When a mouse event occurs, no less than five property pairs are exposed to give you information about the exact place of the event. For our discussion three of them are important:

1.    pageX/Y gives the coordinates relative to the <html> element in CSS pixels.

2.    clientX/Y gives the coordinates relative to the viewport in CSS pixels.

3.    screenX/Y gives the coordinates relative to the screen in device pixels.

额。。关于事件的坐标,当一个鼠标事件发生时, HTML 提供了至少 5 种以上方法来描述鼠标的坐标。以下三种最为重要:
            1. pageX/Y. 描述鼠标在 html 中的位置, CSS 像素描述
            2. clientX/Y. 描述鼠标在 viewport 中的位置, CSS 像素描述
            3. screenX/Y. 描述鼠标在 screen 中的位置, 用设备像素描述
(经本人测试, clientX/Y pageX/Y 的值完全一样,返回的是在 window 中的位置。经查证,他们的存在完全是由于浏览器各自为战的原因, pageX/Y 来自于 NetScape. 作者, WTF!

Media queries

some words about media queries. The idea is very simple: you can define special CSS rules that are executed only if the width of the page is larger than, equal to, or smaller than a certain size.
Media queries 是非常重要的特性,主要目的是探测目标设备的信息,针对不同的环境显示不同的 CSS. 详情请见 http://www.w3.org/TR/css3-mediaqueries/#values
media features 里面有两个属性, width/height device-width/device-height. 例如:
div.sidebar {
            width: 300px;
}

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

}
这段 CSS 定义了 sidebar 的宽度为 300px, 然而在宽度不超过 400 的页面内, sidebar 的宽度就应当为 100px.
这里需要注意的是, media query 里面的 width/height, 指的是 viewport width/height ,也就是 documentElement .clientWidth/Height  ( 个人测试,应该是 window 的,也就是说,等同于 window.innerWidth and window.innerHeight ) CSS 像素衡量。
Device-width/height, 指的就是 screen.width/height 使用设备像素衡量。
见下图:


Conclusion


That concludes our foray into the desktop browsers’ behaviour. The second part of this series ports these concepts to mobile and highlights some important differences with the desktop.

总结
本片描述了桌面浏览器的一些尺度概念,第二章我们将针对于手机浏览器,讲述这些概念重要的区别。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值