FED

©FrontEndDev.org
2015 - 2024
web@2.23.0 api@2.21.1

[翻译]picture——浏览器内置的响应式标签

<picture>标签介绍

<picture>标签提供可声明式的方式来加载图片。网页开发者不必非要用CSS和JS来处理响应式的图片加载。用这种方式的好处是提高加载速度—尤其是在移动端时网络情况不好的时候。

随着新的属性 srcset、sizes加入到<img>标签,<picture>标签给网页开发者更多的灵活性来定义图片的源。书写清晰的标记来让浏览器检测到下面不同的标记,忽略还是加载,来支持响应式设计并提高加载的时间:

艺术的选择

这是一个手机端的应用还是一个桌面端的显示? 根据浏览器规格优化图片的加载

设备像素比例的选择

设备是否支持高DPI显示?加载分辨率更高的图片。

视窗的选择

图片是否一直填充在视窗的一部分?相对于视窗的图片加载

图片格式的选择

浏览器是否支持更小的图片类型?加载可替换的图片类型如:WebP

为美的设计而用

最普遍的应用<picture>元素是在响应式设计中的美术设计。代替一张图片缩放来适应窗口的大小的方式,用多张图片的设计来适应浏览器的窗口。

用一张图片来适应不同屏幕窗口的大小

用多张不同的图片来适应不同窗口的大小

提高资源的加载性能

当用<picture>或者用的srcset和sizes属性,浏览器仅仅会下载对应明确的适合的图片。这种本地实现的方式可以很好的被解析并最好的使用浏览器级的缓存和预加载。

查看在线示例

事实上网络被创建用于加载一张猫的图片。用<picture>我们可以模拟难以想象的猫的能力来适应空间,不管网页多大或者多小。

打开示例页面用chrome38以上的版本。调整浏览器的视窗大小。 作为一个开始,这个例子仅仅突出了<picture>的最小的特性。让我们深入的开始钻研下吧。

<picture>语法

下面的HTML和CSS的片段就是这个例子的代码实现:

<style>
  img {display: block; margin: 0 auto;}
</style>

<picture>
  <source
    media="(min-width: 650px)"
    srcset="images/kitten-stretching.png">
  <source
    media="(min-width: 465px)"
    srcset="images/kitten-sitting.png">
  <img
    src="images/kitten-curled.png"
    alt="a cute kitten">
</picture>

注意下这没有用js和第三方的库。CSS的<style>块是用来定义image元素样式而且没有包含media queries.<picture>元素的本地实现意味这你可以只用HTML来声明响应式图片。

用**<source>元素**

<picture>标签它本身没有属性。神奇的地方是<picture>被用来当做<source>的容器。 <source>元素,是用来加载多媒体的比如视频和音频,已经被更新用到图片的加载并且一些新的属性已经被添加:

srcset (必需) 接受单一的图片文件路径(如:srcset="kitten.png"). 或者是逗号分隔的用像素密度描述的图片路径(如:srcset="kitten.png, ketten@2x.ng 2x"),1x 的描述是默认不使用的。 关于

media (可选) 接受任何验证的media query,你可以看到在CSS @ media 选择器(如:media="(max-width:30em)").在之前的<picture>语法的例子里已经用到了。

sizes(可选) 接收单一的宽度描述(如:sizes="100vw")或者单一的media query宽度描述(如:sizes="(max-width:30em) 100vw"). 或者逗号分隔的media query对宽度的描述(如:sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)") 最后的一个被当做默认的。

查看[Combine with width descriptors](Combine with width descriptors)看如何使用

type(可选) 接受支持的MIME类型(如: type="image/webp" or type="image/vnd.ms-photo")

查看[Load alternative image file formats](Load alternative image file formats)看如何使用. 浏览器会根据这些提示和属性来加载确切的图片资源。根据标签的列表顺序。浏览器会使用第一个合适的<source>元素并忽略掉后面的<source>标签。

