一、响应式Web设计基础
响应式Web设计可以让一个网站同时适配多种设备和多个屏幕,可以让网站的布局和功能随用户的使用环境(屏幕大小、输入方式、设备/浏览器能力)而变化。(弹性布局、弹性图片、媒体查询)
1、什么是响应式Web设计
所谓响应式Web设计,就是网页内容会随着访问它的视口及设备的不同而呈现不同的样式。
2、视口
(1)浏览器中用于呈现网页的区域叫视口。视口通常并不等于屏幕大小,特别是可以缩放浏览器窗口的情况下。
(2)<meta name="viewport" content="width=device-width">
这个视口的<meta>标签是一种非标准的(但却是事实标准的)方式,它告诉浏览器怎么渲染网页。在这里,<meta>标签想表达的意思是:按照设备的宽度(device-width)来渲染网页内容。
3、max-width
img{
max-width:100%;
}
给图片绑定该样式,就是要保证所有图片最大显示为其自身的100%(即最大只可以显示为自身那么大)。此时,如果包含图片的元素(比如包含图片的body或div)比图片固有宽度小,图片就会缩放占满最大可用空间。
二、媒体查询
(1)利用媒体查询,可以根据设备的能力应用特定的CSS样式。比如,可以根据视口宽度、屏幕宽高比和朝向(水平还是垂直)等,只用几行CSS代码就改变内容的显示方式。
(2)媒体查询得到了广泛实现。除了古老的IE(8及一下版本),几乎所有浏览器都支持它。
(3)CSS3媒体查询可以让我们针对特定的设备能力或条件为网页应用特定的CSS样式。
(4)官方给媒体查询下的定义:
媒体查询包含媒体类型和零个或多个检测媒体特性的表达式。width、height和color都是可用于媒体查询的特性。使用媒体查询,可以不必修改内容本身,而让网页适配不同的设备。
-
媒体查询的语法
(1)在link标签中使用媒体查询
从CSS2开始接触CSS的读者都知道,可以在标签的media属性中指定设备类型 (screen或print),为不同设备应用样式表。
<link rel="style sheet" type="text/css" media="screen" href="screenstyles.css">
媒体查询更进一步,不仅可以指定设备类型,还能指定设备的能力和特性。
<link rel="stylesheet" media="screen and (orientation: portrait)" href="portrait-screen.css" />
样式表portrait-screen.css会应用给任何有屏幕且屏幕方向垂直的设备,而不符合这两个条件的设备则不会获得其样式。
如果在媒体查询表达式的开头添加一个not,就可以把询问的条件反过来。
<link rel="stylesheet" media="not screen and (orientation: portrait)" href="portrait-screen.css" />
该样式表应用给垂直朝向的非屏幕设备
(2)组合媒体查询
可以将多个媒体查询串在一起。对于上面的例子,可以进一步限制只把样式表应用给视口大于800像素的设备:
<link rel="stylesheet" media="screen and (orientation: portrait) and (min-width: 800px)" href="800wide-portrait-screen.css" />
此外,可以组合多个媒体查询。只要其中任何一个媒体查询表达式为真,就会应用样式;如果没有一个为真,则样式表没用。
<link rel="stylesheet" media="screen and (orientation: portrait) and (min-width: 800px), projection" href="800wide-portrait-screen.css" />
1、逗号分隔每个媒体查询表达式。
2、在projection(投影机)之后没有仍和特征/值对。这样省略特定的特性。表示适用于具备任何特性的该媒体类型。在这里表示可以适用于仍和投影机。
3、任何CSS长度单位都可以用来指定媒体查询的条件。像素(px)是最常用的,而em或rem也都可以用。假设你想在800像素处设置断点,但又想用em单位,可以用800除以16,就是50rem。
(3)@import与媒体查询
可以在使用@import导入CSS时使用媒体查询,有条件地向当前样式表中加载其他样式表。
//导入样式表phone.css,但条件是必须是屏幕设备,而且视口不超过360像素
@import url("phone.css") screen and (max-width:360px);
注意:使用CSS中的@import会增加HTTP请求(进而影响加载速度),因此请慎用。
(4)在CSS中使用媒体查询
在标签中引入CSS文件,以及通过@import引入CSS文件时使用媒体查询,这两种方式都是链接样式的场景。但更常见的是在CSS文件内部直接使用媒体查询。
@media screen and (max-device-width: 400px) {
h1 { color: green }
}
它会在屏幕设备的宽度为400像素及以下时把所有h1元素变成绿色。
1、首先使用@media规则声明这是一个媒体查询,然后指定匹配的设备类型。
2、然后在后面的括号中,进一步指定查询条件。
3、最后,跟编写其他样式一样,把CSS规则写在一对花括号中。
4、多数情况下,并不需要指定screen。
在针对所有设备的媒体查询中,可以使用简写语法。即省略关键字all(以及紧随其后的and)。换句话说,如果不指定关键字,则关键字就是all。
(5)媒体查询可以测试哪些特性
媒体查询3级规定的所有可用特性:
-
width:视口宽度。
-
height:视口高度。
-
device-width:渲染表面的宽度(可以认为是设备屏幕的宽度)。
-
device-height:渲染表面的高度(可以认为是设备屏幕的高度)。
-
orientation:设备方向是水平还是垂直。
-
aspect-ratio:视口的宽高比。16∶9的宽屏显示器可以写成aspect-ratio:16/9。
-
color:颜色组分的位深。比如min-color:16表示设备至少支持16位深。
-
color-index:设备颜色查找表中的条目数,值必须是数值,且不能为负。
-
monochrome:单色帧缓冲中表示每个像素的位数,值必须是数值(整数),比如 monochrome: 2,且不能为负。
-
resolution:屏幕或打印分辨率,比如min-resolution: 300dpi。也可以接受每厘米多少点,比如min-resolution: 118dpcm。
-
scan:针对电视的逐行扫描(progressive)和隔行扫描(interlace)。例如720p HD TV(720p 中的p表示progressive,即逐行)可以使用scan: progressive来判断; 而1080i HD TV(1080i中的i表示interlace,即隔行)可以使用scan: interlace来判断。
- grid:设备基于栅格还是位图。
上面列表中的特性,除scan和grid外,都可以加上min或max前缀以指定范围。
@import url("tiny.css") screen and (min-width:200px) and (maxwidth: 360px);
这里使用最大宽度(max-width)和最小宽度(min-width)设定了范围。因此,tiny.css 只在设备视口介于200像素和360像素之间时才会被应用。
-
通过媒体查询修改设计
从原理上讲,位于下方的CSS样式会覆盖位于上方的目标相同的CSS样式,除非上方的选择 符优先级更高或者更具体。因此,可以在一开始设置一套基准样式,将其应用给不同版本的设计 方案。这套样式表确保用户的基准体验。然后再通过媒体查询覆盖样式表中相关的部分。比如, 如果是在一个很小的视口中,可以只显示文本导航(或者用较小的字号),然后对于拥有较大空 间的较大视口,则通过媒体查询为文本导航加上图标。
(1)任何CSS都可以放在媒体查询里
要知道,正常情况下我们编写的任何CSS样式,都可以放在媒体查询里。因此,使用媒体查 询可以从整体上修改一个网站的布局和外观(通常针对不同的视口大小)。
(2)针对高分辨率设备的媒体查询
媒体查询的一个常见的使用场景,就是针对高分辨率设备编写特殊样式。
@media (min-resolution: 2dppx) {
/* 样式 */
}
这里的媒体查询只针对每像素单位为2点(2dppx)的屏幕。类似的设备有iPhone 4的视网膜24屏,以及其他很多高清屏的安卓机。减小dppx值,可以扩大这个媒体查询的适用范围。
-
组织和编写媒体查询的注意事项
(1)使用媒体查询链接不同的CSS文件
1、从浏览器的角度看,CSS属于“阻塞渲染”的资源。
换句话说,浏览器需要下载并解析链接 的CSS文件,然后再渲染页面。
不过,现代浏览器都很聪明,知道哪些样式表(在头部通过媒体查询链接的样式表)必须立 即分析,而哪些样式可以等到页面初始渲染结束后再处理。
在这些浏览器看来,不符合媒体查询指定条件(比如屏幕比媒体查询指定的小)的CSS文件 可以延缓执行(deferred),到页面初始加载后再处理,以便让用户感觉页面加载速度更快。
2、阻塞渲染
“请注意,「阻塞渲染」仅是指该资源是否会暂停浏览器的首次页面渲染。无论CSS
是否阻塞渲染,CSS资源都会被下载,只是说非阻塞性资源的优先级比较低而已。”
3、所有链接的文件都会被下载下来,只是如果有的文件不必立即应用,那浏览器就不会让它影响页面的渲染。
4、因此,如果浏览器要加载的响应式页面通过不同的媒体查询链接了4 个不同的样式表(分别为不同视口的设备应用样式),那它就会下载4个CSS文件,但在渲染页面 之前,它只会解析那个针对当前视口大小的样式表。
(2)分隔媒体查询的利弊
1、编写多个媒体查询分别对应不同的样式表虽然有好处,但有时候也不一定。
2、多一个文件就要多一次HTTP请求,在某些条件下,HTTP请求多了会明显影响页面加载速度。
(3)把媒体查询写在常规样式表中
1、除非在极端情况下,否则我都建议在既有的样式表中写媒体查询,跟常规的规则写在一起。
-
关于视口的meta标签
(1)为了利用媒体查询,应该让小屏幕以其原生大小来显示网页,而不是先在980像素宽的窗口中渲染好,让用户去放大或缩小。
(2)这个用于视口的meta标签,是网页与移动浏览器的接口。网页通过这个标签告诉移动浏览器,它希望浏览器如何渲染当前页面。
(3)在可以预见的未来,任何响应式的希望在小屏幕设备上好好显示的网页,都必须添加这个meta标签。
(4)这个视口<meta>标签应该放在HTML的<head>标签中。可以在其中设置具体的宽度(比如使用像素单位),或者设置一个比例(比如2.0,即实际大小的两倍)。
//设置以内容实际大小的两倍(百分之二百)显示:
<meta name="viewport" content="initial-scale=2.0,width=device-width" />
1、name="viewport" 表示针对视口。
2、content="initial-scale=2.0“ 的意思是”把内容放大为实际大小的两倍“(0.5就是一般,3.0就是三倍)
3、width=device-width告诉浏览器页面的宽度等于设备的宽度。
(5)通过这个<meta>标签还可以控制用户可以缩放页面的程度。
下面的例子允许用户最大将页面放大到设备宽度的三倍,最小可以使页面缩小至设备宽度的一半。
<meta name="viewport" content="width=device-width, maximum-scale=3, minimum-scale=0.5" />
甚至可以完全禁止用户缩放。虽然允许缩放是一个重要的无障碍特性,但现实当中很少有必要这么做:
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
1、user-scalable=no是禁止用户缩放的。
2、initial-scale=1.0,意思是让移动浏览器在其视口的宽度中渲染网页。
3、将width设置为device-width就是要在所有支持的移动浏览器中,以百分之百的视口宽度 来渲染页面。
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
三、响应式图片
(1)Embedded Content规范描述了如何进行简单的图片分辨率切换(让拥有高分辨率屏幕的用户看到高分辨率的图片),以及支持“文艺范儿”,即可以根据视口空间大小显示完全不同的图片(类似媒体查询)
-
通过srcset切换分辨率
假设一张图片有三种分辨率的版本,一张小的针对小屏幕,一个中等的针对中等屏幕,还有一个比较大的针对所有其他屏幕。如何让浏览器知道这三个版本?如下:
<img src="scones_small.jpg" srcset="scones_medium.jpg 1.5x, scones_ large.jpg 2x" alt="Scones taste amazing">
1)src属性作用:一是指定1倍大小的小图片,二是在不支持srcset属性的浏览器中用作后备。正因如痴,才给它指定了最小的图片,好让旧版本的浏览器以最快的速度取得它。
2)对于支持srcset属性的浏览器,通过逗号分隔的图片描述,让浏览器自己决定选择哪一个。
3)图片描述首先是图片名(如cones_medium.jpg),然后是一个分辨率说明。
4)本例中用的1.5x和2x,其中的数字可以是任意整数,比如3x或4x都可以(如果你的用户可能使用那么高分辨率的屏幕)。
-
srcset及sizes联合切换
在响应式设计中,经常可以看到小屏幕中全屏显示,而在大屏幕上只显示一半宽的图片。
<img srcset="scones-small.jpg 450w, scones-medium.jpg 900w"
sizes="(min-width: 17em) 100vw, (min-width: 40em) 50vw" src="sconessmall. jpg" alt="Scones">
1)添加了以w为后缀的值,这个值的意思是告诉浏览器图片有多宽。这里表示图片分别是450像素宽(scones-small.jpg)和
900像素宽(scones-medium.jpg)。但这里以w为后缀的值并不是“真实”大小,它只是对浏览器 的一个提示,大致等于图片的“CSS像素”大小
2)使用w后缀的值对引入sizes属性非常重要。通过后者可以把意图传达给浏览器。(第一个值告诉浏览器“在最小宽度为17em的设备中,我想让图片显示的宽度约 为100vw)
3)vh(视口高度的1%)、vw(视口宽度的1%)
4)sizes属性的第二个值,意思其实是“嘿,浏览器,如果设备宽度大于等于40em,我只想让对应的图片显示为50vw宽”。
5)sizes属性仅仅是对浏览器给出提示。因此并不保证浏览器言听计从。
6)如果不想让浏览器决定,可以使用picture元素。使用这个元素可以让浏览器交付你让它交付的图片。
-
picture元素
为不同的视口提供不同的图片
<picture>
<source media="(min-width: 30em)" srcset="cake-table.jpg">
<source media="(min-width: 60em)" srcset="cake-shop.jpg">
<img src="scones.jpg" alt="One way or another, you WILL getcake.">
</picture>
1)picture元素只是一个容器,为我们给其中的img元素指定图片提供便利。加入你想为图片添加样式,那目标应该是内部的那个img
2)srcset属性的用途跟前面例子中的一样。
3)img标签是浏览器不支持picture元素,或者支持picture但没有合适媒体定义时的后备。
4)source标签,可以使用媒体查询表达式明确告诉浏览器在什么条件下使用什么图片。
- 使用新图片格式
picture还支持提供可替换的图片格式。WebP是一个新格式(详见https://developers.google. com/speed/webp/),但支持的浏览器不多(http://caniuse.com/)。对于支持它的浏览器,我们可以提供该格式的图片,再为不支持它的提供更常见的格式:
<picture>
<source type="image/webp" srcset="scones-baby-yeah.webp">
<img src="scones-baby-yeah.jpg" alt="Again, you WILL eatcake.">
</picture>
1)type属性通常用于指定视频来源。但我们在这里可以用它把WebP指定为优先使用的图片格式。浏览器如果能显示,就显示,如果不能,就使用img标签里的图片。
四、相对视口的长度
css3引入了相对视口的长度单位。每种单位都是视口的某种形式的百分比。
vw:视口宽度
vh:视口高度
vmin:视口中的最小值,等于vw或vh中较小的值
vmax:视口中的最大值,等于vw或vh中较大的值
(1)想要一个高度为浏览器窗口高度90%的模态弹层
.modal {
height: 90vh;
}
(2)在设定字体字号时结合使用这些相对单位很不错,可以让文字随着视口的大小变化而缩放。