🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 视口 视口(`viewport`)代表当前可见的计算机图形区域。在`Web`浏览器术语中,通常与浏览器窗口相同,但不包括浏览器的`UI`, 菜单栏等——即指你正在浏览的文档的那一部分。 <br> 一般我们所说的视口共包括三种:布局视口、视觉视口和理想视口,它们在屏幕适配中起着非常重要的作用。 <br> <br> # 布局视口 ![](https://box.kancloud.cn/055a4ea0fb21ff16f4a0c3bddd2824f6_1280x959.png) <br> 布局视口(`layout viewport`):当我们以百分比来指定一个元素的大小时,它的计算值是由这个元素的包含块计算而来的。当这个元素是最顶级的元素时,它就是基于布局视口来计算的。 <br> 所以,布局视口是网页布局的基准窗口,在`PC`浏览器上,布局视口就等于当前浏览器的窗口大小(不包括`borders` 、`margins`、滚动条)。 <br> 在移动端,布局视口被赋予一个默认值,大部分为`980px`,这保证`PC`的网页可以在手机浏览器上呈现,但是非常小,用户可以手动对网页进行放大。 <br> 我们可以通过调用`document.documentElement.clientWidth / clientHeight`来获取布局视口大小。 <br> 如果要显式设置布局视口,可以使用 HTML 中的 meta 标签: ~~~ <meta name="viewport" content="width=400"> ~~~ <br> # 视觉视口 ![](https://box.kancloud.cn/a6c64213de04e2ca87de7401ce46d238_1280x959.png) <br> 视觉视口(`visual viewport`):用户通过屏幕真实看到的区域。 <br> 视觉视口默认等于当前浏览器的窗口大小(包括滚动条宽度)。 <br> 当用户对浏览器进行缩放时,不会改变布局视口的大小,所以页面布局是不变的,但是缩放会改变视觉视口的大小。 <br> 例如:用户将浏览器窗口放大了`200%`,这时浏览器窗口中的`CSS像素`会随着视觉视口的放大而放大,这时一个`CSS`像素会跨越更多的物理像素。 <br> 所以,布局视口会限制你的`CSS`布局而视觉视口决定用户具体能看到什么。 <br> 我们可以通过调用`window.innerWidth / innerHeight`来获取视觉视口大小。 <br> # 理想视口 ![](https://box.kancloud.cn/feabe3d19cb813b3c2183599901f0f8f_1280x694.png) <br> 布局视口在移动端展示的效果并不是一个理想的效果,所以理想视口(`ideal viewport`)就诞生了:网站页面在移动端展示的理想大小。 <br> 如上图,我们在描述设备独立像素时曾使用过这张图,在浏览器调试移动端时页面上给定的像素大小就是理想视口大小,它的单位正是设备独立像素。 <br> 上面在介绍`CSS像素时`曾经提到`页面的缩放系数 = CSS像素 / 设备独立像素`,实际上说`页面的缩放系数 = 理想视口宽度 / 视觉视口宽度`更为准确。 <br> 所以,当页面缩放比例为`100%`时,`CSS像素 = 设备独立像素`,`理想视口 = 视觉视口`。 <br> 我们可以通过调用`screen.width / height`来获取理想视口大小。 <br> # Meta viewport `<meta>` 元素表示那些不能由其它`HTML`元相关元素之一表示的任何元数据信息,它可以告诉浏览器如何解析页面。 <br> 我们可以借助`<meta>`元素的`viewport`来帮助我们设置视口、缩放等,从而让移动端得到更好的展示效果。 <br> ~~~ <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;"> 复制代码 ~~~ <br> 上面是`viewport`的一个配置,我们来看看它们的具体含义: | `Value` | 可能值 | 描述 | | --- | --- | --- | | `width` | 正整数或`device-width` | 以`pixels`(像素)为单位, 定义布局视口的宽度。 | | `height` | 正整数或`device-height` | 以`pixels`(像素)为单位, 定义布局视口的高度。 | | `initial-scale` | `0.0 - 10.0` | 定义页面初始缩放比率。 | | `minimum-scale` | `0.0 - 10.0` | 定义缩放的最小值;必须小于或等于`maximum-scale`的值。 | | `maximum-scale` | `0.0 - 10.0` | 定义缩放的最大值;必须大于或等于`minimum-scale`的值。 | | `user-scalable` | 一个布尔值(`yes`或者`no`) | 如果设置为 `no`,用户将不能放大或缩小网页。默认值为 yes。 | <br> # 移动端适配 为了在移动端让页面获得更好的显示效果,我们必须让布局视口、视觉视口都尽可能等于理想视口。 <br> `device-width`就等于理想视口的宽度,所以设置`width=device-width`就相当于让布局视口等于理想视口。 <br> 由于`initial-scale = 理想视口宽度 / 视觉视口宽度`,所以我们设置`initial-scale=1;`就相当于让视觉视口等于理想视口。 <br> 这时,1个`CSS`像素就等于1个设备独立像素,而且我们也是基于理想视口来进行布局的,所以呈现出来的页面布局在各种设备上都能大致相似。 <br> # 缩放 上面提到`width`可以决定布局视口的宽度,实际上它并不是布局视口的唯一决定性因素,设置`initial-scale`也有肯能影响到布局视口,因为布局视口宽度取的是`width`和视觉视口宽度的最大值。 <br> 例如:若手机的理想视口宽度为`400px`,设置`width=device-width`,`initial-scale=2`,此时`视觉视口宽度 = 理想视口宽度 / initial-scale`即`200px`,布局视口取两者最大值即`device-width` `400px`。 <br> 若设置`width=device-width`,`initial-scale=0.5`,此时`视觉视口宽度 = 理想视口宽度 / initial-scale`即`800px`,布局视口取两者最大值即`800px`。 # 获取浏览器大小 ![](https://box.kancloud.cn/4b2e92b142aa86a6cbb67eef366c5e55_1280x668.png) * `window.innerHeight`:获取浏览器视觉视口高度(包括垂直滚动条)。 * `window.outerHeight`:获取浏览器窗口外部的高度。表示整个浏览器窗口的高度,包括侧边栏、窗口镶边和调正窗口大小的边框。 * `window.screen.Height`:获取获屏幕取理想视口高度,这个数值是固定的,`设备的分辨率/设备像素比` * `window.screen.availHeight`:浏览器窗口可用的高度。 * `document.documentElement.clientHeight`:获取浏览器布局视口高度,包括内边距,但不包括垂直滚动条、边框和外边距。 * `document.documentElement.offsetHeight`:包括内边距、滚动条、边框和外边距。 * `document.documentElement.scrollHeight`:在不使用滚动条的情况下适合视口中的所有内容所需的最小宽度。测量方式与`clientHeight`相同:它包含元素的内边距,但不包括边框,外边距或垂直滚动条。 <br> <br> # 参考资料 [关于移动端适配,你必须要知道的](https://juejin.im/post/5cddf289f265da038f77696c)