目录

导读

视口 viewport

viewport 的缩放与平移

viewport的DOM API

移动端的 viewport

窄屏设备的问题

放大的viewport

可定制的viewport

Viewport Meta Tag 的使用

viewport 属性表

viewport 属性举例

width

initial-scale

maximum-scale / minimum-scale

user-scalable

viewport-fit

width和initial-scale的取值冲突

参考资料

移动端视口分类

布局视口

视觉视口

理想视口

视口单位

总结:

viewport 属性表

布局视口

视觉视口

理想视口

视口单位


导读

viewport是移动端跨屏适配的基石,吃透这一概念,任何复杂多变的适配需求,都可以手到擒来。

移动端开发中,有一个躲避不掉的HTML meta 声明 <meta name="viewport"> 。通常被用来做跨屏适配,常见声明如下:

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

视口 viewport

viewport 中文译作“视口”。

维基百科①的解释为:

在计算机图形学理论中,当将一些对象渲染到图像时,存在两个类似区域的相关概念。(视口和窗口)

视口是一个以特定于渲染设备的坐标表示的区域(通常为矩形)。视口范围内的图像会以剪切的形式,投影到到世界坐标窗口中,完成图像的可视化展示。

在 Web 浏览器中,视口是整个文档的可见部分。如果文档大于视口,则用户可以通过滚动来移动视口。

白话描述一下:

  • 计算机把图像渲染到显示器的过程中,会先把图像画在一个逻辑层的画布上,然后从这个画布中框选一部分,将其投影到显示层。

  • 这个选框就是视口,显示层就是窗口。

  • 在浏览器中,我们可以通过滚动条来移动视口以看到更多网页内容。

更形象的视口解释:

如这张某宝的商品放大效果图,左半图为计算机看到的逻辑层画布,上方半透明选框为视口(viewport),右半图为浏览器窗口,即用户看到的部分。

视口(viewport)可以理解为浏览器显示页面内容的屏幕区域。

viewport 的缩放与平移

浏览器中,对页面进行放大的时候,视口的大小如何变化?视口会变小

因为,浏览器窗口中所浏览图像的放大,是依赖于视口的缩小来实现的。

如果不好理解,可以参照下图动画来感受一下。(上面蓝框表示底层画布、红框表示视口,下面表示用户在浏览器窗口中看到的页面)

同理,当浏览器窗口比较小,而我们想要看到页面下面的内容时,我们需要向下滚动滚动条,浏览器在实现这个的过程中所依赖的,便是视口的下移。

viewport的DOM API

关于上面的解释,我们来验证一下。

目前已被标准实现的 API 中,有两个 DOM 属性可以用来获取视口的大小。

以宽度为例:

  • document.documentElement.clientWidth(不含滚动条)

  • window.innerWidth(含滚动条)

如图,PC Chrome 中试验,确实如之前解释,放大到 200%后,视口大小缩小了一倍。(小数点默认四舍五入了)

注意:

  • 在移动端的浏览器中,对页面手动捏合做放大时,document.documentElement.clientWidth 不会有任何变化。window.innerWidth在 iOS 中会等倍数缩小,在 Android 的不同浏览器中表现差异较大。

  • 如果有需要获取初始视口宽度的需求,建议使用document.documentElement.clientWidth ②。

移动端的 viewport

看起来 viewport 并没有太多复杂之处,但是 2010 年左右,移动端时代来了。

注:移动设备的显著特点是屏幕小,考虑到国际社会通行的水平阅读习惯,下文我们只讨论宽度。

窄屏设备的问题

移动互联网的早期,屏幕设备的物理像素点宽度多数在 320、480、640 等。而互联网世界的绝大多数站点又是针对 PC 设计的,其文档宽度普遍在 800px 以上。

如果浏览器和针对 PC 制作的网页都不做任何处理,那么在窄屏设备上加载网页,我们看到的效果便是默认显示网页的左上角部分,然后通过水平和竖直方向的滚动来浏览网页的其他部分。

首先,我们看不到网页全局的样子。其次,我们需要通过不断的滚动来保证阅读内容的连续性。这样的体验,有点过于糟糕了。

