web 中的 viewport 问题

你是不是被 Web 布局中的各种 viewport 概念搞蒙,不但如此,你还得去考虑网页有放大缩小的情况,更气人的是 Mobile 侧和 PC 侧很多表现竟然不一样。本篇就带你一同探讨下这些问题。

px

css 中的 px 并不代表一个屏幕的物理像素,而是一个逻辑像素。比如我们写了一个 10 X 10 px 的方块,如果我们此时进行放大(ctrl+)操作,让整个网页变为 200%,那会发现这个方块在屏幕上长宽也各增大了一倍,那么同样代码的 10x10 对应占用的物理像素变为了原来的 4 倍(长宽各 2 倍)。所以 css 中的 px 并不是物理像素,这样更加灵活。后来浏览器还引入了 devicePixelRatio,同样 px 即使在高分辨率的显示屏幕上也不会出现问题,因为会乘以这个系数来作为真实的物理像素。

window.innerWidth

在 PC 浏览器上,当你放大、缩小网页时,你会发现 innerWidth 和 innerHeight 会随着改变,放大时 innerWidth 会变小,这是为啥呢?innerWidth 的官方定义如下:

The read-only Window property **innerWidth** returns the interior width of the window in pixels. This includes the width of the vertical scroll bar, if one is present.

所以 innerWidth 和 innerHeight 表现的是网页的布局区域的像素值,如果网页整体放大,那么同样的物理区域内显示的像素当然就变少了,进而导致了 innerWidth 变小。官方定义还有下面一句话:

More precisely, innerWidth returns the width of the window's layout viewport.

layout viewport 和 visual viewport

继续先来一段官方解释。

The layout viewport is the viewport into which the browser draws a web page. Essentially, it represents what is available to be seen, while the visual viewport represents what is currently visible on the user's display device.

通俗来讲,layout viewport 表示一个可见布局,这个可见布局里的内容并不一定当前可见,当前可见的部分有被称为 visual viewport。

此时我们回顾下刚刚介绍 px 时使用的放大缩小能力,PC 侧和移动侧放大缩小功能是不一样的,而且它们的作用也不同。在 PC 侧的浏览器,我们可以通过浏览器的 zoom 功能。


而在移动端,我们需要用两指缩放、或用单指双击的方式。这种方式并不会引起 window.innerWidth 的变化。也就是说移动侧的 layout viewport 不变,会变动只是 visual viewport。文档也证实了这一说法

This becomes important, for example, on mobile devices, where a pinching gesture can usually be used to zoom in and out on a site's contents. The rendered document doesn't change in any way, so the layout viewport remains the same as the user adjusts the zoom level. Instead, the visual viewport is updated to indicate the area of the page that they can see.

当网页完全缩放塞满整个屏幕时,layout viewport === visual viewport。而当两指放大时,visual viewport 要小于 layout viewport。

viewport

移动端布局中用到一个 name 为 viewport 的 meta,此 viewport 和刚刚所提到的 layout viewport 和 visual viewport 并不同。此属性的作用是约束整个网页布局 html 的大小。所以你可以通过以下两个属性获得他的大小。

document.documentElement.clientWidth
document.documentElement.clientHeight

PC 侧的浏览视窗大小是可以随意变动的,所以在 PC 侧,此属性设置无效,PC 侧的 window.innerWidth === document.documentElement.clientWidth。而到移动端就不一样了,移动端的浏览器往往占据整个屏幕,你无法调整视窗的比例和大小,此时定义 viewport 就有作用了。并且为了能在移动设备上显示老的 PC 侧页面,移动浏览器厂商默认把这个 viewport 定为了 980px,有些如 IE 定为了 1024px。

例如我写了个以下例子

<html>
    <body style="margin: 0">
        <div style="width: 100%; font-size: 40px; overflow: hidden; background-color: rgb(220, 220, 220);">12345678912345678912345678</div>
    </body>
</html>

在没有加 meta 的情况下,这个 div 长度为 980,由于移动端浏览器机制,针对这种默认场景,浏览器会把整个网页自动缩小到占据屏幕的整个宽。如果要展示如 PC 侧一样的大小,则会出现左右滚动条,体验很差。

此时我们加上 viewport 的 meta,则会发现宽度变为了屏幕的 320 宽。

<meta name='viewport' content="width=device-width">

viewport 可以用来改变移动端 html 的宽度像素值,此值与屏幕本身的宽度并无关,只是你可以通过设置 width=device-width 的方式让两者相同。

另外此 meta 中还有 initial-scale, maximum-scale, minimum-scale, user-scalable 这几个配置,user-scalable 及表示用户是否可以用两指缩放。scale 几个参数表示缩放比例,都是相对于屏幕宽度来说的,所以initial-scale=1.0width=device-width是一样的意思,如果调成 0.5,则相当于把 width 设置为了 2 倍 device-width。因为内容缩小了一倍,那自然viewport就放大了一倍了。

总结一下

screen.width, screen.height 表示整个显示屏幕的逻辑像素宽高;
window.innerWidth, window.innerHeight 表示 layout viewport,在 PC 侧会随着浏览器窗口和 zoom 效果而变大变小。而在移动端侧,则表示整个布局的长宽,由代码决定。
visual viewport 真正表示当前可以看见的区域。
meta viewport 可以定义 html 的宽度。

如果你想了解 Android 中的尺寸布局问题,可以看:《Android布局中的尺寸单位介绍》

参考:
https://www.quirksmode.org/mobile/viewports.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容