图片在响应式网页设计中是出了名的最具挑战性的方面之一。今天我们就来看看如何使用 <picture>
元素来处理响应式图片.
固定宽度,像素完美的网站设计已经离我们远去了。在宽屏显示器,互联网电视,多尺寸的平板电脑和智能手机的今天,我们的设计必须应付一切可能,将宽由 320px
向 7680px
转变。
伴随这种多分辨率风景而至的,是需要拉伸或收缩图像,以适应这些不同的要求。这可以被理解为如下问题,矢量图形出现异常时,绝大多数具有特定像素的图像宽度并不改变。
所以,我们应该怎么做呢?
作为一般规则,你会在任何响应式网站中发现以下CSS样式:
img { max-width: 100%; height: auto; }
此代码使用 max-width:100%
的设置,以确保图像永远不会超越其父容器的宽度。如果父容器的宽度收缩小于图像的宽度,图像将随之缩小。 height:auto
的设置可以确保当有这种情况发生时,图像将以自身的宽高比保留。
这解决了一方面的问题,使我们能够在许多不同的情况下显示相同的图像。不过,这并不能让我们对不同的情况指定不同的图像。
<picture>
<picture>
是HTML5一个新的元素。
如果 <picture>
元素与当前的 <audio>
和 <video>
元素协同合作将大大增强响应式图像的工作进程。它允许你放置多个 source
标签,以指定不同的图像文件名,进而根据不同的条件进行加载。
它可以让你根据以下条件加载完全不同的图像:
反过来这也意味着您可以:
<picture>
的工作原理 <picture>
基本工作步骤如下:
<picture></picture>
标签。 <source>
元素。 media
属性,用来包含你想要的特性,如视口的当前高度(viewport height),宽度( width
),方向(orientation)等。 srcset
属性与相应的图像文件名相匹配,进行加载。如果你想提供不同的像素密度,例如Retina显示屏,你可以添加额外的文件名到你的 srcset
属性中, <img>
元素。 这里有一个简单的基本的例子,用来检查视口是否小于 768px
,如果小于的话就加载一个较小的图像:
<picture> <source srcset="smaller.jpg" media="(max-width: 768px)"> <source srcset="default.jpg"> <img srcset="default.jpg" alt="My default image"> </picture>
你可能会注意到,在 media
属性使用的语法与创建CSS媒体特性中使用的语法一样。您可以使用相同的特性,这意味着你可以查询 max-width
, min-width
, max-height
, min-height
, orientation
等属性。
同时,您也可以使用这些特性判断设备的方向,从而加载横向或纵向版本的图像,同时您也可以进行大小特性的混合。例如:
<picture> <source srcset="smaller_landscape.jpg" media="(max-width: 40em) and (orientation: landscape)"> <source srcset="smaller_portrait.jpg" media="(max-width: 40em) and (orientation: portrait)"> <source srcset="default_landscape.jpg" media="(min-width: 40em) and (orientation: landscape)"> <source srcset="default_portrait.jpg" media="(min-width: 40em) and (orientation: portrait)"> <img srcset="default_landscape.jpg" alt="My default image"> </picture>
上面的代码实现了可以在一个小的景观设备上加载小的,景观裁剪图像的版本。在大的景观设备上加载大的相同的图像版本。
这样,在小尺寸的小型设备上,或在大尺寸的大型设备上,该设备可以自主进行图像主导从而加载不同图像剪裁的版本。
如果您想为更高密度的显示器提供不同分辨率的图像版本,可以通过在 srcset
属性中添加额外的文件名来实现。例如,让我们来看看屏幕像素密度为 2x
的Retina 代码处理片断:
<picture> <source srcset="smaller.jpg, smaller_retina.jpg 2x" media="(max-width: 768px)"> <source srcset="default.jpg, default_retina.jpg 2x"> <img srcset="default.jpg, default_retina.jpg 2x" alt="My default image"> </picture>
<picture>
元素现在的使用情况 现在,Chrome,Firefox和Opera浏览器都已经实现了对 <picture>
元素的支持。在不久的将来,在其他浏览器也将得到广泛的支持。但现在这一时刻还没有来临。
与此同时,如果你现在就想使用 <picture>
元素可能还需要等待。你也可以使用 Picturefill2.0 ; Filament 成员 提供的一个polyfill。
通过下载并添加 picturefill.js 文件到您项目的头部就可以实现:
<script src="picturefill.js"></script>
还有你可以通过异步加载脚本来增加效率,你可以参考 Picturefill的文档 。
有了这个脚本加载,除了少数的限制, <picture>
元素将如我所讲的运行。
Picturefill在其他的IE版本都可以正常工作,但是IE9却不能识别被包裹在 picture
标签中的 source
元素。为了解决这个问题,在 video
标签内包住你的源元素,这就会使他们在IE9中被识别,例如:
<picture> <!--[if IE 9]><video style="display: none;"><![endif]--> <source srcset="smaller.jpg" media="(max-width: 768px)"> <source srcset="default.jpg"> <!--[if IE 9]></video><![endif]--> <img srcset="default.jpg" alt="My default image"> </picture>
和IE9一样,Android 2.3识别不了在 picture
元素中 source
元素。然而,在使用常规的 img
标签时,它就可以识别 srcset
属性。为了避免在Android 2.3及任何有相同问题的其他浏览器中出现此问题,确保在 srcset
属性中存在默认用于回退的 img
元素的文件名。
有了这个基于JavaScript的解决方案,因此在浏览器中需要支持JavaScript。 Picturefill 2.0不提供“no-js”的解决方法,因为如果这样,当原生浏览器支持 <picture>
元素时,将会出现多个图像。但是,如果“no-js”是你的不二选择,你必须使用Picturefill 1.2。
Picturefill另外一个要求就是需要本地媒体特性的支持,从而使 media
属性中的特性能够正常工作。所有现代浏览器都支持媒体特性,IE8和以及更低版本的浏览器是剩下的唯一不支持的 用户群 。
在原生支持 srcset
元素,但不支持 picture
元素的浏览器中,和回退的 img
元素中指定的文件名可能会被提前调用,从而会在 source
元素中确定一个更好的拟合图片。
这只是一个暂时的问题,一旦本地支持 picture
元素就会自行消失。
<picture>
元素的信息。 今天在您的项目中就尝试使用 <picture>
元素,看看是否实现了预期功能!
本文根据 @Kezz Bracey 的《 Quick Tip: How to Use HTML5 “picture” for Responsive Images 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: http://webdesign.tutsplus.com/tutorials/quick-tip-how-to-use-html5-picture-for-responsive-images--cms-21015 。
在校学生,本科计算机专业。一个积极进取、爱笑的女生,热爱前端,喜欢与人交流分享。想要通过自己的努力做到心中的那个自己。微博:@静-如秋叶