放大的viewport

为了优化“最初为 PC 设计的网页”在移动设备的浏览体验,移动浏览器厂商们想了一个方案,那就是增大页面载入时初始视口的宽度,比如 Android 和 iOS 都比较常见的 980px。

在手机端,html的大小都是980px,为什么?

这主要是历史原因导致的,因为在移动设备刚流行的时候,网站大多都是pc端的,pc端的页面宽度一般都比较大, 移动设备的宽度比较小,如果pc端页面直接在移动端显示的话,页面就会错乱。 为了解决这个问题,移动端html的大小直接就定成了980px。

在pc端,html的大小默认是继承了浏览器的宽度,即浏览器多宽,html的大小就是多宽, 但是在移动端,多出来了一个视口的概念,视口说白了就是介于浏览器与html之间的一个东西, 视口的宽度默认定死了980px,因此html的宽度默认就是980px,视口的特点是能够根据设备的宽度进行缩放。 将视口宽度和手机屏幕一样宽,网页基于视口进行布局,网页的布局宽度就和手机屏幕一致了。

随着智能手机的出现, 980px 这个布局视口宽度出现了,也就是说在手机上浏览器上,默认的布局视口宽度是 980px,默认开发者在 980px 的页面上使用代码进行页面绘制。但是这就导致了一个情况:980px的宽度大于大部分手机屏幕的宽度,为了将页面显示完全,只能对原来的页面进行缩放,如果不进行缩放,那么就需要左右拖动来浏览。

按照 viewport 的缩放,如此的设计,会把逻辑层画布中 980px 的图像投影显示到 414px 的屏幕上,看到的效果便是一个挤在一起看不清楚细节的缩小版页面。

如上图,页面载入时,我们可以一眼看到整个页面的样子了。

不过,该方案依然会有很多问题:

  • 对缩小版页面内细节内容的浏览,依然要依靠放大和滚动,体验不好;

  • 如果 为 PC 设计的 网页的 CSS 宽度描述大于 980px,那么在移动端展示时,初始页面依然会有滚动条;

  • 限制了依据视口宽度做媒体查询(Media queries)机制的有效性,因为视口宽度初始为 980px,浏览器不会以 640px、480px 或更低分辨率来启动对应的媒体查询。

注:媒体查询请注意区分"@media screen and (xxx){}"中的min-device-width 和min-width。前者依据的是设备逻辑宽度(screen.width),后者依据的是视口宽度(document.documentElement.clientWidth)。

可定制的viewport

浏览器厂商:“既然我说的数,你们都各种意见,那好吧,你们自己定吧。”

为了解决上述固定 viewport 宽度的方案所引发的各种问题,Apple 在 iOS Safari 中首先引入了Viewport Meta Tag ,允许 Web 开发人员定制视口的大小和缩放比例,后续其他的移动浏览器厂商也都支持了此标记(约 2010 年)。

虽然至今 W3C 都未将此标记列入标准,但是,这并不影响我们使用它。

如前面 viewport 概念的解释,css 中同样 px 大小的宽高描述,在不同大小的视口状态下,用户在浏览器窗口中看到的页面大小的效果是不同的。有了定制视口的能力,我们可以轻松的做到以下几点③:

  • 针对较宽(比如 2000px) PC 设计的页面,我们可以设置 viewport 宽度为 2000,以使得移动设备中初始渲染的页面效果刚好不出现滚动条;

  • 利用了媒体查询做了移动端适配的页面,我们可以设置 viewport 宽度为 device-width,以保证媒体查询技术的有效性,同时还能保证横竖屏切换时,px 单位做大小描述的页面元素的视觉大小一致性;

  • 需要充分利用屏幕物理像素点做 1 像素极细边线的页面,我们可以设置 viewport 缩放倍数为 1/dpr,以使得 css 中的 1px 刚好对应设备物理像素中的 1 个点;

  • 需要根据屏幕宽度弹性伸缩的页面,我们可以结合各种相对长度单位(%/rem/vw 等),设置合适的 viewport,以实现布局伸缩和内容大小固定的完美统一。

Viewport Meta Tag 的使用