添加最后的<img>元素

<img>元素在<picture>内部用来当浏览器不支持时或者没有源标签匹配时的显示。在<picture>内使用<img>标签是必须得,如果你忘记了,将不会有图片显示出来。

<img>来声明默认的图片显示。将<img>标签放到<picture>内的最后,浏览器在找到<img>标签之前会忽略<source>的声明。这个图片标签也需要你写上它的alt属性。

嵌入使用像素密度描述

增加高分辨率的像素密度描述,像 1x,1.5x,2x和3x. 新的srcset属性应用到<img><source>元素。

下面的例子支持1x,1.5x,和2x 的屏幕

<picture>
  <source
    media="(min-width: 650px)"
    srcset="images/kitten-stretching.png,
            images/kitten-stretching@1.5x.png 1.5x,
            images/kitten-stretching@2x.png 2x">
  <source
    media="(min-width: 465px)"
    srcset="images/kitten-sitting.png,
            images/kitten-sitting@1.5x.png 1.5x
            images/kitten-sitting@2x.png 2x">
  <img
    src="images/kitten-curled.png"
    srcset="images/kitten-curled@1.5x.png 1.5x,
            images/kitten-curled@2x.png 2x"
    alt="a cute kitten">
</picture>

整合使用宽度描述

网页基础深入的描述过<img>元素:

"当图片最后的尺寸不知道的时候,确定图片源的密度是一件困难的事。特别是那些相对浏览器设置比例的图片,是依赖浏览器尺寸的。 代替固定图片的大小和密度,每一个图片的尺寸可以通过增加一个宽度描述来确定,让浏览器自动的精确计算像素密度并选择最合适的图片下载。"

这是一个用sizes属性来设置图片比例相对窗口为80%的例子。它用srcset属性来响应4个版本的阳光房子的图片,宽度分别为160px,320px, 640px, 和 1280px:

<img src="lighthouse-160.jpg" alt="lighthouse"
     sizes="80vw"
     srcset="lighthouse-160.jpg 160w,
             lighthouse-320.jpg 320w,
             lighthouse-640.jpg 640w,
             lighthouse-1280.jpg 1280w">

浏览器将会用这些提示来选择最恰当的图片源来适应窗口宽度和硬件显示:

如图,左边的浏览器窗口大约800px.浏览器将会加载lighthouse-640.jpg,除非设备分辨率是2x—in,lighthouse-1280.jpg 图片才会被加载

增加<picture>元素,sizes属性被用到了<img><source>元素:

<picture>
  <source media="(min-width: 800px)"
          sizes="80vw"
          srcset="lighthouse-landscape-640.jpg 640w,
                  lighthouse-landscape-1280.jpg 1280w,
                  lighthouse-landscape-2560.jpg 2560w">
  <img src="lighthouse-160.jpg" alt="lighthouse"
       sizes="80vw"
       srcset="lighthouse-160.jpg 160w,
               lighthouse-320.jpg 320w,
               lighthouse-640.jpg 640w,
               lighthouse-1280.jpg 1280w">
</picture>

在上面的例子中,当窗口在800px并且大于时,浏览器将会加载对应版本的图片:

左边的时大于800px的窗口,所以对应版本的图片将显示出来

加载可改变的图片格式

<source>元素的type属性可以用来加载可变图片文件格式,不过这并不是所有图片都支持。举个例子,你可以在支持的浏览器里使用WebP格式,在不支持的浏览器使用JPEG格式:

<picture>
  <source type="image/webp" srcset="images/butterfly.webp">
  <img src="images/butterfly.jpg" alt="a butterfly">
</picture>

其他代码示例

相关介绍对响应式图片:从示例和带注释的代码片段开始,在Dev.Opera博客有详细的关于<picture>和的srcset,media,sizes以及type属性介绍。

现在就试试吧

<picture>元素在Chrome38就可以使用了,用chrome的开发者工具模拟器开始尝试吧。

英文原文