概述

前几天偶然看到一个pc端网页,发现用手机打开竟然同比缩放了,作为一个前端从业者,我自然想要弄清它到底是怎么缩放的。之后查了它的meta信息,css和js,发现没有任何兼容手机端的代码,那它到底是怎么缩放的呢?百思不得其解,最后无意中看别人说viewport的默认值是980px,才知道原来是viewport的锅。

于是我深入的复习了一下viewport相关知识,把心得记录下来,供以后开发时参考,相信对其他人也有用。

基础概念

本来看了移动前端开发之viewport的深入理解,但是仍然有一些概念不理解,于是去看了PPK大神对于viewport的研究(第一篇第二篇第三篇),算是理清了。

首先从css像素和实际像素说起,css像素就是我们写的css的像素,如果没有进行任何缩放的话,css像素就和实际像素是一样的,如果用浏览器对页面进行了缩放,那么css像素不变,实际像素会根据缩放比例变化

值得一提的是,缩放是个很重要的概念,在pc端的网页一般没有进行缩放,所以1px的css像素常常等于1px的实际像素。

  1. 取viewport宽高,用document.documentElement.clientWidth和document.documentElement.Height。
  2. 取设备宽高,用screen.width和screen.height。
  3. 取窗口可视区域宽高,用window.innerWidth和window.innerHeight。
  4. 取可视区域偏移量,用window.pageXOffset和window.pageYOffset。

viewport宽高

viewport宽高是用document.documentElement.clientWidth和document.documentElement.Height来取到的。细心观察可以发现,document.documentElement就是html元素,而document.documentElement.clientWidth就是html的宽度。

我们知道,css里面的包含块的宽度会自动延伸至父元素的宽度,所以最外层包含块的宽度会延伸到body的宽度,而body的宽度会延伸到html的宽度,那html的宽度延伸到什么宽度呢?答案是viewport的宽度!所以可以用html的宽度来度量viewport的宽度。

另外,这里有一个小坑,就是html的宽度是可以修改的,但是即使修改了html的宽度,document.documentElement.clientWidth和document.documentElement.Height的值仍然是viewport的宽高,这是html元素的这2个属性的不同之处。

那当我们改了html的宽度之后,怎么获得html的宽高呢?方式是利用document.documentElement.offsetWidth和document.documentElement.offsetHeight.

移动端viewport

明白了上面viewport的宽高机制之后就很好理解移动端的viewport了。

移动端由于设备的像素很小,所以如果不进行缩放的话,就只能看到pc端网页的部分内容,所以移动端浏览器在兼容的时候,会对页面进行缩放,但是为了避免在缩放的时候页面发生重排和重绘,浏览器就有2个viewport,一个是我们常说的viewport,它用来放置页面,它的默认值宽度是980px;另一个是可视区域的visual viewport,它是移动端的可视区域,用来放大或缩小。

在pc端,我们常说的viewport就等于可视区域的visual viewport,所以css像素和实际像素比是1比1。

在移动端,由于放置页面的viewport的宽度默认为980px,但是设备的宽度常常小于980px,所以可视区域的viewport会对它进行缩放,直到页面内容的宽度正好达到屏幕的宽度。所以我们用手机端看到的pc端页面都是已经缩放过的(如果页面没有设置viewport的话)。

注意,有些情况下,可视区域的viewport的宽度不会等于放置页面的viewport的宽度。比如有一个页面,我们设置它的最外层包含块的最小宽度为1250px,那么放置页面的viewport的宽度仍是默认值980px,但是可视区域的viewport的宽度会达到1250px。

那怎么得到可视区域的缩放比例呢?它等于设备的宽度除以可视区域的宽度,即:screen.width/window.innerWidth。(注意不是viewport的宽度)

其他宽度信息也可以按照上面列出的方法来取。

修改viewport

如果是专门为移动端做的页面,那么常常要设置viewport,使它的两个viewport都等于设备宽度。代码如下:

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

viewport的其它设置方法可以参考:移动前端开发之viewport的深入理解

