移动端开发-viewport与媒体查询

首先要知道,在移动开发中,手机的浏览器会默认网页是为宽屏而设计的,它会缩小整个页面来适应屏幕。javascript

1. 不使用viewport出现的问题

提到响应式设计,你们首先想到的多是 Bootstrap , @media 。css

@media(媒体查询)是CSS3的属性,利用它能够在不依赖其余库的状况下实现响应式设计。示例代码以下:java

       @media screen and (min-width: 960px) {
          body { background-color: blue; }
        }

        @media screen and (max-width: 960px) and (min-width: 500px) {
          body { background-color: red; }
        }

        @media screen and (max-width: 500px) {
          body { background-color: yellow; }
        }

我在body里加了一段话,在PC端效果以下: 
开始: 
这里写图片描述web

缩小浏览器窗口: 
这里写图片描述浏览器

再缩小浏览器窗口: 
这里写图片描述服务器

我把这样页面放到服务器上,用个人手机访问,个人手机屏幕宽度是414px。那么这个页面在我手机上应该是黄色。请看屏幕截图: 
这里写图片描述iphone

是蓝色的。那么问题来了,为何媒体查询失效了呢。这是因为设备尺寸和Viewport尺寸不一致致使的。为了解释这个问题,首先咱们要理解移动设备上的1px != css中的1px。ide

2. css中的px与移动设备的px

在css中咱们通常使用px做为单位,在桌面浏览器中css的1个像素每每都是对应着电脑屏幕的1个物理像素,这可能会形成咱们的一个错觉,那就是css中的像素就是设备的物理像素。但实际状况却并不是如此,css中的像素只是一个抽象的单位,在不一样的设备或不一样的环境中,css中的1px所表明的设备物理像素是不一样的。影响css中px与设备px换算的因素主要有如下两个:布局

  • 设备尺寸
  • 用户缩放

设备尺寸 
iphone3的分辨率为320x480,在iphone3上,一个css像素确实是等于一个屏幕物理像素的。从iphone4分辨率提升了一倍,变成640x960,但屏幕尺寸却没变化,这就意味着一样大小的屏幕上,像素却多了一倍,这时,一个css像素是等于两个物理像素的。其余设备相似。 
用户缩放 
当用户把页面放大一倍,那么css中1px所表明的物理像素也会增长一倍;反之把页面缩小一倍,css中1px所表明的物理像素也会减小一倍。你能够想象,css中的px是一个一个小格子,在缩放页面的时候,实际上是在缩放每一个小格子,而设备物理像素显然是大小不变的。测试

在移动端浏览器中以及某些桌面浏览器中,window对象有一个devicePixelRatio属性,它的官方的定义为:设备物理像素和设备独立像素的比例,也就是 devicePixelRatio = 物理像素 / 独立像素。css中的px就能够看作是设备的独立像素,因此经过devicePixelRatio,咱们能够知道该设备上一个css像素表明多少个物理像素。在上面例子中增长js脚本:

window.alert(window.devicePixelRatio);

在PC端: 
这里写图片描述

在个人手机上: 
这里写图片描述

设备像素比是不一样的。

3. 三种视口(viewport)

你可能觉得我啰嗦这么多终于要进入正题了。咳咳,其实我仍是想让你了解下面三个概念。若是你熟悉移动端开发,请跳过这节直接看4 ,若是你刚刚接触移动端开发,我建议你读下去,迟早你得了解。

3.1 布局视口(layout viewport)

移动设备上的浏览器认为本身必须能让全部的网站都正常显示,即便是那些不是为移动设备设计的网站。但若是以浏览器的可视区域做为viewport的话,由于移动设备的屏幕都不是很宽,因此那些为桌面浏览器设计的网站放到移动设备上显示时,必然会由于移动设备的viewport太窄,而挤做一团,甚至布局什么的都会乱掉。因此这些浏览器就决定默认状况下把viewport设为一个较宽的值,好比980px,这样的话即便是那些为桌面设计的网站也能在移动浏览器上正常显示了。这个宽度被称为布局视口(layout viewport),能够经过document.documentElement.clientWidth得到。

3.2 视觉视口(visual viewport)

