Viewport 不权威指南

什么是 Viewport,为什么需要 Viewport

Viewport:视口,视觉窗口,显示区域。

在显示面积上手机屏幕相对桌面显示器要小很多,在几年前(现在也如此)大部分网站都是为桌面显示器浏览而设计,很少考虑到适应手机屏幕,所以如果用手机浏览大多网站时会出现问题,比如常见固定宽度的网页会出现横向竖向滑动条,当然这不算什么大问题;但如果是浏览流动布局的网页那情况会非常糟糕,设想一个宽度为 30% 的侧边栏对于 320px 手机屏幕而言也就 96px,只能容纳八个 12px 的汉字,可阅读性非常差。

为了让手机也能获得良好的网页浏览体验,Apple 找到了一个办法:在移动版的 SafariiOS平台)中定义了 viewport meta 标签,它的作用就是创建一个虚拟的窗口(viewport),而且这个虚拟窗口的分辨率接近于桌面显示器,Apple 将其定位为 980px

以一代 iPhone 下的 Safari 来说就是:
iPhone 320px 物理屏幕上——视觉窗口(visual viewport),创建出了一个 980px 的虚拟窗口——布局窗口(layout viewport),在视觉窗口(visual viewport)中我们可以拖动横向竖向滑动条或者放大缩小网页,来达到最佳的浏览效果(类似桌面浏览器);而布局窗口(layout viewport)用来配合 CSS 渲染布局,例如当我们设置一个容器的宽度为 100% 时,这个容器的实际值为 980px 而不是 320px。如此一来大部分网页就能以缩放的形式正常的显示在手机屏幕上了。


如何设置 Viewport

有了 layout viewport似乎解决手机浏览网页的难题,但如果遇到专门为手机优化的网页就又有新的问题:


是的,因为 iPhone layout viewport默认为 980px,导致专为其优化的 320px 宽的页面只能以缩放的方式显示,这时就需要对 viewport 进行设置:

<head>

...

<metaname="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no"/>

...

</head>

这个是最常见的一条 viewport meta 代码,将 viewport 定义为:宽度为设备宽度,初始缩放比例为 1 倍,禁止用户缩放。设置好后我们的页面就显示完美了:

  1. <meta name="viewport"

  2.        content=" 

  3.            height = [pixel_value | device-height] , 

  4.            width = [pixel_value | device-width ] , 

  5.            initial-scale = float_value , 

  6.            minimum-scale = float_value , 

  7.            maximum-scale = float_value , 

  8.            user-scalable = [yes | no] , 

  9.            target-densitydpi = [dpi_value | device-dpi | 

  10.                                 high-dpi | medium-dpi | low-dpi] 

  11.            " />

 


viewport 全部属性&值如下:

width: viewport宽度
height: viewport
高度
initial-scale:
初始缩放比例
maximum-scale:
最大缩放比例
minimum-scale:
最小缩放比例
user-scalable:
是否允许用户缩放

例:

width=960 device-width
height=1000
device-height
initial-scale=0.5
maximum-scale=2
minimum-scale=1
user-scalable=1
0 (yes no)

layout viewport的默认值

Apple实现viewport后,其他浏览器也加入了对viewport meta的支持,但彼此间还是有些差异,差异最大的是layout viewport的表现:

Safari iPhone:980px
Opera: 850px
Android WebKit: 800px
IE: 974px

最后关注下 width=device-width

其实这个属性&值很有意思,字面意应该是 viewport 宽度等于设备宽度,但在实际中不同的浏览器都给出了个定值:320px;这个值还是源于 Apple,因为早期 iPhone 的分辨率为 320px × 480px,大量为 iPhone 量身定制的网站都设置了width=device-width,并且按照宽度 320px 来设计制作,所以其他浏览器加入 viewport 支持时为了兼容性也将 device-width 定义为了 320px

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

最初执行viewport meta加入如下

<metaname="viewport" content="width=device-width,initial-scale=1.0">

编译过程会转化成如下的语意,

@viewport {

width: device-width;

initial-scale:1.0

}

基本说明

