这一页咱们将讨论移动浏览器。若是您对移动设备彻底陌生,我建议您首先阅读第一部分关于桌面浏览器的内容,以便在熟悉的环境中作好准备。css
移动浏览器和桌面浏览器比较,最明显的差别是屏幕大小。移动浏览器若是要显示桌面优化网页,要么字体会缩小到没法阅读,要么只能显示网页的一部分。html
移动设备屏幕要比桌面小得多,最大的宽度大概是400px,有些还要更小一些。(有些手机声称更大一些的尺寸,可是他们在说谎——或至少给了咱们无用的信息)web
做为中间层的平板电脑例如iPad等,弥补了台式电脑和手机支架的差距(让差距显得不突兀吧),可是这么有改变根本性问题。网站依然须要在手机设备上运行,咱们须要让其在小屏幕上良好显示。浏览器
最重要的问题集中在CSS上,特别是viewport(视口)的大小。若是在移动设备上直接使用桌面网页,CSS将会出现严重错误。app
让咱们回到以前的一个例子,侧边栏宽度width:10%。若是移动浏览器同桌面浏览器同样运行,侧边栏的宽度大概是40px,这是在太窄了。流布局被严重压缩。布局
一个解决办法就是针对移动浏览器从新构建一个特殊的网站。抛开是否应该这么作来解决根本问题,实际上能有多少网站提供专门针对于移动设备的网站。测试
移动浏览器供应商想要给用户提供最好的体验,须要作的就是“尽量跟桌面网页相似”。若是想要作到这样,就必须耍些花招。字体
对于你的CSS布局来讲,目前的viewport太窄了。明显的解决办法就是让viewport更宽些。为了这个目的,须要将viewport分为两个种类:the visual viewport 和the layout viewport。优化
George Cummins在Stack Overflow上对基本概念作了最好的解释:网站
Imagine the layout viewport as being a large image which does not change size or shape. Now image you have a smaller frame through which you look at the large image. The small frame is surrounded by opaque material which obscures your view of all but a portion of the large image. The portion of the large image that you can see through the frame is the visual viewport. You can back away from the large image while holding your frame (zoom out) to see the entire image at once, or you can move closer (zoom in) to see only a portion. You can also change the orientation of the frame, but the size and shape of the large image (layout viewport) never changes.
将布局视图端口想象成一个不改变大小或形状的大图像。再想象你有一个相框,能够经过相框看到那幅大图像。相框外周都是不透明的,只有经过中间部分能够看见图像。能够透过相框看到的那部分就是the visual viewport(可视窗口)。你能够拿着相框后退距离图像远一点,就能够看到整个图像。也能够距离更近一些,只看图像的一部分。图像的大小和形状(the layout viewport)并不会发生任何改变。
(能够去看原文,其实英文挺直观的。而且还有做者引用的其余解释)
the visual viewport(可视窗口)是当前显示在屏幕上的页面的一部分。用户能够经过滚动操做移动去查看页面的其余部分,也能够缩放改变the visual viewport (可视窗口)的大小。
然而,CSS布局,特别是百分比宽度,是根据layout viewpor(布局视图)t计算的,它比visual viewport宽得多。
<html>元素最初会采用layout viewport的宽度,css将会被解释为当前屏幕比手机屏幕宽得多。这能够确保你的站点布局和桌面布局一致。
layout viewport到底多宽呢?每一个浏览器都不同。Safari Iphone使用980px,Opera使用850px,Android Webkit是800px,IE是974px。
有一些浏览有一些特殊的行为:
显而易见,两个viewport都是CSS像素单位。可是当visual viewport随着缩放改变时(若是放大,屏幕显示的CSS像素就会减小),layout viewport始终保持不变。
为了理解layout viewport 的尺寸先来看一下当页面彻底缩小的时候发生了什么。许多移动浏览器最初以彻底缩小模式显示任何页面。
重点是:浏览器选择了layout viewport的大小以至于它以彻底缩小的模式覆盖屏幕(所以同visual viewport 一致)
所以,layout viewport的宽高等于以最大缩小模式显示在屏幕的内容的宽高。即便用户放大,也不会发生改变。
layout viewport老是保持不变。当你旋转你的手机,visual viewport发生改变,可是浏览器适配器会适当放大使得layout viewport和visual viewport同样宽。
这对layout viewport的高度有影响,layout viewport的高度大大低于竖屏模式。可是web开发人员并不关心高度,只关心宽
如今有了两个viewport尺寸须要测量。很是幸运的是,浏览器大战给了咱们两对属性。
document.documentElement.clientWidth/Height表示layout viewport的大小。
方向与高度有关,但与宽度无关。
至于visual vireport,能够经过window.innerWidth/Height得到。很显然,当用户进行缩放时,这个数值会发生变化,使更多或者更少的CSS像素适合屏幕。
不幸的是,这是一个没有彻底兼容的领域。许多浏览器仍然须要添加对测量visual viewport的支持。可是,没有浏览器将此测量存储在任何其余属性对中,我猜想window.innerWidth/Height是一个标准,尽管支持力度不够。
window.innerWidth/Height Meaning Visual viewport dimensions Measured in CSS pixels Full support iPhone, Symbian, BlackBerry Problems Opera and Firefox return the screen width in device pixels. Android, Bolt, MicroB, and NetFront return the layout viewport dimensions in CSS pixels. Not supported IE, but it gives the visual viewport dimension in document. documentElement. offsetWidth/Height. Samsung WebKit reports either the dimensions of the layout viewport or of the <html>, depending on whether a <meta viewport> tag has been applied to the page or not. Gibberish Iris, Skyfire, Obigo
就像在桌面,screen.width/height给出屏幕的大小,使用设备像素。如同桌面同样,做为web开发者,不须要知道这个信息。您感兴趣的不是屏幕的物理大小,而是它当前适合多少CSS像素。
screen.width and screen.height Meaning Screen size Measured in Device pixels Full support Opera Mini, Android, Symbian, Iris, Firefox, MicroB, IE, BlackBerry Problems Opera Mobile on Windows Mobile only gives the landscape size. Opera Mobile on S60 gets it right. Samsung WebKit reports either the dimensions of the layout viewport or of the <html>, depending on whether a <meta viewport> tag has been applied to the page or not. iPhone and Obigo only give portrait sizes. NetFront only gives landscape sizes. Gibberish Bolt, Skyfire
不可能直接读取缩放级别,可是分割screen.width和window.innerWidth获得。问题是若是这两个属性对都获得彻底的支持才能够。
幸运的是缩放级别并不重要。你须要知道的是,屏幕适合多少CSS像素。能够从window.innerWIdth获取I信息——若是它被正确支持。
若是须要知道相对于layout viewport当前页面的位置。也就是滚动偏移量,跟桌面同样,存在window.pageX/YOffset中。
window.pageX/YOffset Meaning Scrolling offset; which is the same as the visual viewport’s offset relative to the layout viewport. Measured in CSS pixels Full support iPhone, Android, Symbian, Iris, MicroB, Skyfire, Obigo. Problems Opera, Bolt, Firefox, and NetFront always return 0. Samsung WebKit reports correct values only if a <meta viewport> is applied to the page. Not supported IE, BlackBerry. IE stores the values in document. documentElement. scrollLeft / Top
和桌面同样,document.documentelement.offsetWidth/Height给出了以CSS像素为单位的<html>元素的总大小。
document. documentElement. offsetWidth / Height Meaning Total size of the <html> element. Measured in CSS pixels Full support Opera, iPhone, Android, Symbian, Samsung, Iris, Bolt, Firefox, MicroB, Skyfire, BlackBerry, Obigo. Problems NetFront’s values are only correct at 100% zoom. IE uses this propery pair to store the dimensions of the visual viewport. In IE, see document. body. clientWidth/Height for the correct values.
媒体查询和桌面查询相同。width/height使用layout viewport做为参考,使用CSS像素做为单位。device-width/height采用设备屏幕,设备像素做为单位。
换句话说,width/height反映的是document.documentElement.clientWidth/Height的值。device-width/height反映的screen.width/height的值。(它们实际上在全部浏览器中都这样作,即便反映的值可能不正确。)
因此到底哪一个数值对于开发是有用的呢。其实我也不知道
我开始认为device-width是最重要的,由于它给的是设备的信息,咱们可能会须要这个信息。例如,能够改变布局的宽度以适应设备的宽度。不过,您也可使用<meta viewport>;使用device-width的媒体查询并非绝对必要的。
那么,width究竟是不是更重要的媒体查询呢?也许;它提供了一些线索,关于浏览器供应商认为何是该设备上一个网站的良好宽度。但这是至关模糊的,宽度媒体查询实际上没有提供任何其余信息。
因此我犹豫不决。就目前而言,我认为媒体查询对于判断您是在台式机、平板电脑仍是移动设备上很是重要,但对于区分不一样的平板电脑或移动设备并非很是有用。
事件坐标或多或少与桌面坐标相同。不幸的是,在12个通过测试的浏览器中,只有两个,即Symbian WebKit和Iris,彻底正确地实现了这三个功能。全部其余浏览器都有或多或少的严重问题。
pageX/Y依然是相对于页面坐标,使用的是CSS像素。这是目前三对属性中最有用的信息,跟桌面同样。
clientX/Y是相对于visual viewport的坐标,使用的是CSS像素单位。这是有道理的,尽管我不彻底肯定它有什么好处。
screenX/Y是相对于屏幕的,使用的是设备像素单位。固然,固然,这是clientX/Y使用的相同参照物,设备像素是无用的。因此咱们不须要担忧screenX/Y,它和在桌面同样毫无用处。
最后,来讨论<meta name="viewport' content="width=320">;最开始是苹果手机的扩展,如今已经在其余浏览器普遍使用。它的意思是调整layout viewport。为了理解这个操做的必要性,先回退一步。
若是你构建了一个简单的页面,而且没有给任何元素宽度。他们会拉伸到l填充layout viewport。大多数浏览器多会缩小使得可以在页面上显示整个layout viewport,效果以下图
全部用户都会当即放大,这是可行的,但大多数浏览器保持元素的宽度不变,这使得文本难以阅读。
(Android WebKit是一个显著的例外,它实际上减小了包含文本的元素的大小,使它们适合显示在屏幕上。这很是棒,我以为全部其余浏览器都应该复制这种行为。稍后我会详细记录下来。)
如今,你设置<html>的宽度width:320px。如今,<html>元素缩小了,全部其余元素也缩小了,它们如今占用了320px的100%。这在用户放大时有效,但在最初,当用户面对一个放大后的页面,整个页面大包含大部分空白。
为了解决这个问题,苹果发明了meta viewport标签。当您设置<meta name="viewport" content="width=320">时,您将布局viewport的宽度设置为320px。如今页面的初始状态也是正确的。
你能够设置layout viewport为任何值,能够是device-width。device-width采用screen.width做为参考,而且能够响应调整layout viewport。
不过这里有个陷阱。有时候screen.width没有多大意义,觉得像素值过高了。好比,Nexus One的正式宽度为480px,可是谷歌的工程师认为,当使用device-width时,将layout viewport的宽度设置为480px实在是太大了。他们缩小它至三分之二。因此device-width变为320px,就像在iPhone上同样。
若是真的像传言的那样,新款iPhone的像素会更大(这并不必定意味着屏幕更大!)也许最终设备的宽度就是320像素。
结论其实和桌面浏览器差很少,可是因为移动浏览器对于许多属性对没有彻底支持,移动设备有不少种,使得在移动设备上实现良好的布局比较不容易。
screen.width/height
,设备的屏幕尺寸。
window.innerWidth/Height
,包含滚动条尺寸的浏览器完整尺寸。
document.documentElement.clientWidth/Height
,viewport 的尺寸。
document.documentElement.offsetWidth/Height
,<html>
的尺寸。
window.pageX/YOffset
,页面的移位。
window.pageX/Y
,从<html>
原点到事件触发点距离。
window.clientX/Y
,从 viewport 原点(浏览器窗口)到事件触发点的距离。
window.screenX/Y
,从用户显示器窗口原点到事件触发点的距离。