你可能不知道的viewport的更多相关文章

  1. 你可能不知道的7个CSS单位

    如果你是一名前端开发工程师,一般px和em使用频率比较高.但是今天本文的重点是介绍一些我们使用很少.甚至么有听说的单位. 一.重温em <style type="text/css&qu ...

  2. 您可能不知道的CSS元素隐藏“失效”以其妙用——张鑫旭

    一.CSS元素隐藏 在CSS中,让元素隐藏(指屏幕范围内肉眼不可见)的方法很多,有的占据空间,有的不占据空间:有的可以响应点击,有的不能响应点击.后宫选秀——一个一个看. { display: non ...

  3. 你所不知道的setInterval

    在你所不知道的setTimeout记载了下setTimeout相关,此篇则整理了下setInterval:作为拥有广泛应用场景(定时器,轮播图,动画效果,自动滚动等等),而又充满各种不确定性的这set ...

  4. 你所不知道的setTimeout

    JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.它们向任务队列添加定时任务.初始接触它的人都觉得好简单 ...

  5. 你可能不知道的陷阱, IEnumerable接口

    1.  IEnumerable 与  IEnumerator IEnumerable枚举器接口的重要性,说一万句话都不过分.几乎所有集合都实现了这个接口,Linq的核心也依赖于这个万能的接口.C语言的 ...

  6. 你真的会玩SQL吗?你所不知道的 数据聚合

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  7. 你所不知道的linq(二)

    上一篇说了from in select的本质,具体参见你所不知道的linq.本篇说下from...in... from... in... select 首先上一段代码,猜猜结果是什么? class P ...

  8. swift与OC之间不得不知道的21点

    swift与OC之间不得不知道的21点   自6月的WWDC大会上由苹果的大神Chris Lattner向我们首次展示swift至今已经大半年时间了,虽然绝大部分软件公司代码里还都见不到一丁点swif ...

  9. 你所不知道的15个Axure使用技巧

    你有用原型开发工具吗?如果有,那你用的是Axure还是别的? 从以前就喜欢使用Axure,主要是觉得它能清楚的表达设计的思路,还有交互的真实再现,能让看的人一目了然,昨天看了这篇博文,便更加确定Axu ...

随机推荐

  1. python中的异常处理常用方法

    异常处理 什么是异常? 异常就是与正常情况不同,程序在执行过程中出现错误,导致无法执行完毕.异常其实就是代码执行过程中出错. 常见的一些异常 AttributeError 试图访问一个对象没有的属性, ...

  2. 剑指offer——合并两个排序的链表——对象、引用和赋值初接触

    题目描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然,我们需要合成后的链表满足单调不减规则. 先公布结果: /* public class ListNode { int val; List ...

  3. week07 13.2 NewsPipeline之 二 News Fetcher - Xpath

    我们使用Xpath来专门做一个scrapter 我们专门弄个文件夹 里面全部是 各个新闻源(CNN BBC等)的scraper来抓取网站的text内容 主要函数(就是传入text内容的那个url)然后 ...

  4. Halcon示例:bottlet.hdev 光学字符识别(创建OCR)

    * * Training of the OCR* The font is used in "bottle.hdev"* * * Step 0: PreparationsFontNa ...

  5. hello1以及hello2的部分代码分析

    (一)1.GreetingServlet.java源码文件: @WebServlet("/greeting") //以@WebServlet注释开头,注释指定相对于上下文根的URL ...

  6. 二十一、proxyDesign 代理模式

    原理: 时序图: 代码清单: Printable public interface Printable { void setPrinterName(String name); String getPr ...

  7. FastCGI与PHP

    什么是CGI CGI全称"通用网关接口"(Common Gateway Interface),用于HTTP服务器与其它机器上的程序服务通信交流的一种工具,CGI程序须运行在网络服务 ...

  8. HTML中关于class内容空格多类名的问题详解

    之所以想谈谈这个,不明所以.所以转载下来方便自己看看. 问:像 class="info fl" 这种class定义是何意思? 答:这里的空格隔开后,它们所代表的是两个类名,分别为i ...

  9. linux就该这么学,第六天了

    今天学了第六天了,主要讲计划任务了,,at,命令,单次有效,一次性的,crontd服务(周期性)计划任务,crontab -e创建,编辑计划任务.crontab -l查看计划任务,crontaab - ...

  10. 腾讯云的基本配置(centos 7.1)及mysql的使用

    因为想在微信上开发些东西,所以租用了一个月的腾讯云. 推荐选择的镜像是centos7.1.这个系统的选择和本地操作系统基本没有关系. 首先要登录到云主机中,用户名是root,密码是当初自己设置的那一个 ...