我们可以在 Apple 或者 MDN 的开发者文档中查看Viewport Meta Tag 的具体用法说明。

需要注意的一点是,目前只有移动端的浏览器支持这一声明方式,PC上是无效的。

在那些难以界定移动还是 PC 的设备中,这种区分可能会存在一些问题,有一些 Web 组织,如 WICG(Web Platform Incubator Community Group)目前在尝试推动解决这个问题。这里不做更多讨论④。

viewport 属性表

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

通过设置<meta name="viewport">,提供有关视口初始大小的信息,供移动设备使用。属性值为:

属性 属性值 描述
width 数值 / device-width 视口宽度(px)
height 数值 / device-height 视口高度(px)
initial-scale 0.0 ~ 10.0 设备宽度device-width与视口宽度之间的初始缩放比例
maximum-scale 0.0 ~ 10.0 缩放最大值,必须大于等于minimum-scale的值
minimum-scale 0.0 ~ 10.0 缩放最小值必须大于等于maximum-scale的值
user-scalable yes/no 是否允许用户缩放,默认yes,为no时用户不能缩放网页,也可以用1或者0
viewport-fit contain/cover 视口填充屏幕的方式。默认值为contain

viewport 属性举例

在本小节,我们以iPhone6s手机+Safari浏览器举例,对上述属性做详细说明。

如未做特殊说明,均只讨论竖屏模式。

设备参数说明:

  • 操作系统:iOS 12.3.1

  • 屏幕物理分辨率:750*1334

  • 屏幕逻辑分辨率:375*667 (screen.width/height)

  • 设备像素比(dpr):2 (window.devicePixelRatio)

  • 浏览器默认视口宽度:980 (document.documentElement.clientWidth)

width

<meta name="viewport" content="width=1000" />
  • document.documentElement.clientWidth 输出 1000

  • div 宽度 1000px 时,横向刚好铺满屏幕,超过出现横向滚动条

<meta name="viewport" content="width=device-width" />
  • 效果等同于 width=375

  • document.documentElement.clientWidth 输出 375

  • div 宽度 375px 时,横向刚好铺满屏幕,超过出现横向滚动条

initial-scale

<meta name="viewport" content="initial-scale=1" />
  • 效果等同于 width=device-width

<meta name="viewport" content="initial-scale=2" />
  • document.documentElement.clientWidth 输出 188 (375/2)

  • div 宽度 188px 时,横向刚好铺满屏幕,超过出现横向滚动条

  • scale 倍数越小,视口越大

此处插入一个问题:

iPhone6S 的 safari 中,不做任何 viewport 设置情况下,默认 initial-scale 的值为多少?

maximum-scale / minimum-scale

<metaname="viewport"content="initial-scale=2,minimum-scale=1,maximum-scale=3"
/>

预期页面初始 1 倍,最小可以缩小到 0.5 倍,最大放大到 2 倍。但是实际表现并非如此:

  • 小米 9 的系统浏览器表现符合预期;

  • iOS 中 所有 Web 容器均无法缩放 到 比 initial-scale 更小的倍数,即使 minimum-scale 声明了一个更小且合理的取值;

  • iOS 微信(7.0.5)的 webview 中,遵守了最大 3 倍声明,但 Safari 可以放大到比 3 倍更高的倍数。

iOS10 开始,为了提高网页在 Safari 中的可访问性,Safari 限制了最小倍数(minimum-scale)并忽略了 最大倍数(maximum-scale) 的声明。

Android 和 iOS 在不同版本不同厂商的 Web 容器中,此属性的表现可能存在较大程度的不一致,请谨慎使用。

user-scalable

<meta name="viewport" content="initial-scale=1,user-scalable=no" />
  • Safari 中依然无法缩小可以放大,微信中无法缩放;

  • Android 未做测试。

同 4.2.3,此属性同样存在兼容问题,请谨慎使用。

viewport-fit

<meta name="viewport" content="initial-scale=1,viewport-fit=cover" />

此属性为 2017 年 Apple 为了解决 iPhoneX 手机的刘海屏问题,增加的新属性。

