网页的响应式设计是一种设计实践，这种设计实践是随着移动互联网时代的到来而逐渐兴起的。随着智能设备的兴起，人们不再仅仅是通过个人电脑来访问网页，还有可能使用智能手机或者平板电脑，如何适配各种不同尺寸大小，不同分辨率的设备，为网页设计带来了新的挑战。而响应式设计就是一种解决方案，采用响应式设计后，同样的一个网页会在不同设备上显示不同的布局，从而带来良好的用户体验。本文将通过设计一个简单到不能再简单的响应式框架来展现响应式设计的基本原理。

## 一. 什么是响应式设计

就像我们可以用盒子模型的思维来看待网页一样，我们同样可以使用“格子”的思维来看待网页的结构。我们的眼睛在看东西时会遵循一定的模式，比如先从左往右看，然后从上往下看。比如先看文字，然后看标题，最后再阅读下面的文字等等。我们将这样的设计称为网格布局，很多网站都遵循网格布局，不难看出Udacity的网站就是网格布局的：



![img](https:////upload-images.jianshu.io/upload_images/1917785-a88fe711642bc5b0.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)

udacity.png

编写一个响应式框架的原理就是通过创建一些通用的CSS类来定义所需要的样式，特别是控制元素宽度的技巧以及在页面上排布的方式。创建用于控制布局的CSS类是一种最佳实践。

## 二. 一个非常简单的响应式框架

要实现响应式设计，让网站根据浏览器的大小来改变元素的大小，肯定不能用绝对尺寸，比如300px，必须使用百分比代表的相对尺寸。在上一个学习笔记中我们提到，如果将元素的尺寸设置为百分比，那么该元素的大小由离它最近的父元素大小决定。响应式框架的基本原理就是将一行（row）拆分为12个网格（grid），这样我们就可以基于网格进行各种形态的布局设计，比如大名鼎鼎的Bootstrap框架是这么定义的：



![img](https:////upload-images.jianshu.io/upload_images/1917785-4c6dfa0d3aee962a.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)

grid.png

我们以一个示例项目来讲解如何编写一个简单的响应式框架，项目的目录结构如下：



![img](https:////upload-images.jianshu.io/upload_images/1917785-bbfdb0670ac059d4.png?imageMogr2/auto-orient/strip|imageView2/2/w/622/format/webp)

test.png

在main.css文件中编写框架如下（注意这里的row使用了flex显示类型）：

```css
* {
    border: 1px solid red !important;
}

* {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
}

.grid {
    margin: 0 auto;
    max-width: 1200px;
    width: 100%;
}

.row {
    width: 100%;
    margin-bottom: 20px;
    display: flex;
}

.col-1 {
    width: 8.33%;
}

.col-2 {
    width: 16.66%;
}

.col-3 {
    width: 25%;
}

.col-4 {
    width: 33.33%;
}

.col-5 {
    width: 41.66%;
}

.col-6 {
    width: 50%;
}

.col-7 {
    width: 58.33%;
}

.col-8 {
    width: 66.66%;
}

.col-9 {
    width: 75%;
}

.col-10 {
    width: 83.33%;
}

.col-11 {
    width: 91.66%;
}

.col-12 {
    width: 100%;
}
```

在test.html中编写测试代码：

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Framework Test Page</title>
  <link rel="stylesheet" href="css/main.css">
</head>
<body>
  <div class="grid">
    <div class="row">
      <div class="col-2">2 Columns</div>
      <div class="col-10">10 Columns</div>
    </div>
    <div class="row">
      <div class="col-3">3 Columns</div>
      <div class="col-9">9 Columns</div>
    </div>
    <div class="row">
      <div class="col-4">4 Columns</div>
      <div class="col-4">4 Columns</div>
      <div class="col-4">4 Columns</div>
    </div>
    <div class="row">
      <div class="col-3">3 Columns</div>
      <div class="col-6">6 Columns</div>
      <div class="col-3">3 Columns</div>
    </div>
  </div>
</body>
</html>
```

观察页面显示效果：



![img](https:////upload-images.jianshu.io/upload_images/1917785-10e8834f04e59ec3.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)

## 三、视口：

转载[zhangyang33](https://me.csdn.net/u012402190) 发布于2017-04-14 15:07:05 阅读数 86008  收藏

展开

[![img](https://img-blog.csdnimg.cn/20191225111311593.png)](https://blog.csdn.net/csdngkk/article/details/103682497)

简单来说

[meta name="viewport" content="width=device-width,initial-scale=1.0" 解释](http://www.cnblogs.com/yuzhongwusan/p/4184923.html)

 <meta name="viewport" content="width=device-width,initial-scale=1.0">

 

content属性值 :

​     width:可视区域的宽度，值可为数字或关键词device-width

​     height:同width

​     intial-scale:页面首次被显示是可视区域的缩放级别，取值1.0则页面按实际尺寸显示，无任何缩放

​     maximum-scale=1.0, minimum-scale=1.0;可视区域的缩放级别，

​     maximum-scale用户可将页面放大的程序，1.0将禁止用户放大到实际尺寸之上。

​     user-scalable:是否可对页面进行缩放，no 禁止缩放

### 移动前端开发之viewport的深入理解

在移动设备上进行网页的重构或开发，首先得搞明白的就是移动设备上的viewport了，只有明白了viewport的概念以及弄清楚了跟viewport有关的meta标签的使用，才能更好地让我们的网页适配或响应各种不同分辨率的移动设备。

**一、viewport的概念**

通俗的讲，移动设备上的viewport就是设备的屏幕上能用来显示我们的网页的那一块区域，在具体一点，就是浏览器上(也可能是一个app中的webview)用来显示网页的那部分区域，但viewport又不局限于浏览器可视区域的大小，它可能比浏览器的可视区域要大，也可能比浏览器的可视区域要小。在默认情况下，一般来讲，移动设备上的viewport都是要大于浏览器可视区域的，这是因为考虑到移动设备的分辨率相对于桌面电脑来说都比较小，所以为了能在移动设备上正常显示那些传统的为桌面浏览器设计的网站，移动设备上的浏览器都会把自己默认的viewport设为980px或1024px（也可能是其它值，这个是由设备自己决定的），但带来的后果就是浏览器会出现横向滚动条，因为浏览器可视区域的宽度是比这个默认的viewport的宽度要小的。下图列出了一些设备上浏览器的默认viewport的宽度。

[![1](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1ODQ3NTU1NzIxOS5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300958470402077.png)

 

**二、css中的1px并不等于设备的1px**

​    在css中我们一般使用px作为单位，在桌面浏览器中css的1个像素往往都是对应着电脑屏幕的1个物理像素，这可能会造成我们的一个错觉，那就是css中的像素就是设备的物理像素。但实际情况却并非如此，css中的像素只是一个抽象的单位，在不同的设备或不同的环境中，css中的1px所代表的设备物理像素是不同的。在为桌面浏览器设计的网页中，我们无需对这个津津计较，但在移动设备上，必须弄明白这点。在早先的移动设备中，屏幕像素密度都比较低，如iphone3，它的分辨率为320x480，在iphone3上，一个css像素确实是等于一个屏幕物理像素的。后来随着技术的发展，移动设备的屏幕像素密度越来越高，从iphone4开始，苹果公司便推出了所谓的Retina屏，分辨率提高了一倍，变成640x960，但屏幕尺寸却没变化，这就意味着同样大小的屏幕上，像素却多了一倍，这时，一个css像素是等于两个物理像素的。其他品牌的移动设备也是这个道理。例如安卓设备根据屏幕像素密度可分为ldpi、mdpi、hdpi、xhdpi等不同的等级，分辨率也是五花八门，安卓设备上的一个css像素相当于多少个屏幕物理像素，也因设备的不同而不同，没有一个定论。

​    还有一个因素也会引起css中px的变化，那就是用户缩放。例如，当用户把页面放大一倍，那么css中1px所代表的物理像素也会增加一倍；反之把页面缩小一倍，css中1px所代表的物理像素也会减少一倍。关于这点，在文章后面的部分还会讲到。

​    在移动端浏览器中以及某些桌面浏览器中，window对象有一个devicePixelRatio属性，它的官方的定义为：设备物理像素和设备独立像素的比例，也就是 devicePixelRatio = 物理像素 / 独立像素。css中的px就可以看做是设备的独立像素，所以通过devicePixelRatio，我们可以知道该设备上一个css像素代表多少个物理像素。例如，在Retina屏的iphone上，devicePixelRatio的值为2，也就是说1个css像素相当于2个物理像素。但是要注意的是，devicePixelRatio在不同的浏览器中还存在些许的兼容性问题，所以我们现在还并不能完全信赖这个东西，具体的情况可以看下[这篇文章](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)。

devicePixelRatio的测试结果：

[![14](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1ODQ5Njk2MjgzMy5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300958489622990.png)

 

**三、PPK的关于三个viewport的理论**

​    [ppk大神](http://www.quirksmode.org/)对于移动设备上的viewport有着非常多的研究（[第一篇](http://www.quirksmode.org/mobile/viewports.html)，[第二篇](http://www.quirksmode.org/mobile/viewports2.html)，[第三篇](http://www.quirksmode.org/mobile/metaviewport/)），有兴趣的同学可以去看一下，本文中有很多数据和观点也是出自那里。ppk认为，移动设备上有三个viewport。

​    首先，移动设备上的浏览器认为自己必须能让所有的网站都正常显示，即使是那些不是为移动设备设计的网站。但如果以浏览器的可视区域作为viewport的话，因为移动设备的屏幕都不是很宽，所以那些为桌面浏览器设计的网站放到移动设备上显示时，必然会因为移动设备的viewport太窄，而挤作一团，甚至布局什么的都会乱掉。也许有人会问，现在不是有很多手机分辨率都非常大吗，比如768x1024，或者1080x1920这样，那这样的手机用来显示为桌面浏览器设计的网站是没问题的吧？前面我们已经说了，css中的1px并不是代表屏幕上的1px，你分辨率越大，css中1px代表的物理像素就会越多，devicePixelRatio的值也越大，这很好理解，因为你分辨率增大了，但屏幕尺寸并没有变大多少，必须让css中的1px代表更多的物理像素，才能让1px的东西在屏幕上的大小与那些低分辨率的设备差不多，不然就会因为太小而看不清。所以在1080x1920这样的设备上，在默认情况下，也许你只要把一个div的宽度设为300多px（视devicePixelRatio的值而定），就是满屏的宽度了。回到正题上来，如果把移动设备上浏览器的可视区域设为viewport的话，某些网站就会因为viewport太窄而显示错乱，所以这些浏览器就决定默认情况下把viewport设为一个较宽的值，比如980px，这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。ppk把这个浏览器默认的viewport叫做 ***layout viewport**。*这个layout viewport的宽度可以通过document.documentElement.clientWidth 来获取。

​    然而，***layout viewport*** 的宽度是大于浏览器可视区域的宽度的，所以我们还需要一个viewport来代表 浏览器可视区域的大小，ppk把这个viewport叫做 **visual viewport**。visual viewport的宽度可以通过window.innerWidth 来获取，但在Android 2, Oprea mini 和 UC 8中无法正确获取。

[![2](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1ODUyMTY1NTk0NC5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300958506337445.png)      [![3](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1ODU0NzQzNDI1Ni5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300958533834472.png)

​    现在我们已经有两个viewport了：***layout viewport*** 和 ***visual viewport***。但浏览器觉得还不够，因为现在越来越多的网站都会为移动设备进行单独的设计，所以必须还要有一个能完美适配移动设备的viewport。所谓的完美适配指的是，首先不需要用户缩放和横向滚动条就能正常的查看网站的所有内容；第二，显示的文字的大小是合适，比如一段14px大小的文字，不会因为在一个高密度像素的屏幕里显示得太小而无法看清，理想的情况是这段14px的文字无论是在何种密度屏幕，何种分辨率下，显示出来的大小都是差不多的。当然，不只是文字，其他元素像图片什么的也是这个道理。ppk把这个viewport叫做 ***ideal viewport***，也就是第三个viewport——移动设备的理想viewport。

​    ideal viewport并没有一个固定的尺寸，不同的设备拥有有不同的ideal viewport。所有的iphone的ideal viewport宽度都是320px，无论它的屏幕宽度是320还是640，也就是说，在iphone中，css中的320px就代表iphone屏幕的宽度。

[![4](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1ODU2MzY4MzcyNi5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300958560242000.png)          [![5](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1ODU3MDg3OTM0MC5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300958567274384.png)

但是安卓设备就比较复杂了，有320px的，有360px的，有384px的等等，关于不同的设备ideal viewport的宽度都为多少，可以到[http://viewportsizes.com](http://viewportsizes.com/)去查看一下，里面收集了众多设备的理想宽度。

​    再总结一下：ppk把移动设备上的viewport分为***layout viewport***  、 ***visual viewport***   和 ***ideal viewport***  三类，其中的ideal viewport是最适合移动设备的viewport，ideal viewport的宽度等于移动设备的屏幕宽度，只要在css中把某一元素的宽度设为ideal viewport的宽度(单位用px)，那么这个元素的宽度就是设备屏幕的宽度了，也就是宽度为100%的效果。ideal viewport 的意义在于，无论在何种分辨率的屏幕下，那些针对ideal viewport 而设计的网站，不需要用户手动缩放，也不需要出现横向滚动条，都可以完美的呈现给用户。

 

**四、利用meta标签对viewport进行控制**

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

我们在开发移动设备的网站时，最常见的的一个动作就是把下面这个东西复制到我们的head标签中：

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

该meta标签的作用是让当前viewport的宽度等于设备的宽度，同时不允许用户手动缩放。也许允不允许用户缩放不同的网站有不同的要求，但让viewport的宽度等于设备的宽度，这个应该是大家都想要的效果，如果你不这样的设定的话，那就会使用那个比屏幕宽的默认viewport，也就是说会出现横向滚动条。

这个name为viewport的meta标签到底有哪些东西呢，又都有什么作用呢？

meta viewport 标签首先是由苹果公司在其safari浏览器中引入的，目的就是解决移动设备的viewport问题。后来安卓以及各大浏览器厂商也都纷纷效仿，引入对meta viewport的支持，事实也证明这个东西还是非常有用的。

在苹果的规范中，meta viewport 有6个属性(暂且把content中的那些东西称为一个个属性和值)，如下：

| width         | 设置***layout viewport***  的宽度，为一个正整数，或字符串"width-device" |
| ------------- | ------------------------------------------------------------ |
| initial-scale | 设置页面的初始缩放值，为一个数字，可以带小数                 |
| minimum-scale | 允许用户的最小缩放值，为一个数字，可以带小数                 |
| maximum-scale | 允许用户的最大缩放值，为一个数字，可以带小数                 |
| height        | 设置***layout viewport***  的高度，这个属性对我们并不重要，很少使用 |
| user-scalable | 是否允许用户进行缩放，值为"no"或"yes", no 代表不允许，yes代表允许 |

这些属性可以同时使用，也可以单独使用或混合使用，多个属性同时使用时用逗号隔开就行了。

此外，在安卓中还支持  target-densitydpi  这个私有属性，它表示目标设备的密度等级，作用是决定css中的1px代表多少物理像素

| target-densitydpi | 值可以为一个数值或 high-dpi 、 medium-dpi、 low-dpi、 device-dpi 这几个字符串中的一个 |
| ----------------- | ------------------------------------------------------------ |
|                   |                                                              |

特别说明的是，当 target-densitydpi=device-dpi 时， css中的1px会等于物理像素中的1px。

因为这个属性只有安卓支持，并且安卓已经决定要废弃target-densitydpi  这个属性了，所以这个属性我们要避免进行使用  。

 

**五、把当前的viewport宽度设置为 ideal viewport 的宽度**

要得到ideal viewport就必须把默认的layout viewport的宽度设为移动设备的屏幕宽度。因为meta viewport中的width能控制layout viewport的宽度，所以我们只需要把width设为width-device这个特殊的值就行了。

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

下图是这句代码在各大移动端浏览器上的测试结果：

[![6](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1ODU3ODA1NTk1NC5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300958574153540.png)

可以看到通过width=device-width，所有浏览器都能把当前的viewport宽度变成ideal viewport的宽度，但要注意的是，在iphone和ipad上，无论是竖屏还是横屏，宽度都是竖屏时ideal viewport的宽度。

这样的写法看起来谁都会做，没吃过猪肉，谁还没见过猪跑啊~，确实，我们在开发移动设备上的网页时，不管你明不明白什么是viewport，可能你只需要这么一句代码就够了。

可是你肯定不知道

```html
<meta name="viewport" content="initial-scale=1">
```

这句代码也能达到和前一句代码一样的效果，也可以把当前的的viewport变为 ideal viewport。

呵呵，傻眼了吧，因为从理论上来讲，这句代码的作用只是不对当前的页面进行缩放，也就是页面本该是多大就是多大。那为什么会有 width=device-width 的效果呢？

要想清楚这件事情，首先你得弄明白这个缩放是相对于什么来缩放的，因为这里的缩放值是1，也就是没缩放，但却达到了 ideal viewport 的效果，所以，那答案就只有一个了，缩放是相对于 ideal viewport来进行缩放的，当对ideal viewport进行100%的缩放，也就是缩放值为1的时候，不就得到了 ideal viewport吗？事实证明，的确是这样的。下图是各大移动端的浏览器当设置了<meta name="viewport" content="initial-scale=1"> 后是否能把当前的viewport宽度变成 ideal viewport 的宽度的测试结果。

[![7](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1ODU5NzEyMzYzOS5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300958592749939.png)

测试结果表明 initial-scale=1 也能把当前的viewport宽度变成 ideal viewport 的宽度，但这次轮到了windows phone 上的IE 无论是竖屏还是横屏都把宽度设为竖屏时ideal viewport的宽度。但这点小瑕疵已经无关紧要了。

但如果width 和 initial-scale=1同时出现，并且还出现了冲突呢？比如：

```html
<meta name="viewport" content="width=400, initial-scale=1">
```

width=400表示把当前viewport的宽度设为400px，initial-scale=1则表示把当前viewport的宽度设为ideal viewport的宽度，那么浏览器到底该服从哪个命令呢？是书写顺序在后面的那个吗？不是。当遇到这种情况时，浏览器会取它们两个中较大的那个值。例如，当width=400，ideal viewport的宽度为320时，取的是400；当width=400， ideal viewport的宽度为480时，取的是ideal viewport的宽度。（ps:在uc9浏览器中，当initial-scale=1时，无论width属性的值为多少，此时viewport的宽度永远都是ideal viewport的宽度）

最后，总结一下，要把当前的viewport宽度设为ideal viewport的宽度，既可以设置 width=device-width，也可以设置 initial-scale=1，但这两者各有一个小缺陷，就是iphone、ipad以及IE 会横竖屏不分，通通以竖屏的ideal viewport宽度为准。所以，最完美的写法应该是，两者都写上去，这样就 initial-scale=1 解决了 iphone、ipad的毛病，width=device-width则解决了IE的毛病：

```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```

 

**六、关于meta viewport的更多知识**

**1、关于缩放以及initial-scale的默认值**

​    首先我们先来讨论一下缩放的问题，前面已经提到过，缩放是相对于ideal viewport来缩放的，缩放值越大，当前viewport的宽度就会越小，反之亦然。例如在iphone中，ideal viewport的宽度是320px，如果我们设置 initial-scale=2 ，此时viewport的宽度会变为只有160px了，这也好理解，放大了一倍嘛，就是原来1px的东西变成2px了，但是1px变为2px并不是把原来的320px变为640px了，而是在实际宽度不变的情况下，1px变得跟原来的2px的长度一样了，所以放大2倍后原来需要320px才能填满的宽度现在只需要160px就做到了。因此，我们可以得出一个公式：

```html
visual viewport宽度 = ideal viewport宽度  / 当前缩放值



 



当前缩放值 = ideal viewport宽度  / visual viewport宽度
```

​    ps: visual viewport的宽度指的是浏览器可视区域的宽度。

​    大多数浏览器都符合这个理论，但是安卓上的原生浏览器以及IE有些问题。安卓自带的webkit浏览器只有在 initial-scale = 1 以及没有设置width属性时才是表现正常的，也就相当于这理论在它身上基本没用；而IE则根本不甩initial-scale这个属性，无论你给他设置什么，initial-scale表现出来的效果永远是1。

​    好了，现在再来说下initial-scale的默认值问题，就是不写这个属性的时候，它的默认值会是多少呢？很显然不会是1，因为当 initial-scale = 1 时，当前的layout viewport宽度会被设为 ideal viewport的宽度，但前面说了，各浏览器默认的 layout viewport宽度一般都是980啊，1024啊，800啊等等这些个值，没有一开始就是 ideal viewport的宽度的，所以 initial-scale的默认值肯定不是1。安卓设备上的initial-scale默认值好像没有方法能够得到，或者就是干脆它就没有默认值，一定要你显示的写出来这个东西才会起作用，我们不管它了，这里我们重点说一下iphone和ipad上的initial-scale默认值。

   根据测试，我们可以在iphone和ipad上得到一个结论，就是无论你给layout viewpor设置的宽度是多少，而又没有指定初始的缩放值的话，那么iphone和ipad会自动计算initial-scale这个值，以保证当前layout viewport的宽度在缩放后就是浏览器可视区域的宽度，也就是说不会出现横向滚动条。比如说，在iphone上，我们不设置任何的viewport meta标签，此时layout viewport的宽度为980px，但我们可以看到浏览器并没有出现横向滚动条，浏览器默认的把页面缩小了。根据上面的公式，当前缩放值 = ideal viewport宽度  / visual viewport宽度，我们可以得出：

​      当前缩放值 = 320 / 980

也就是当前的initial-scale默认值应该是 0.33这样子。当你指定了initial-scale的值后，这个默认值就不起作用了。

总之记住这个结论就行了：**在iphone和ipad上，无论你给viewport设的宽的是多少，如果没有指定默认的缩放值，则iphone和ipad会自动计算这个缩放值，以达到当前页面不会出现横向滚动条(或者说viewport的宽度就是屏幕的宽度)的目的。**

[![11](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1OTAwNTg3NDczOC5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300959001492039.png)    [![12](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1OTAyNDMwNzkwOC5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300959019771981.png)     [![13](https://imgconvert.csdnimg.cn/aHR0cDovL2ltYWdlcy5jbml0YmxvZy5jb20vYmxvZy8xMzA2MjMvMjAxNDA3LzMwMDk1OTAzMTE4NzA2NC5wbmc?x-oss-process=image/format,png)](http://images.cnitblog.com/blog/130623/201407/300959028057093.png)

 

**2、动态改变meta viewport标签**

第一种方法

可以使用document.write来动态输出meta viewport标签，例如：

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

第二种方法

通过setAttribute来改变 

```html
<meta id="testViewport" name="viewport" content="width = 380">



<script>



var mvp = document.getElementById('testViewport');



mvp.setAttribute('content','width=480');



</script>
```

 

 

安卓2.3自带浏览器上的一个bug

![复制代码](https://imgconvert.csdnimg.cn/aHR0cDovL2NvbW1vbi5jbmJsb2dzLmNvbS9pbWFnZXMvY29weWNvZGUuZ2lm)

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



 



<script type="text/javascript">



alert(document.documentElement.clientWidth); //弹出600，正常情况应该弹出320



</script>

<meta name="viewport" content="width=600">
<script type="text/javascript">
alert(document.documentElement.clientWidth); //弹出320，正常情况应该弹出600

</script>
```

![复制代码](https://imgconvert.csdnimg.cn/aHR0cDovL2NvbW1vbi5jbmJsb2dzLmNvbS9pbWFnZXMvY29weWNvZGUuZ2lm)

测试的手机ideal viewport 宽度为320px，第一次弹出的值是600,但这个值应该是第行meta标签的结果啊，然后第二次弹出的值是320，这才是第一行meta标签所达到的效果啊，所以在安卓2.3(或许是所有2.x版本中)的自带浏览器中，对meta viewport标签进行覆盖或更改，会出现让人非常迷糊的结果。

 

**七、结语**

说了那么多废话，最后还是有必要总结一点有用的出来。

首先如果不设置meta viewport标签，那么移动设备上浏览器默认的宽度值为800px，980px，1024px等这些，总之是大于屏幕宽度的。这里的宽度所用的单位px都是指css中的px，它跟代表实际屏幕物理像素的px不是一回事。

第二、每个移动设备浏览器中都有一个理想的宽度，这个理想的宽度是指css中的宽度，跟设备的物理宽度没有关系，在css中，这个宽度就相当于100%的所代表的那个宽度。我们可以用meta标签把viewport的宽度设为那个理想的宽度，如果不知道这个设备的理想宽度是多少，那么用device-width这个特殊值就行了，同时initial-scale=1也有把viewport的宽度设为理想宽度的作用。所以，我们可以使用

```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```

来得到一个理想的viewport（也就是前面说的ideal viewport）

为什么需要有理想的viewport呢？比如一个分辨率为320x480的手机理想viewport的宽度是320px，而另一个屏幕尺寸相同但分辨率为640x960的手机的理想viewport宽度也是为320px，那为什么分辨率大的这个手机的理想宽度要跟分辨率小的那个手机的理想宽度一样呢？这是因为，只有这样才能保证同样的网站在不同分辨率的设备上看起来都是一样或差不多的。实际上，现在市面上虽然有那么多不同种类不同品牌不同分辨率的手机，但它们的理想viewport宽度归纳起来无非也就 320、360、384、400等几种，都是非常接近的，理想宽度的相近也就意味着我们针对某个设备的理想viewport而做出的网站，在其他设备上的表现也不会相差非常多甚至是表现一样的。



## 四、媒体查询

```
媒体指的就是各种设备 (移动设备, PC设备)
查询指的是要检测属于哪种设备
媒体查询: 通过查询当前属于哪种设备, 让网页能够在不同的设备下正常的预览

复制代码
```

学习媒体查询的核心是什么?

```
实现页面在不同设备下正常预览 [判断当前设备]
```

媒体类型

```
将不同的设备划分为不同的类型
all (所有的设备)
print (打印设备)
screen (电脑屏幕,平板电脑,智能手机)
复制代码
```

媒体特性

```
用来描述设备的特点,比如宽度,高度...
```

- width	网页显示区域完全等于设置的宽度
- height 网页显示区域完全等于设置的高度
- max-width / max-height 网页显示区域小于等于设置的宽度
- min-width / min-width 网页显示区域大于等于设置的宽度
- orientation: portrait (竖屏模式) | landscape (横屏模式)

语法关键字

```
目的将媒体类型和媒体特性链接到一块,进行设备检测
```

- and	可以将多个媒体特性链接到一块,相当于且
- not 排除某个媒体特性 相当于非,可以省略
- only 指定某个特定的媒体类型, 可以省略

语法



- 外联式语法

```
<link rel="stylesheet" type="text/css" href="01.css" media="only screen and (max-width: 420px)">
```

- 内嵌式语法

```
  @media only screen  and (max-width: 420px) {
      	body {
      		background-color: red;
      	}
      }
      
      备注: 多个条件联写
      @media only screen and (width: 320px) and (height: 568px) {}

```

**媒介类型**

　　在CSS2中，媒体查询只使用于<style>和<link>标签中，以media属性存在

　　media属性用于为不同的媒介类型规定不同的样式

**screen         计算机屏幕（默认值）    tty            电传打字机以及使用等宽字符网格的类似媒介tv             电视类型设备（低分辨率、有限的屏幕翻滚能力）projection     放映机handheld       手持设备（小屏幕、有限的带宽）print          打印预览模式 / 打印页braille        盲人用点字法反馈设备aural          语音合成器all            适合所有设备**

　　真正广泛使用且所有浏览器都兼容的媒介类型是'screen'和'all'

```
<style media="screen">
.box{height: 100px;width: 100px; background-color: lightblue;}   
</style>
<div class="box"></div>
```

  **媒体属性**

　　媒体属性是CSS3新增的内容，多数媒体属性带有“min-”和“max-”前缀，用于表达“小于等于”和“大于等于”。这避免了使用与HTML和XML冲突的“<”和“>”字符

　　[注意]媒体属性必须用括号()包起来，否则无效

　　下表中列出了所有的媒体属性

​     **width | min-width | max-width     height | min-height | max-height     device-width | min-device-width | max-device-width     device-height | min-device-height | max-device-height     aspect-ratio | min-aspect-ratio | max-aspect-ratio     device-aspect-ratio | min-device-aspect-ratio | max-device-aspect-ratio     color | min-color | max-color     color-index | min-color-index | max-color-index     monochrome | min-monochrome | max-monochrome     resolution | min-resolution | max-resolution     scan | grid**

**【1】颜色（color）**

　　指定输出设备每个像素单元的比特值。如果设备不支持输出颜色，则该值为0

　　向所有能显示颜色的设备应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (color){
    .box{height: 100px;width: 100px;background-color: lightblue;}   
}   
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【2】颜色索引（color-index）**

　　颜色索引指定了输出设备中颜色查询表中的条目数量，如果没有使用颜色查询表，则值等于0

　　向所有使用至少256个索引颜色的设备应用样式表(下列代码无显示，说明返回值为0)

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (min-color-index: 256){
    .box{height: 100px; width: 100px;background-color: lightgreen;}   
}   
</style>   
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【3】宽高比（aspect-ratio）**

　　宽高比描述了输出设备目标显示区域的宽高比。该值包含两个以“/”分隔的正整数。代表了水平像素数（第一个值）与垂直像素数（第二个值）的比例

　　向可视区域是正方形或者是宽屏的设备应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (min-aspect-ratio: 1/1) {
    .box{height: 100px;width: 100px; background-color: lightgreen; }       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【4】设备宽高比（device-aspect-ratio）**

　　设备宽高比描述了输出设备的宽高比。该值包含两个以“/”分隔的正整数。代表了水平像素数（第一个值）与垂直像素数（第二个值）的比例

　　向宽高比为16:9的特殊宽屏设备应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (device-aspect-ratio:16/9) {
    .box{ height: 100px;width: 100px; background-color: pink;}       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【5】设备高度（device-height）**

　　设备高度描述了输出设备的高度

　　向显示在最小高度1000px的屏幕上的文档应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (min-device-height: 1000px) {
    .box{ height: 100px;width: 100px; background-color: pink;}       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【6】设备宽度（device-width）**

　　设备宽度描述了输出设备的宽度

　　向显示在最小宽度1000px的屏幕上的文档应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (min-device-width: 1000px) {
    .box{ height: 100px; width: 100px;background-color: lightblue; }       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【7】网格（grid）**

　　网格判断输出设备是网格设备还是位图设备。如果设备是基于网格的（例如电传打字机终端或只能显示一种字形的电话），该值为1，否则为0　　

　　向非网格设备应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (grid:0) {
    .box{height: 100px;width: 100px; background-color: lightgreen;}       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【8】高度（height）**

　　高度描述了输出设备渲染区域（如可视区域的高度或打印机纸盒的高度）的高度

　　向高度大于800px的可视区域的设备应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (min-height:800px) {
    .box{ height: 100px; width: 100px;background-color: lightgreen; }       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【9】宽度（width）**

　　宽度描述了输出设备渲染区域的宽度

　　向宽度大于800px的可视区域的设备应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (min-width:800px) {
    .box{ height: 100px;width: 100px; background-color: lightgreen;}       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【10】黑白（monochrome）**

　　黑白指定了一个黑白（灰度）设备每个像素的比特数。如果不是黑白设备，值为0

　　向非黑白设备应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (monochrome:0) {
    .box{height: 100px; width: 100px; background-color: lightgreen;}       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【11】方向（orientation）**

　　方向指定了设备处于横屏（宽度大于宽度）模式还是竖屏（高度大于宽度）模式

　　值：landscape(横屏) | portrait(竖屏)

　　向竖屏设备应用样式表

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (orientation: portrait) {
    .box{height: 100px;width: 100px;background-color: lightgreen; }       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【12】分辨率（resolution）**

　　分辨率指定输出设备的分辨率（像素密度）。分辨率可以用每英寸（dpi）或每厘米（dpcm）的点数来表示

　　[注意]关于屏幕三要素(屏幕尺寸、分辨率、像素密度)的相关内容移步至此

　　向每英寸至少90点的设备应用样式

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<style>
@media (min-resolution: 90dpi) {
    .box{height: 100px;width: 100px; background-color: lightgreen; }       
}
</style>
<div class="box"></div>
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**【13】扫描（scan）**

　　扫描描述了电视输出设备的扫描过程

　　值： progressive | interlace

**语法**

　　媒体查询包含了一个CSS2已有的媒介类型(或称为媒体类型)和CSS3新增的包含一个或多个表达式的媒体属性，这些媒体属性会被解析成真或假

　　当媒体查询为真时，相关的样式表或样式规则就会按照正常的级联规则被应用。即使媒体查询返回假， <link> 标签上带有媒体查询的样式表仍将被下载（只不过不会被应用）

```
<link rel="stylesheet" href="style.css" media="print">

<div class="box"></div> 
```

　　media并不是'print'，所以媒体查询为假。但是，style.css文件依然被下载

![img](https://files.jb51.net/file_images/article/201708/201781593954924.jpg?201771594029)

**逻辑操作符**

　　操作符not、and、only和逗号(,)可以用来构建复杂的媒体查询

**and**

　　and操作符用来把多个媒体属性组合起来，合并到同一条媒体查询中。只有当每个属性都为真时，这条查询的结果才为真

　　[注意]在不使用not或only操作符的情况下，媒体类型是可选的，默认为all

　　满足横屏以及最小宽度为700px的条件应用样式表

```
@media all and (min-width: 700px) and (orientation: landscape) { ... }
```

　　由于不使用not或only操作符的情况下，媒体类型是可选的，默认为 all，所以可以简写为

```
@media (min-width: 700px) and (orientation: landscape) { ... }
```

**or**

　　将多个媒体查询以逗号分隔放在一起；只要其中任何一个为真，整个媒体语句就返回真，相当于or操作符

　　满足最小宽度为700像素或是横屏的手持设备应用样式表

```
@media (min-width: 700px), handheld and (orientation: landscape) { ... }
```

**not**

　　not操作符用来对一条媒体查询的结果进行取反

　　[注意]not关键字仅能应用于整个查询，而不能单独应用于一个独立的查询



**only**

　　only操作符表示仅在媒体查询匹配成功时应用指定样式。可以通过它让选中的样式在老式浏览器中不被应用

```
media="only screen and (max-width:1000px)"{...}
```

　　上面这行代码，在老式浏览器中被解析为media="only"，因为没有一个叫only的设备，所以实际上老式浏览器不会应用样式

```
media="screen and (max-width:1000px)"{...}
```

　　上面这行代码，在老式浏览器中被解析为media="screen"，它把后面的逻辑表达式忽略了。所以老式浏览器会应用样式

　　所以，在使用媒体查询时，only最好不要忽略

**方法**

　　window.matchMedia()方法用来检查CSS的mediaQuery语句

　　[注意]IE9-浏览器不支持，可以使用第三方函数库matchMedia.js

**属性**

　　window.matchMedia()方法接受一个mediaQuery语句的字符串作为参数，返回一个MediaQueryList对象。该对象有media和matches两个属性

**media：返回所查询的mediaQuery语句字符串matches：返回一个布尔值，表示当前环境是否匹配查询语句**

```
var result = window.matchMedia('(min-width: 600px)');
console.log(result.media); //'(min-width: 600px)'
console.log(result.matches); // true
```

　　可以根据matchMedia()方法的matches属性的不同结果，进行对应的设置

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
var result = window.matchMedia('(min-width: 600px)');
if (result.matches) {
  //
}else{
 //
}
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

　　[注意]如果window.matchMedia无法解析mediaQuery参数，matches属性返回的总是false，而不是报错

```
var result = window.matchMedia('123');
console.log(result.matches);//false
```

**事件**

　　window.matchMedia方法返回的MediaQueryList对象有两个方法，用来监听事件：addListener方法和removeListener方法

```
// 指定回调函数
mql.addListener(mqCallback);
// 撤销回调函数
mql.removeListener(mqCallback);
```

　　注意，只有mediaQuery查询结果发生变化时，才调用指定的回调函数

　　所以，如果想要mediaQuery查询未变化时，就显示相应效果，需要提前调用一次函数

　　下面这个例子是当页面宽度小于1000px时，页面背景颜色为品红色；否则为淡蓝色

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
var mql = window.matchMedia("(min-width: 1000px)");
mqCallback(mql);
mql.addListener(mqCallback);
function mqCallback(mql) {
  if (mql.matches) {
    document.body.background = 'pink';
  }else{
      document.body.background = 'lightblue';
  }
}
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**打印样式**

　　媒体查询的一个常用功能是打印样式的设置，主要是背景清除、字体颜色变黑等

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
@media print{
    *,*:before,*:after{
        background:transparent!important;
        color:#000 !important;
        box-shadow: none !important;
        text-shadow: none !important;
    }
    a,a:visited{
        text-decoration: underline;
    }
    a[href]:after{
        content:"(" attr(href) ")";
    }
    abbr[title]:after{
        content:"(" attr(title) ")";
    }
    a[href^="#"]:after,a[href^="javascript:;"]:after{
        content:"";
    }
    pre,blockquote{
        border: 1px solid #999;
        /*只有opera浏览器起作用，避免在元素内部插入分页符*/
        page-break-inside:avoid;
    }
    thead{
        display:table-header-group;
    }
    tr,img{
        page-break-inside:avoid;
    }
    img{
        max-width:100%!important;
    }
    p,h2,h3{
        /*元素内部发生分页时，最少保留3行*/
        orphans:3;
        /*元素内部发生分页时，元素顶部最少保留3行*/
        windows:3;
    }
    h2,h3{
        /*避免在元素后面插入一个分页符*/
        page-break-after:avoid;
    }
}
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

**相对单位**

　　如果媒体查询@media使用的是相对单位，如rem，这里有一个坑需要着重强调一下

　　一般而言，rem是相对于HTML的字体大小的。但是，由于媒体查询的级别非常高，它并不是HTML的子元素，不是相对于HTML，而是相对于浏览器的，而浏览器的默认字体大小是16px

　　如果HTML设置字体大小为12px，设置如下媒体查询

```
media="only screen and (max-width:1rem)"
```

　　实际上，max-width等于16px，而不是12px

　　而正是由于媒体查询是相对于浏览器的， 所以使用rem就没有必要，完全可以使用em来替代

```
media="only screen and (max-width:1em)"
```

媒体查询多用于响应式网页中。

1.初始化设置：

在HTML文件中，网页顶部<head></head>标签中插入一句话：

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

 

这句话在于对响应式网页做一个初始化设置，主要包括：

name="viewport"：标记显示设备为视口；

width = device-width：宽度等于当前设备的宽度；

initial-scale：初始的缩放比例（默认设置为1.0）；
minimum-scale：允许用户缩放到的最小比例（默认设置为1.0）；
maximum-scale：允许用户缩放到的最大比例（默认设置为1.0）；   
user-scalable：用户是否可以手动缩放（默认设置为no，因为我们不希望用户放大缩小页面）。

 

2.解决IE浏览器的兼容性问题：

因为IE浏览器(IE8)不支持HTML5和CSS3中的media，所以要加载用于解决IE浏览器兼容性问题的JS文件：

 

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
<!--[if lt IE 9]>

<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>

<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>

<![endif]-->
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

 

两个<script></script>标签中的src属性所指向的文件链接地址为固定地址中的文件，直接异地引用就好，不用下载到本地引用。

3.设置IE的渲染方式为最高：

现在有很多人的IE浏览器都升级到IE9以上，这个时候会有很多诡异的事情发生，例如现在是IE9的浏览器，但是浏览器的文档模式却是IE8，为了防止这种情况，我们需要下面这段代码来让IE的文档模式永远都是最新：

 

```
<meta http-equiv="X-UA-Compatible"content="IE=edge">
```

 

当然还有一个更给力的写法：

 

```
<meta http-equiv="X-UA-Compatible"content="IE=Edge，chrome=1">
```

 

这段代码后面加了一个chrome=1，这是由于Google Chrome Frame（谷歌内嵌浏览器框架GCF），如果用户电脑安装这个chrome插件，就可让电脑内的IE浏览器规避版本因素，使用Webkit引擎及V8引擎进行排版及运算。当然如果用户没装这个插件，这段代码就会让IE浏览器以最高的文档模式展现效果。

4.CSS3 media 媒体查询的写法：

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
@media screen and (max-width: 960px){

body{

background:#000;

}

}
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

 

这是一个media的标准写法，在CSS文件中，意为：当页面小于960px时执行以下CSS代码，具体内容暂不用管。

对于上述代码中的screen，意为在告知设备在打印页面时使用衬线字体，在屏幕上显示时用无衬线字体。目前很多网站都会直接省略screen,从而不需要考虑用户打印网页的需求，所以又有这种写法：

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
@media (max-width: 960px){

body{

background:#000;

}

}
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

 

本着思维严谨的原则，个人不会采用这种写法。

5.CSS3媒体查询主体代码组合：

 

在响应式网页布局中需要持续运用媒体查询代码组合，主要作用在于判断所适配屏幕的宽度，并根据各种宽度条件套用不同的CSS样式。

如当屏幕宽度等于960px时，将网页背景色变为红色：

 

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
@media screen and (max-device-width:960px){

body{

background:red;

}

} 
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

如当屏幕宽度最大为960px（小于960px）时，将网页背景色变为黑色：

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
@media screen and (max-width: 960px){

     body{

        background:#000;

    }

}    
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

如当屏幕宽度最小为960px（大于960px）时，将网页背景色变为桔色：

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
@media screen and (min-width:960px){

    body{

        background:orange;

    }

}    
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

更为常见的是混合使用，如当屏幕宽度介于960px和1200px之间时，将网页背景色变为黄色：

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

```
@media screen and (min-width:960px) and(max-width:1200px){
　　body{

　　　　background:yellow;

　　}
}
```

[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)

6.总体开发思路：

 

使用CSS3中媒体查询的大致思路就是判断网页在不同设备中所处的宽度范围，这样的范围可能有三种（PC、平板、手机），也可能有四种（PC、平板、中大屏手机、小屏手机），当然也可能只需要两种（平板、手机，PC端单独开发一版时可不作为CSS3媒体查询的使用对象），并为各种宽度范围情况下的所需页面元素套用不同的CSS样式，从而适配各种设备。

7.响应式网页开发中的宽度问题：

在实际开发中，通常需要设置响应式网页宽度的最大值，一旦忽略最大宽度，臃肿或零散的网页布局都会造成视觉洪灾，也就是我们常说的看起来很low。
另外谈谈目前显示设备中的网页宽度问题（由于篇幅问题，就不从工业革命开始扯了），目前最为常见的宽度基本上都是：大于或等于960px的PC端（1920px、1600px、1440px、1280px、1140px、960px）、960px至640px之间的平板端（768px、640px）以及640px以下的手机端（480px、320px），以上宽度存在已久，且显示设备中的网页宽度会长期处于这样的状态下，在响应式网页宽度设计上，基本从这几个尺寸考虑就已经足够。

@media screen and (min-width:1200px){ ... }/* 大型设备（大台式电脑，1200px 起） */

@media screen and (min-width:992px){ ... }/* 中型设备（台式电脑，992px 起） */

@media screen and (min-width:768px) { ... } /* 小型设备（平板电脑，768px 起） */

@media screen and (min-width:480px){ ... }/* 超小设备（手机，小于 768px） */
————————————————


媒体查询器中还包含并不常用的相关功能，悉如示下：

 

- width:浏览器可视宽度，
- height:浏览器可视高度，
- device-width:设备屏幕的宽度，
- device-height:设备屏幕的高度，
- orientation:检测设备目前处于横向还是纵向状态，
- aspect-ratio:检测浏览器可视宽度和高度的比例(例如：aspect-ratio:16/9)，
- device-aspect-ratio:检测设备的宽度和高度的比例，
- color:检测颜色的位数（例如：min-color:32就会检测设备是否拥有32位颜色），
- color-index:检查设备颜色索引表中的颜色（他的值不能是负数），
- monochrome:检测单色楨缓冲区域中的每个像素的位数（这个太高级，估计咱很少会用的到），
- resolution:检测屏幕或打印机的分辨率(例如：min-resolution:300dpi或min-resolution:118dpcm)，
- grid：检测输出的设备是网格的还是位图设备。

9.扩展——在CSS2中同样有媒体查询：

 

 

media媒体查询并不是CSS3诞生之后的专用功能，早在CSS2开始就已经支持media，比如：

在HTML文件中的<head></head>标签中写入这句：

 

<link rel="stylesheet"type="text/css" media="screen"href="style.css">

以上是CSS2实现的衬线用法，href属性中写入在某单一显示设备中链接的CSS文件，但仅供入门，

如要判断移动设备是否为纵向放置的显示屏，可以这样写：

 

<link rel="stylesheet" type="text/css"media="screen and (orientation:portrait)"href="style.css">

如要让小于960px的页面执行指定的CSS样式文件，可以这样写：

 

<link rel="stylesheet"type="text/css" media="screen and (max-width:960px)"href="style.css">

当然，CSS2中的媒体查询方法放到现在并不推荐使用，最大的弊端在于这样会增加页面http的请求次数，增加页面负担，使用CSS3中的媒体查询才是目前的最佳方法。

## **五、百分比布局**

通过百分比单位，可以使得浏览器中组件的宽和高随着浏览器的高度的变化而变化，从而实现响应式的效果。Bootstrap里面的栅格系统就是利用百分比来定义元素的宽高，CSS3支持最大最小高，可以将百分比和max(min)一起结合使用来定义元素在不同设备下的宽高。

子元素的height或width中使用百分比，是相对于子元素的直接父元素，width相对于父元素的width，height相对于父元素的height；子元素的top和bottom如果设置百分比，则相对于直接非static定位(默认定位)的父元素的高度，同样子元素的left和right如果设置百分比，则相对于直接非static定位(默认定位的)父元素的宽度；子元素的padding如果设置百分比，不论是垂直方向或者是水平方向，都相对于直接父亲元素的width，而与父元素的height无关。跟padding一样，margin也是如此，子元素的margin如果设置成百分比，不论是垂直方向还是水平方向，都相对于直接父元素的width；border-radius不一样，如果设置border-radius为百分比，则是相对于自身的宽度，除了border-radius外，还有比如translate、background-size等都是相对于自身的；

从上述对于百分比单位的介绍我们很容易看出如果全部使用百分比单位来实现响应式的布局，有明显的以下两个缺点：

计算困难，如果我们要定义一个元素的宽度和高度，按照设计稿，必须换算成百分比单位。

各个属性中如果使用百分比，相对父元素的属性并不是唯一的。比如width和height相对于父元素的width和height，而margin、padding不管垂直还是水平方向都相对比父元素的宽度、border-radius则是相对于元素自身等等，造成我们使用百分比单位容易使布局问题变得复杂。

