[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)
- 第一部分 HTML
- meta
- meta标签
- HTML5
- 2.1 语义
- 2.2 通信
- 2.3 离线&存储
- 2.4 多媒体
- 2.5 3D,图像&效果
- 2.6 性能&集成
- 2.7 设备访问
- SEO
- Canvas
- 压缩图片
- 制作圆角矩形
- 全局属性
- 第二部分 CSS
- CSS原理
- 层叠上下文(stacking context)
- 外边距合并
- 块状格式化上下文(BFC)
- 盒模型
- important
- 样式继承
- 层叠
- 属性值处理流程
- 分辨率
- 视口
- CSS API
- grid(未完成)
- flex
- 选择器
- 3D
- Matrix
- AT规则
- line-height 和 vertical-align
- CSS技术
- 居中
- 响应式布局
- 兼容性
- 移动端适配方案
- CSS应用
- CSS Modules(未完成)
- 分层
- 面向对象CSS(未完成)
- 布局
- 三列布局
- 单列等宽,其他多列自适应均匀
- 多列等高
- 圣杯布局
- 双飞翼布局
- 瀑布流
- 1px问题
- 适配iPhoneX
- 横屏适配
- 图片模糊问题
- stylelint
- 第三部分 JavaScript
- JavaScript原理
- 内存空间
- 作用域
- 执行上下文栈
- 变量对象
- 作用域链
- this
- 类型转换
- 闭包(未完成)
- 原型、面向对象
- class和extend
- 继承
- new
- DOM
- Event Loop
- 垃圾回收机制
- 内存泄漏
- 数值存储
- 连等赋值
- 基本类型
- 堆栈溢出
- JavaScriptAPI
- document.referrer
- Promise(未完成)
- Object.create
- 遍历对象属性
- 宽度、高度
- performance
- 位运算
- tostring( ) 与 valueOf( )方法
- JavaScript技术
- 错误
- 异常处理
- 存储
- Cookie与Session
- ES6(未完成)
- Babel转码
- let和const命令
- 变量的解构赋值
- 字符串的扩展
- 正则的扩展
- 数值的扩展
- 数组的扩展
- 函数的扩展
- 对象的扩展
- Symbol
- Set 和 Map 数据结构
- proxy
- Reflect
- module
- AJAX
- ES5
- 严格模式
- JSON
- 数组方法
- 对象方法
- 函数方法
- 服务端推送(未完成)
- JavaScript应用
- 复杂判断
- 3D 全景图
- 重载
- 上传(未完成)
- 上传方式
- 文件格式
- 渲染大量数据
- 图片裁剪
- 斐波那契数列
- 编码
- 数组去重
- 浅拷贝、深拷贝
- instanceof
- 模拟 new
- 防抖
- 节流
- 数组扁平化
- sleep函数
- 模拟bind
- 柯里化
- 零碎知识点
- 第四部分 进阶
- 计算机原理
- 数据结构(未完成)
- 算法(未完成)
- 排序算法
- 冒泡排序
- 选择排序
- 插入排序
- 快速排序
- 搜索算法
- 动态规划
- 二叉树
- 浏览器
- 浏览器结构
- 浏览器工作原理
- HTML解析
- CSS解析
- 渲染树构建
- 布局(Layout)
- 渲染
- 浏览器输入 URL 后发生了什么
- 跨域
- 缓存机制
- reflow(回流)和repaint(重绘)
- 渲染层合并
- 编译(未完成)
- Babel
- 设计模式(未完成)
- 函数式编程(未完成)
- 正则表达式(未完成)
- 性能
- 性能分析
- 性能指标
- 首屏加载
- 优化
- 浏览器层面
- HTTP层面
- 代码层面
- 构建层面
- 移动端首屏优化
- 服务器层面
- bigpipe
- 构建工具
- Gulp
- webpack
- Webpack概念
- Webpack工具
- Webpack优化
- Webpack原理
- 实现loader
- 实现plugin
- tapable
- Webpack打包后代码
- rollup.js
- parcel
- 模块化
- ESM
- 安全
- XSS
- CSRF
- 点击劫持
- 中间人攻击
- 密码存储
- 测试(未完成)
- 单元测试
- E2E测试
- 框架测试
- 样式回归测试
- 异步测试
- 自动化测试
- PWA
- PWA官网
- web app manifest
- service worker
- app install banners
- 调试PWA
- PWA教程
- 框架
- MVVM原理
- Vue
- Vue 饿了么整理
- 样式
- 技巧
- Vue音乐播放器
- Vue源码
- Virtual Dom
- computed原理
- 数组绑定原理
- 双向绑定
- nextTick
- keep-alive
- 导航守卫
- 组件通信
- React
- Diff 算法
- Fiber 原理
- batchUpdate
- React 生命周期
- Redux
- 动画(未完成)
- 异常监控、收集(未完成)
- 数据采集
- Sentry
- 贝塞尔曲线
- 视频
- 服务端渲染
- 服务端渲染的利与弊
- Vue SSR
- React SSR
- 客户端
- 离线包
- 第五部分 网络
- 五层协议
- TCP
- UDP
- HTTP
- 方法
- 首部
- 状态码
- 持久连接
- TLS
- content-type
- Redirect
- CSP
- 请求流程
- HTTP/2 及 HTTP/3
- CDN
- DNS
- HTTPDNS
- 第六部分 服务端
- Linux
- Linux命令
- 权限
- XAMPP
- Node.js
- 安装
- Node模块化
- 设置环境变量
- Node的event loop
- 进程
- 全局对象
- 异步IO与事件驱动
- 文件系统
- Node错误处理
- koa
- koa-compose
- koa-router
- Nginx
- Nginx配置文件
- 代理服务
- 负载均衡
- 获取用户IP
- 解决跨域
- 适配PC与移动环境
- 简单的访问限制
- 页面内容修改
- 图片处理
- 合并请求
- PM2
- MongoDB
- MySQL
- 常用MySql命令
- 自动化(未完成)
- docker
- 创建CLI
- 持续集成
- 持续交付
- 持续部署
- Jenkins
- 部署与发布
- 远程登录服务器
- 增强服务器安全等级
- 搭建 Nodejs 生产环境
- 配置 Nginx 实现反向代理
- 管理域名解析
- 配置 PM2 一键部署
- 发布上线
- 部署HTTPS
- Node 应用
- 爬虫(未完成)
- 例子
- 反爬虫
- 中间件
- body-parser
- connect-redis
- cookie-parser
- cors
- csurf
- express-session
- helmet
- ioredis
- log4js(未完成)
- uuid
- errorhandler
- nodeclub源码
- app.js
- config.js
- 消息队列
- RPC
- 性能优化
- 第七部分 总结
- Web服务器
- 目录结构
- 依赖
- 功能
- 代码片段
- 整理
- 知识清单、博客
- 项目、组件、库
- Node代码
- 面试必考
- 91算法
- 第八部分 工作代码总结
- 样式代码
- 框架代码
- 组件代码
- 功能代码
- 通用代码