相关技术细节和兼容性本文不做更多讨论,详情可以阅读文末参考链接⑤:

width和initial-scale的取值冲突

同理,width=device-width 和 initial-scale=1 也是等效的。(device-width 对应数值在竖屏模式下为 375,横屏模式下为 667)

既然,两个属性的作用都是设置初始视口大小,那同时设置且存在冲突的情况下,浏览器会怎么处理呢?优先级规则是按书写顺序还是宽度大小?比如下面这样:

<meta name="viewport" content="width=device-width,initial-scale=2" />

Safari 的运行结果是“按宽度大小”取更大的,但是这样的对比研究并没有任何意义。因为并没有相应的规范约束这件事情,浏览器的兼容表现肯定是千差万别。

作为开发者,我们要做的,就是避免冲突。要么只写一个,要么两个都计算正确。从语义表达角度看,建议只设置"width"。从计算方便角度看,可以只设置 initial-scale。

以上参照:不生效 设置了viewport_彻底搞懂移动Web开发中的viewport与跨屏适配_苏爽爽的博客-CSDN博客

参考资料

[1].https://en.wikipedia.org/wiki/Viewport

[2].Viewport concepts - CSS: Cascading Style Sheets | MDN

[3].Configuring the Viewport

[4].GitHub - WICG/visual-viewport: A proposal to add explicit APIs to the Web for querying and setting the visual viewport

[5].@viewport - CSS: Cascading Style Sheets | MDN

移动端视口分类

移动端涉及布局视口(Layout Viewport)、视觉视口(Visual ViewPort)和理想视口(Ideal ViewPort)。

布局视口

布局视口是看不见的,浏览器厂商设置的一个固定值,一般是768px~1024px之间。这里我们可以认为它是一个画板用于展示网页。

布局视口相对于用户来说并没有什么影响,布局视口对于开发者来说实际意义重大,它规定开发者需要以这么一个宽度来进行开发,只有将布局视口按照理想视口的宽度来开发,显示出来的页面兼容性才更好、视觉效果和体验也更好。

一般移动设备的浏览器都默认设置了一个布局视口,用于解决早期的PC端页面在手机上显示的问题。iOS, Android基本都将这个视口分辨率设置为 980px,所以PC上的网页大多都能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页。

视觉视口

视觉视口是浏览器可视区域的大小,即用户看到的网页的区域(理解为网页的可视区域)。在 PC 端,浏览器窗口可以随意改变大小,我们可以直观的看到。而在移动端端,大部分手机、平板的浏览器是不支持改变浏览器宽高的,所以其视觉视口就是其屏幕大小。

理想视口

它对设备来说是最理想的布局视口,用户不需要对页面进行缩放就能完美的显示整个页面。这个理想的宽度是指以CSS像素单位计算的宽度,即屏幕的逻辑像素宽度,跟设备的物理宽度没有关系。在css中,这个宽度就相当于100%的所代表的那个宽度。

通过设置 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">实现

于是上述的meta设置,就是我们的理想设置,他规定了我们的视口宽度为屏幕宽度,初始缩放比例为1,就是初始时候我们的视觉视口就是理想视口!

理想视口的出现和乔布斯老爷子有关,他规定:布局视口宽度 = 视觉视口宽度 = 设备宽度(网页内容宽度)

手机浏览器窗口大小无法调整,所以视觉视口宽度就是设备宽度,精简写法:布局视口宽度 = 视觉视口宽度

意义:

  • 网页内容宽度 = 布局视口宽度

其实也很好理解,就是规定开发者在开发过程中,内容的宽度不能超出布局视口的宽度。

  • 布局视口宽度 = 视觉视口宽度

相对于浏览器窗口可以调整的 PC 端而言,视觉视口宽度就是浏览器窗口的宽度。相对于不能调整大小的移动端而言,视觉视口宽度就是设备屏幕大小宽度。这两个宽度相等的意义在于让设备可以将内容宽度显示完整,也就是不能左右滑动,可以上下滑动。也就是这种布局理念才造就了用户从上往下浏览内容的习惯。