width=device-width

先提一下几个注意的地方,首先在viewport里面的width通常会看到设定为device-width ,主要是为了让整个页面宽度与手机可视宽度相同,如此就可以简单相容于不同机型萤幕大小,如果这边width没有设定的话,就会依照html css给予的width当作预设值。

因为解析度不同,device-width有时候不一定是view width ,所以在类似iphone 4高解析度机器上,device-width=320,可是实际解析度为480,这时候就需要利用javascript针对UA下去做动态调整。user-scalable 从属性名称来看就是允许开启、关闭的设定,使用者能否放大、缩小页面,如果页面不允许手机使用者缩放,就直接设定为0,或者no,反之要启动缩放功能,给予1或者是yes接下来将说明几种常用的方式,以及测试验证提供给大家参考。基本宽度(并不是指html body width),

注解

除此之外不同移动浏览器厂商也有不同的解决方案,例如 UCweb 就是使用中间件技术。
不同的浏览器厂商对于 layout viewport的大小定义不同,详见”layout viewport的默认值

参考文章:

http://dev.w3.org/csswg/css-device-adapt/
http://www.quirksmode.org/mobile/viewports2.html
https://developer.mozilla.org/en/Mobile/Viewport_meta_tag
http://blogs.msdn.com/b/iemobile/archive/2010/11/22/the-ie-mobile-viewport-on-windows-phone-7.aspx

Media queries &Viewport

  解决问题的关键就是Media queries和Viewports。下面的内容是关于如何最好的使用Media queries和Viewports的。但是我并不会深入的讲怎样增强响应的细节,如果感兴趣,可以查看这篇博文的最后一部分:“参考文章”。

  ● @media queries

  作为一个网页设计师或前端开发者,我们希望我们的网页总能很容易的自适应不同的设备和屏幕尺寸,不管我们用户使用的是21″台式显示器,13″笔记本电脑,10″的iPad或者更小的智能手机。响应式网页设计使用@media queries根据浏览器的宽度和CSS来改变页面的布局。我们可以这样使用的CSS:

1.     /* Default wide-screen styles */

2.     @media all and (max-width: 1024px) {

3.     /* styles for narrow desktop browsers andiPad landscape */

4.     }

5.     @media all and (max-width: 768px) {

6.     /* styles for narrower desktop browsersand iPad portrait */

7.     }

8.     @media all and (max-width: 480px) {

9.     /* styles for iPhone/Android landscape(and really narrow browser windows) */

10.   }

11.   @media all and (max-width: 320px) {

12.   /* styles for iPhone/Android portrait */

13.   }

14.   @media all and (max-width: 240px) {

15.   /* styles for smaller devices */

16.   }

  是的,我们可以设置更小的width,或者中间尺寸。我待会再讨论。CSS media queries是非常强大和复杂的,在这里不想过多的讨论,因为上面的代码已经足够应付响应式Web设计了。如果你想要知道更多关于Media Queries的细节,请阅读参考文献里的相关文章。

  ● viewports

  现在,当我们调整我们浏览器的大小时,上面的代码已经可以非常不错的完成工作了。但这并不能满足移动端的浏览器。原因是移动端浏览器(iPhone/Safari, Android/Chrome和Fennec)会默认页面是为宽屏幕设计的,所以将它缩小整个页面来适应小屏幕。这就表明了上面的代码完全不足于适应移动端的浏览器,因为设备无法识别正确的宽度。解决方法:在文档的头部使用苹果提供的viewport meta标签,并结合@media queries:

