当web第一次出现时,这样的问题并不存在,在上世纪90年代中期,仅仅可以通过笔记本电脑和台式机来浏览web页面,所以浏览器开发者和规范制定者甚至没有想到要实现这种解决方式(响应式开发)。最近应用的响应式图像技术,通过让浏览器提供多个图像文件来解决上述问题,比如使用相同显示效果的图片但包含多个不同的分辨率(分辨率切换),或者使用不同的图片以适应不同的空间分配(美术设计)。
注意: 在这篇文章中讨论的新特性 — srcset/sizes/— 都已经被新版本的现代浏览器和移动浏览器所支持(包括Edge,而不是IE)。

怎样创建自适应的图片?

在这一部分中,我们将看看上面说明的两个问题,并且展示怎样用HTML的响应式图片来解决这些问题。需要注意的是,如以上示例所示,在本节中我们将专注于HTML的,但网站页眉的图片仅是装饰性的,实际上应该要用CSS的背景图片来实现。CSS是比HTML更好的响应式设计的工具,我们会在未来的CSS模块中讨论。

分辨率切换:不同的尺寸

那么,我们想要用分辨率切换解决什么问题呢?我们想要显示相同的图片内容,仅仅依据设备来显示更大或更小的图片——这是我们在示例中使用第二个内容图像的情况。标准的元素传统上仅仅让你给浏览器指定唯一的资源文件。
我们可以使用两个新的属性——srcset 和sizes——来提供更多额外的资源图像和提示,帮助浏览器选择正确的一个资源。你可以看到 responsive.html 的例子,也可以在GitHub上看到源码:
srcset和sizes属性看起来很复杂,但是如果你按照上图所示进行格式化,那么他们并不是很难理解,每一行有不同的属性值。每个值都包含逗号分隔的列表。列表的每一部分由三个子部分组成。让我们来看看现在的每一个内容:
srcset定义了我们允许浏览器选择的图像集,以及每个图像的大小。在每个逗号之前,我们写:
一个文件名(elva-fairy-480w.jpg.)一个空格图像的固有宽度(以像素为单位)(480w)——注意到这里使用w单位,而不是你预计的px。这是图像的真实大小,可以通过检查你电脑上的图片文件找到(例如,在Mac上,你可以在Finder上选择这个图像,然后按 Cmd + I 来显示信息)。
sizes定义了一组媒体条件(例如屏幕宽度)并且指明当某些媒体条件为真时,什么样的图片尺寸是最佳选择—我们在之前已经讨论了一些提示。在这种情况下,在每个逗号之前,我们写:
一个媒体条件((max-width:480px))——你会在 CSS topic中学到更多的。但是现在我们仅仅讨论的是媒体条件描述了屏幕可能处于的状态。在这里,我们说“当可视窗口的宽度是480像素或更少”。一个空格当媒体条件为真时,图像将填充的槽的宽度(440px)
注意: 对于槽的宽度,你也许会提供一个固定值 (px, em) 或者是一个相对于视口的长度(vw),但不是百分比。你也许已经注意到最后一个槽的宽度是没有媒体条件的,它是默认的,当没有任何一个媒体条件为真时,它就会生效。 当浏览器成功匹配第一个媒体条件的时候,剩下所有的东西都会被忽略,所以要注意媒体条件的顺序。
所以,有了这些属性,浏览器会:
查看设备宽度检查sizes列表中哪个媒体条件是第一个为真查看给予该媒体查询的槽大小加载srcset列表中引用的最接近所选的槽大小的图像
就是这样!所以在这里,如果支持浏览器以视窗宽度为480px来加载页面,那么(max-width: 480px)的媒体条件为真,因此440px的槽会被选择,所以elva-fairy-480w.jpg将加载,因为它的的固定宽度(480w)最接近于440px。800px的照片大小为128KB而480px版本仅有63KB大小—节省了65KB。现在想象一下,如果这是一个有很多图片的页面。使用这种技术会节省移动端用户的大量带宽。
老旧的浏览器不支持这些特性,它会忽略这些特征。并继续正常加载 src属性引用的图像文件。
注意: 在HTML 文件中的
标签里, 你将会找到这一行代码: 这行代码会强制地让手机浏览器采用它们真实可视窗口的宽度来加载网页(有些手机浏览器会提供不真实的可视窗口宽度, 然后加载比浏览器真实可视窗口的宽度大的宽度的网页,然后再缩小加载的页面,这样的做法对响应式图片或其他设计,没有任何帮助。我们会在未来的模块教给你更多关于这方面的知识)。

一些有用的开发工具

这里有一些在浏览器中的非常实用的开发者工具用来帮助制定重要的槽宽度,以及其他你可能会用到的场景。当我在设置槽宽度的时候,我先加载了示例中的无响应的版本(not-responsive.html),然后进入响应设计视图 (Tools > Web Developer > Responsive Design View),这个工具允许你在不同设备的屏幕宽度场景下查看网页的布局。
我设置我的视图宽度为 320px,然后再改为 480px;每一次宽度的改变我就进入DOM 检查 ,点击我们感兴趣的元素,然后在显示屏右侧的 Box Model 视图选项卡中查看它的大小。 你应该会看到,这种无响应式的做法会让你的图片在不同屏幕宽度下有着固定的宽度。
接着, 你可以检查 srcset 是否正常工作,你需要将视图的宽度设置为你想要的,(比如,把宽度设置的比较小,让页面看起来比较狭窄),打开网络检查(Tools > Web Developer > Network),然后重新加载页面。网络检查工具会给你一个列表,里面的文件都是已经被下载来构造网页的。然后你可以在这里看到哪个图像文件被下载了。
注意: 在Chrome 中测试时,通过如下方式禁用缓存:打开 DevTools ,并选中 Settings > preferences > Network下Disable cache的选择框。否则,Chrome 会优先选择缓存图片而不是恰好适配的那个。