其实,即使你布局视口=视觉视口宽度,在内容宽度≠布局视口宽度的情况下,会出现的情况就是内容过宽,需要进行缩放来显示整个内容,但是这就导致了内容的缩小,看起来费劲。但是如果你不缩小就只能显示一部分宽度,就需要左右滑动。

所以乔布斯提出了这种“理想视口”的概念,从而在开发行为方面进行了规范、在浏览器厂商配置进行了相对统一、在用户习惯上达到了满足。由此,三个方面都达到了一种标准化的统一。

乔布斯提出的理想视口概念其实意义重大,他不仅让开发者、浏览器厂商、用户习惯各自形成了一个标准,同时理想视口也是后续很多布局方案的基础。因为有了屏幕宽度 = 布局宽度这个概念后,布局方案都是以这个标准,以此来设计出了响应式布局和单独开发移动端的百分比布局方案。

viewport的深入理解: 点击打开链接

视口单位

移动互联网发展起来之后,CSS3引入了 vw、vh、vmin、vmax 长度单位,以方便移动端页面的开发。

vw(Viewport Width)、vh(Viewport Height)是基于视口的单位。

使用 vw、vh 能很好地解决宽度、高度适配问题,比使用 % 单位更高级!

  • vw:相对于视口的宽度,视口被均分为100单位的vw。1vw等于视口宽度的1%

  • vh:相对于视口的高度,视口被均分为100单位的vh。1vh等于视口高度的1%

  • vmin 相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin

  • vmax 相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax

即可以指定 height: x vh; 也可以指定 height: x vw; 比单纯指定 height: x %; 要有用得多!

总结:

viewport 属性表

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

因为要适配各种屏幕尺寸所以宽度不能固定要加入width=device-width来进行屏幕适配'

initial-scale=1  效果等同于 width=device-width

initial-scale=2   div 宽度 188px 时,横向刚好铺满屏幕,超过出现横向滚动条

scale 倍数越小,视口越大

布局视口

布局视口是看不见的,浏览器厂商设置的一个固定值

视觉视口

视觉视口是浏览器可视区域的大小,即用户看到的网页的区域(理解为网页的可视区域)

理想视口

它对设备来说是最理想的布局视口,用户不需要对页面进行缩放就能完美的显示整个页面。这个理想的宽度是指以CSS像素单位计算的宽度,即屏幕的逻辑像素宽度,跟设备的物理宽度没有关系。在css中,这个宽度就相当于100%的所代表的那个宽度。通过设置

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

实现于是上述的meta设置,就是我们的理想设置,他规定了我们的视口宽度为屏幕宽度,初始缩放比例为1,就是初始时候我们的视觉视口就是理想视口!理想视口的出现和乔布斯老爷子有关,他规定:布局视口宽度 = 视觉视口宽度 = 设备宽度(网页内容宽度)手机浏览器窗口大小无法调整,所以视觉视口宽度就是设备宽度,精简写法:布局视口宽度 = 视觉视口宽度

视口单位

vw:相对于视口的宽度,视口被均分为100单位的vw。1vw等于视口宽度的1%

即可以指定 height: x vh; 也可以指定 height: x vw; 比单纯指定 height: x %; 要有用得多!