虽然独立布局视口的创造很大程度地帮助了桌面网站到手机上的转移,但咱们不能彻底无视移动端设备的屏幕尺寸。一些CSS声明与用户见到的东西有关,而与CSS的初始包含块无关。而且,有时候知道用户看到了网站的哪些部分对web开发者会有帮助。视觉视口是用户正在看到的网站的区域,对于的javascript属性是window.innerWidth
缩放会影响视觉视口的大小。当缩放程度是100%时,视觉视口与设备屏幕同样宽。放大使视觉视口变得更小,由于屏幕上显示的CSS像素更小了,而缩小会让视觉视口更大,由于屏幕上的CSS像素更多了。所以缩放程度和视觉视口的大小是逆相关的:放得越大,视觉视口越小。 
注意:当用户缩放时,只有视觉视口的尺寸会发生改变,布局视口不会改变。移动端的缩放不会致使CSS布局被从新计算。

3.3 理想视口(ideal viewport)

如今愈来愈多的网站都会为移动设备进行单独的设计,因此必须还要有一个能完美适配移动设备的viewport。所谓的完美适配指的是,首先不须要用户缩放和横向滚动条就能正常的查看网站的全部内容;第二,显示的文字的大小是合适,好比一段14px大小的文字,不会由于在一个高密度像素的屏幕里显示得过小而没法看清,理想的状况是这段14px的文字不管是在何种密度屏幕,何种分辨率下,显示出来的大小都是差很少的。固然,不仅是文字,其余元素像图片什么的也是这个道理。这个视口被称为理想视口(ideal viewport),这个尺寸是厂商肯定的。 
只有当网站是为手机准备的时候才应该使用理想视口。只有主动地往页面里添加meta视口标签时理想视口才会生效。若是没有meta视口标签声明,那么布局视口将会维持它的默认宽度,理想视口只有当显式地使用它的时候才会产生影响:

//这一行代码告诉浏览器,布局视口的宽度应该与理想视口的宽度一致
<meta name="viewport" content="width=device-width">

3.4 测试三种视口

在head标签中加入<meta name="viewport" content="width=device-width">,使布局视口宽度等于理想视口宽度,加入下面js代码进行测试。

   var ratio = window.devicePixelRatio;
    var layoutWidth = document.documentElement.clientWidth;
    var visualWidth = window.innerWidth;
    window.alert('devicePixelRatio: ' + ratio + ' || layout viewport: ' + layoutWidth + ' || visual viewport: ' + visualWidth);

PC端: 
这里写图片描述 
手机: 
这里写图片描述

4 使用meta标签控制viewport实现响应式设计

移动设备默认的viewport是layout viewport,也就是那个比屏幕要宽的viewport,但在进行移动设备网站的开发时,咱们须要的是ideal viewport。那么怎么才能获得ideal viewport呢?这就该轮到meta标签出场了。

4.1 设置meta标签

咱们在开发移动设备的网站时,最多见的的一个动做就是把下面这个东西复制到咱们的head标签中:

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

该meta标签的做用是让当前viewport的宽度等于设备的宽度,同时不容许用户手动缩放。meta标签中共有6个关键字:

  • width:能够用width来设置viewport的宽度,以替代那些不合适的默认宽度。咱们能够给其设定一个固定大小,但设定成device-width更加明智一些,这样咱们能够兼容不一样大小的屏幕。
  • height:同width
  • initial-scale:控制默认的缩放比例,缩放是相对于ideal viewport来缩放的
  • minimum-scale:这个是用户能够缩放页面的最大比例
  • maximum-scale:这个是用户能够缩放页面的最小比例
  • user-scalable:若是设置了user-scalable=no,用户将没法对页面进行缩放

了解这些之后,咱们在测试例子中的head标签中加入viewport,使理想视口宽度等于布局视口宽度:

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

PC端网页效果不变,手机端访问效果: 
这里写图片描述 
这是咱们想要的效果了。

4.2 动态改变meta标签

第一种方法

可使用document.write来动态输出meta viewport标签,例如:

document.write('<meta name="viewport" content="width=device-width,initial-scale=1">')

第二种方法

经过setAttribute来改变

<meta id="testViewport" name="viewport" content="width = 380">
<script>
var mvp = document.getElementById('testViewport');
mvp.setAttribute('content','width=480');
</script>

 

参考:https://blog.csdn.net/qiqingjin/article/details/51539644

相关文章
相关标签/搜索