自适应图片——一种可以在不同的屏幕尺寸和分辨率的设备上都能良好工作以及其他特性的图片
切换分辨率并切换图像
使用两个新的属性—srcset和sizes来提供更多额外的资源图像和提示,帮助浏览器选择正确的一个资源。
<img srcset="elva-fairy-320w.jpg 320w,
elva-fairy-480w.jpg 480w,
elva-fairy-800w.jpg 800w"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
srcset定义了我们允许浏览器选择的图像集,以及每个图像的大小。在每个逗号之前,我们写:
- 一个文件名 (elva-fairy-480w.jpg.)
- 一个空格
- 图像的固有宽度(以像素为单位)(480w)——注意到这里使用w单位,而不是你预计的px。这是图像的真实大小,可以通过检查你电脑上的图片文件找到
sizes定义了一组媒体条件(例如屏幕宽度)并且指明当某些媒体条件为真时,什么样的图片尺寸是最佳选择。
- 一个媒体条件((max-width:480px))——你会在 CSS topic中学到更多的。但是现在我们仅仅讨论的是媒体条件描述了屏幕可能处于的状态。在这里,我们说“当可视窗口的宽度是480像素或更少”。
- 一个空格
- 当媒体条件为真时,图像将填充的槽的宽度(440px)
注意: 对于槽的宽度,你也许会提供一个固定值 (px, em) 或者是一个相对于视口的长度(vw),但不是百分比。你也许已经注意到最后一个槽的宽度是没有媒体条件的,它是默认的,当没有任何一个媒体条件为真时,它就会生效。 当浏览器成功匹配第一个媒体条件的时候,剩下所有的东西都会被忽略,所以要注意媒体条件的顺序。
所以,有了这些属性,浏览器会:
- 查看设备宽度
- 检查sizes列表中哪个媒体条件是第一个为真
- 查看给予该媒体查询的槽大小
- 加载srcset列表中引用的最接近所选的槽大小的图像
注意: 在 HTML 文件中的 <head> 标签里, 你将会找到这一行代码 <meta name=“viewport” content=“width=device-width”>: 这行代码会强制地让手机浏览器采用它们真实可视窗口的宽度来加载网页(有些手机浏览器会提供不真实的可视窗口宽度, 然后加载比浏览器真实可视窗口的宽度大的宽度的网页,然后再缩小加载的页面,这样的做法对响应式图片或其他设计,没有任何帮助。我们会在未来的模块教给你更多关于这方面的知识)。
一些有用的开发工具
打开网页开发者工具
这个工具允许你在不同设备的屏幕宽度场景下查看网页的布局。
切换分辨率
如果你支持多种分辨率显示,但希望每个人在屏幕上看到的图片的实际尺寸是相同的,你可以让浏览器通过srcset和x语法结合——一种更简单的语法——而不用sizes,来选择适当分辨率的图片。
<img srcset="elva-fairy-320w.jpg,
elva-fairy-480w.jpg 1.5x,
elva-fairy-640w.jpg 2x"
src="elva-fairy-640w.jpg" alt="Elva dressed as a fairy">
切换图像
让我们改用 <picture>!就像<video>和<audio>,<picture>素包含了一些<source>元素,它使浏览器在不同资源间做出选择,紧跟着的是最重要的<img>元素。
<picture>
<source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
<source media="(min-width: 800px)" srcset="elva-800w.jpg">
<img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
</picture>
- <source>元素包含一个media属性,这一属性包含一个媒体条件——就像第一个srcset例子,这些条件来决定哪张图片会显示——第一个条件返回真,那么就会显示这张图片。在这种情况下,如果视窗的宽度为799px或更少,第一个<source>元素的图片就会显示。如果视窗的宽度是800px或更大,就显示第二张图片。
- srcset属性包含要显示图片的路径。请注意,正如我们在<img>上面看到的那样,<source>可以使用引用多个图像的srcset属性,还有sizes属性。所以你可以通过一个 <picture>元素提供多个图片,不过也可以给每个图片提供多分辨率的图片。实际上,你可能不想经常做这样的事情。
- 在任何情况下,你都必须在 </picture>之前正确提供一个<img>元素以及它的src和alt属性,否则不会有图片显示。当媒体条件都不返回真的时候(你可以在这个例子中删除第二个<source> 元素),它会提供图片;如果浏览器不支持 <picture>元素时,它可以作为后备方案。
注意: 你应该仅仅当在美术设计场景下使用media属性;当你使用media时,不要在sizes属性中也提供媒体条件。
为什么我们不能使用 CSS 或 JavaScript 来做到这一效果?
当浏览器开始加载一个页面, 它会在主解析器开始加载和解析页面的 CSS 和 JavaScript 之前先下载 (预加载) 任意的图片。这是一个非常有用的技巧,平均下来减少了页面加载时间的20%。但是, 这对响应式图片一点帮助都没有, 所以需要类似 srcset的实现方法。因为你不能先加载好 <img> 元素后, 再用 JavaScript 检测可视窗口的宽度,如果觉得大小不合适,再动态地加载小的图片替换已经加载好的图片,这样的话, 原始的图像已经被加载了, 然后你又加载了小的图像, 这样的做法对于响应式图像的理念来说,是很糟糕的。
新图像格式
有很多令人激动的新图像格式(例如WebP和JPEG-2000)可以在有高质量的同时有较低的文件大小。然而,浏览器对其的支持参差不齐。
<picture>让我们能继续满足老式浏览器的需要。你可以在type属性中提供MIME类型,这样浏览器就能立即拒绝其不支持的文件类型:
<picture>
<source type="image/svg+xml" srcset="pyramid.svg">
<source type="image/webp" srcset="pyramid.webp">
<img src="pyramid.png" alt="regular pyramid built from four equilateral triangles">
</picture>
- 不要使用media属性,除非你也需要美术设计。
- 在<source> 元素中,你只可以引用在type中声明的文件类型。
- 像之前一样,如果必要,你可以在srcset和sizes中使用逗号分割的列表。
总结
学会:
- 学会在网页插入自适应的图片,以适应不同大小屏幕的设备,这是必须的
- 不使用JS或CSS来完成自适应图片
- 可以利用<img>的scrcet属性和sizes属性,其中scrset属性可以选择不同的图片,sIzes属性对应不同的屏幕条件和图片将要填充的宽度。两者一一对应,类似查表。除了这两个属性,src属性和alt属性也是必须的,相当于else
- 也可以不使用sizes属性,在srcset属性后加上x语法,表明显示器的分辨率。1x是默认值
- 使用<picture>元素,和<source>来指定图片,屏幕属性用media,图片选择用srcset。类似<vidio> 和<audio>
不懂:
x语法是什么?怎么指代不同屏幕
解答:
<img srcset="elva-fairy-320w.jpg,
elva-fairy-480w.jpg 1.5x,
elva-fairy-640w.jpg 2x"
src="elva-fairy-640w.jpg" alt="Elva dressed as a fairy">
类似倍数,480是320的1.5倍。所以上述代码,在屏幕上都是一样比例的大小