响应式布局——视口viewport和常用单位相关推荐

  1. 响应式设计 视口 viewport 媒体查询

    响应式网页设计能让手机.平板电脑等均能获得完美的浏览体验,能够兼顾多屏幕.多场景的灵活设计,这与一次编写,到处运行有异曲同工的作用. 移动端设备的使用率虽然越来越高,但是计算机端用户也还有不少,基于这 ...

  2. html5的网页布局工具,HTML5网站响应式布局的主流设计方法介绍及工具推荐

    我们都知道,目前主流的pc屏幕的分辨率都是1366*768.1440*900 .1280*1024等大屏的显示器.所以网页不能再按照1024的标准来设计或者是前端重构了.加上现在移动互联网的发展势头, ...

  3. 南京html5响应式网站,HTML5响应式布局的设计方法和响应式前端优化

    作为一名优秀的web前端人员,不懂响应式布局怎么可以呢? 今天跟大家分享web前端开发和设计的干货:关于响应式布局的设计方法和响应式前端优化. 我们都知道,目前主流的pc屏幕的分辨率都是1366*76 ...

  4. 怎么在服务器端做响应式布局,关于响应式布局的设计方法和响应式前端优化

    原标题:关于响应式布局的设计方法和响应式前端优化 作为一名优秀的web前端人员,不懂响应式布局怎么可以呢? 今天跟大家分享web前端开发和设计的干货.关于响应式布局的设计方法和响应式前端优化. 我们都 ...

  5. PC端、移动端响应式布局的常用解决方案对比(媒体查询、百分比、rem和vw/vh)

    PC端.移动端响应式布局的常用解决方案对比 简要介绍: 一.px 和 视口 1. 像素 2. 视口 (1) 布局视口(layout viewport) (2) 视觉视口(visual viewport ...

  6. 响应式布局的常用解决方案对比(媒体查询、百分比、rem和vw/vh)

    响应式布局的常用解决方案对比(媒体查询.百分比.rem和vw/vh) px和视口 媒体查询 百分比 自适应场景下的rem解决方案 通过vw/vh来实现自适应 px和视口 在静态网页中,我们经常用像素( ...

  7. 响应式布局的常用解决方案(媒体查询、百分比、rem和vw/vh)

        在前端开发过程中,静态网页通常需要适应不同分辨率的设备,常用的自适应解决方案包括媒体查询.百分比.rem.和vw /vh,本文主要分析px在移动端布局中的不足,以及几种不同的自适应解决方案 一 ...

  8. CSS3与页面布局学习笔记(四)——页面布局大全(负边距、双飞翼、多栏、弹性、流式、瀑布流、响应式布局)

    一.负边距与浮动布局 1.1.负边距 所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%.当一个元素与另一个元素margin取负值时将拉近距离.常见的功能 ...

  9. 移动web学习(一) --- 流式布局, 视口viewpoint ,2倍图和3倍图, less

    从这章开始,学习移动web 移动web开发指的是需要适配移动设备的网页开发,和pc端没有本质的区别,还是使用html,css,js 一.学习移动web的原因 1. 使用移动设备的用户越来越多 2. 一 ...

最新文章

  1. (转)MySQL联表查询
  2. 0909 初识操作系统
  3. 充分的总结分析系统,来调整CMDB及流程。
  4. python代码大全p-python处理写入数据代码讲解
  5. android studio 使用SVN 锁定文件,防止别人修改(基于Android studio 1.4 )
  6. Redis单线程执行流程
  7. RequestMapping
  8. 函数在机器底层是如何实现的_软件机器人如何实现“二次录入”自动化,促进智慧政务?...
  9. 今日拷问:侬是什么垃圾!
  10. 产品设计:一层分类与多层分类模式的感悟
  11. 2018暑期周总结报告(四)
  12. AutoCAD2014 无法通过快捷方式启动
  13. 增强学习之一——Q-Learning公式
  14. python编程语言创始人-涨姿势!10位编程语言创始人,你都知道是谁吗?
  15. 通过这18000个Python项目对比,并从中精选出 45 个值得学习的!
  16. 用时间做种子生成随机数
  17. 根据TXT文件中的文件名复制文件
  18. 电灯开关-第12届蓝桥杯Scratch省赛2真题第1题
  19. 遍历算法(先序,中序,后序,广度,深度)
  20. java开发环境(java开发环境和运行环境)

热门文章

  1. Cesium 源码解析 Model(一)
  2. 腾讯第一批开发工程师徐钢武回忆道【曾几何时我真的认为代码是这样的】
  3. 微信小程序 async await解决异步问题
  4. 模拟器也可以使用摄像头,不用真机也可以测试摄像头程序 ,
  5. nvme分区选mbr还是guid_win10 双系统 Ubuntu UEFI+GPT bios+mbr 理论与实践
  6. EASYOPS系列|谨慎!勿让持续交付变成bug自动化发布
  7. 浅谈互联网行业发展趋势及现状
  8. Titan 的设计与实现
  9. CISCO 服务器配置 RAID 指南及安装操作系统
  10. 论文的参考文献格式怎么弄呢?