1.     <meta name="viewport"content="...">

  以上的代码中,content为空,因为我觉得有必要详细讲一下,而不是直接给出来,这样我们就能更清楚的记住,并且知道content里应该填些什么,并且为什么这样填

  ● width=device-width

  我们看见很多网站都建议把content属性的值设置为width=device-width。这相当于告诉浏览器将页面宽度假设为设备宽度。不幸的是,只有当设备是纵向时假设才是正确的。当我们把设备旋转成横向时,device-width还是和纵向的一样(比如,320px),这意味着,即使我们把页面设计成适应了480px横向设备,它还是会返回320px的效果。

  曾经尝试在media query里使用orientation来解决这个问题,但是orientation不会真正的告诉我们实际的设备宽度,因为它只告诉我们设备的宽度是大于还是小于设备的高度。正如有人指出,由于大部分网页往往垂直滚动,所以这是无关紧要的。

  如果我们的页面在纵向和横向设备中样式相同,那么我们就可以用width=device-width就足够了,需要注意的是这个是唯一告诉android设备使用设备宽度的方法。

  ● initial-scale=1.0,maximum-scale=1.0

  initial-scale=1设置告诉浏览器初始化页面时不要对页面进行缩放。解决了没有使用viewport时出现的页面缩放问题。但还是有 bug,当我们把移动端设备从纵向转成横向时,你就会发现这个问题了。这是因为initial-scale只在页面完全加载后有作用。在我们把移动设备从纵向转成横向的过程中,浏览器就会认为页面不变,但scales会设置为1.5,为了使320px的页面适应480px。但是,因为我们在@media queries中设置了480px这个宽度,那么页面CSS规则也会是适应480px的。结果就是,页面CSS规则是适应480px的,另外scale还是1.5。这个结果并不可怕,但是不可取。

  为解决这个bug,我们可以添加maximum-scale=1这个设置。它的作用是阻止页面在旋转时放大,但它同时带来了更严重的问题:也阻止了用户手动放大或缩小页面。同样user-scalable=no设置也会让用户不能缩放页面。所以一般情况下,不要使用以上俩个设置。

  是不是无法解决这个bug了?首先这个bug最多只是在显示层面,带来的后果一点不严重,因为即使页面自动缩放了,它还是成比例的。

  ● width=<actual width>

  有些人建议在viewport里使用特定的width,并且也按这个width设计页面。如果你可以为每个种类的device编写页面的话,这个设置是可行的,但需要我们明白的是它不是响应式设计。打印时,使用固定宽度布局是必要的,但我们网页应该适应用户的各种样式的设备。总之,不要这样使用。

  ● @media all and (device-width:480)

  这是个media query而不是viewport标签里的选项, 我在很多地方看到过这样的代码,但我并不认为这是好的做法。为什么?根据CSS3对media queries的描述,device-width在media queries里表示的是输出设备表面渲染的宽度。对于continuous media来说,device-width就是屏幕的宽度;对于paged media来说,device-width就是页面尺寸的宽度。以continuous media为例,device-width就是设备屏幕的宽度。除非浏览器最大化,它始终大于viewport的width。

  测试表明,大多数桌面浏览器把device-width和width当作同义词。而移动端浏览器对此会有点混淆。至于viewport标签里,device-width只在纵向时等于设备的width。例如,一个320*480的设备,device-width总是320px,不论方向。然而对于CSS media queries,device-width是基于其目前方向上屏幕的width。

  如果你一定要这样使用,请和orientation一起使用。但绝对不要使用max-device-width和min-device-width,因为用max-width和min-width替换会比较好。同样需要注意的是,新型号设备的宽度可能会改变。

  ● 中间尺寸

  上面我提到过,我们可以为任意数量的width来设计页面。最重要的是在不同width的浏览器中测试他们,通过调整window浏览器的大小来测试是最简单的方法。随着设计页面的width越来越小,我们可以去掉(Display:none;)一些不重要的内容,比如 footer,sidebars,menu等,为主要内容留足够大的空间。我们的网站也许需要一个可以在所有width屏幕上运行良好的布局,也许只需要满足两到三个布局。这是非常容易设计和测试的,所以没有理由不做。

  ● 推荐设置

   最后,是我推荐的做法:

  1. 使用viewport标签

  2. 使用media queries来选择最适合页面尺寸的CSS

  3. 在viewport标签里,使用width=device-width,initial-scale=1或者单独使用width=device-width

  4. 不要使用maximum-scale=1和user-scalable=no

  5. 不要使用width=<specific width>

 6. 不要使用@media all and (*-device-width: xxx)

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章