百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>html5教程> 使用srcset实现响应式图片 sizes属性
分享文章到:

使用srcset实现响应式图片 sizes属性

发布时间:01/15 来源: 浏览: 关键词:
在整个网站的开发中实现响应式,图片响应式较为困难,即优化和减少图片的体积,还要考虑手机端网络流量的问题,本文我们讲的 srcset 属性可以实现。

图片要在各种设备上平滑过渡显示,它们将会碰到的问题有:1.适当的优化和减少图片的体积;2.注意不要浪费带宽(网站的成败与否加载速度是其中主要因素之一);3.设备使用相应的解决方案。


对于第一个问题,使用TinyPng和JPEGmini工具可以帮助减少图片的体积和优化图片。

对于第二个问题,在一些场合下我们可能要使用到强大的媒体查询。多亏了有他们,我们可以很简单的处理背景图片的问题。但是,有些地方使用的是img来显示图片,这也是我们要解决的第三个问题,也是最后一个问题,如何根据设备的分辨率调用合适的图像。

在这种情况之下,有个两个解决方案:使用<picture>元素和<img>元素的srcset属性。

在这篇文章中,我会向大家总体的介绍srcset属性。


srcset属性

使用这个属性主要有什么好处呢?好处就是Web开发人员可以给使用高分辨率的用户显示高分辨的图像源,给其他设备分辨率的用户使用其他的图像源。在第一种情况下使用低PDD(pixel density displays)不需要背负着下载无用的高分辨率图像,而担心浪费带宽;而后者可以享受高清设备带来的不一样的享受。在第二种情况中,我们可以根据不同的屏幕尺寸指定不同的图像,这主要是根据用户的设备来提供一个较好的图像源。

事实上,srcset属性就做了这样的事情,根据像素密度或用户使用的屏幕尺寸大小,指定一个图像源。所以说,srcset属性可以让浏览器提供一套"建议",让浏览器根据正确的行为匹配正确的图像。通过这样做,我们提高了Web的质量,同时提高了Web页面的加载速度和给用户一个较好的体验。

在这一点上,这个属性的基本特征就是:根据指定的条件来做选择,使其工作。这对于我们编码工作和实现的方法变理更为简易。

W3C规范是这样描述srcset:srcset属性允许作者根据不同分辨率或不同的视窗尺寸提多个不同分辨图像。用户代理会根据之前获取的任何资源做选择,从而避免多个资源加载浪费带宽和相关性能问题。

原话:

    The srcset attribute allows authors to provide, in a compact manner, multiple variants of the same image at differing resolutions or for different viewport dimensions. User Agents may make their resource selection before fetching any of the resources, thus avoiding multiple resource loads and the associated performance problems in constrained bandwidth environments.

srcset属性包含一系列的逗号分隔值,一方面是指定图像的url,另一方面指图像将要显示的条件。图像条件我们可以看到有像素密度、视窗尺寸大小或者同时两者都存在。有一点非常有趣,浏览器可以根据用户的设置或页面访问时间,选择或抓取一个低分辨图像和高分辨图像。

想象一下,在你的移动浏览器偏好设置允许请求高分辨图像。例如,只有当连接到wifi的网络环境,或者在网络不强时会询问你是否手动设置浏览器偏好,允许加载低分辨图像。

语法格式如下:

<img src="small-photo.jpg" srcset="big-photo.jpg 2x" />

上面的代码要求浏览器显示名为small-photo.jpg图像。除非在一个高分辨显示器(像素密度为2x,比如Retina屏幕),才显示名为big-photo.jpg图像。请注意,只有浏览器理解这个属性才会显示其他图像,如果浏览器不能正确的解释这个属性,流星器会忽略其他图像,回退到src属性指定的图像。

如上所述,这个属性不仅限于高密度分辨率的设备。在一些情况下,还可以根据屏幕的视窗尺寸的宽度来选择图片,这就相当于媒体查询查到一个断点时加载背景图像。受益于它,你必须在指定的像素的数量后跟一个w(例如600 w)。为了更好的理解这个示例,让我们来看一个来自Sxc.hv网站的效果——"莫斯科的秋季"。压缩后的尺寸是1368 x 700,优化后体积是389kb。

srcset属性

到目前为止,我们所讨论的优势是让用户在使用他们的智能手机上网时下载一张大小比设备更大的图像,那么他的设备可以显示吗?此外,请记住移动连接受到一定的限制,一个棘手的问题就是图像过大将减缓你的页面加载,这可能会导致您的用户离开你的网站(很明显,首要的就是避免这种现像)。已经说过了,你可以考虑使用和设备尺寸相同的图像,比如尺寸400 x 22px,大小约40kb。

srcset属性


令人难以置信的是,使用下面的一段代码,我们就可以让用户节省带宽和改善用户的体验:

<img src="low-density-photo.jpg" srcset="small-photo.jpg 480w, big-photo.jpg 1024w, high-density-photo.jpg 1024w 2x" />

这段代码使用了low-density-photo.jpg图像作为候选图像,根据不同的条例提供了显示图像的一个列表:设备屏幕宽度小于或等于480px屏幕使用small-photo.jpg,设备屏幕宽度小于或等于1024px使用big-photo.jpg,最后是有两个条件,设备屏幕小于或等于1024的Retina屏将显示high-density-photo.jpg图像。

有一个不太好的消息要告诉你,目前支持srcset的浏览器只有Webkit引擎的浏览器:

aaa.jpg


此外,你不能设置一个图像基于max-width设备的屏幕,因为目前还没有具体说明如何使用。这个问题有点复杂,所以要不断检查规范是否有更新,阅读更多关于它的规范和方法才能更好的实现你的项目需求。

有关于srcset的W3C规范的草案在2013年12月2日发布了,草案中包含了一些有关于这个属性使用的示例和如何使用这个属性。

作为一个编辑的草案,我们也只能说这个属性离我更近,至于什么时候浏览器能全面支持和使用srcset属性,我们只能抱着希望期待。


在本文中,我们已经描述了srcset属性能更好的帮助Web开发人员更好的管理网站的图片。然而,正如我们所看到的,目前支持的浏览器还很少,但我们有自信,浏览最终将会解决这个问题。



响应式图片srcset全新释义sizes属性w描述符

说起图片的srcset属性,估计有不少与时俱进的小伙伴会在心中不由自主念想道:“这个我知道的,可以根据屏幕密度现实对应尺寸图片,例如……”

<img src="mm-width-128px.jpg" srcset="mm-width-128px.jpg 1x, mm-width-256px 2x">

上面代码对应demo轻戳这里。当然,我们也可以简写成:

<img src="mm-width-128px.jpg" srcset="mm-width-256px 2x">

由于我们都不是“别人家”的公司,因此,我们的办公PC显示器默认设备像素比都是1,因此,这些显示器呈现的图片默认都是128像素宽度的。下面问题来了,(不是挖掘机哪家强),如何让?潘肯允酒髂D飧呱璞赶袼乇饶兀?br/>
方法一:
Chrome浏览器,切换设备模式,如下截图(v38):

切换设备模式
然后,选择对应的设备,例如iPhone6 Plus的设备像素比就是3.
iPhone 6 Plus设备像素比为3


此时,刷新页面,加载的就是大尺寸图片,也就是256像素宽度那张。

方法二:
Chrome浏览器,Ctrl+✚快捷键,或者ctrl + 鼠标滚轮,放大页面的比例,例如,试试放大到150%:

页面放大150%


此时设备像素比window.devicePixelRatio为1.5,因此加载的就是256像素宽度的图片。有图有真相:

设备像素比1.5使用2x图片


不同的2x显示策略
还有些时候,使用同尺寸的高清图片作为2x对应图片,虽然两者图片大小差不多,但个人觉得还是2倍尺寸优化大图更好一点,为什么呢?

srcset当初设计的用意是为了高密度屏幕上图片更好的显示,如果世界上就只有“不同设备密度”这一个戏剧冲突的话,2x图片是高清图还是2倍尺寸图其实都无伤大雅。然而,事实上,生活无处不戏剧,现代web布局中,有种布局不可忽略,那就是「响应式布局」,剧本往往会这样,PC浏览器上显示大图,Mobile浏览器上显示小图。发现没,同样是“大小图的要求”,和设备像素比有类似的戏剧冲突。

于是,如果我们2x图片使用的是高清图,结合响应式布局,我们可能需要4张图片资源,即:小图、小图高清和大图、大图高清。但是,2x图片走的是2倍尺寸图片,我们只需要3张图片资源,即:小图、中图以及中图、大图。

在老一代srcset规范成型过程中,其实已经考虑到与响应式布局的纠葛,出现了w描述符,例如,走高清路线的:

<img src="small.jpg" srcset="small.jpg 640w 1x, small-hd.jpg 640w 2x, large.jpg 1x, large-hd.jpg 2x">

走2倍尺寸路线的:

<img src="small.jpg" srcset="small.jpg 640w 1x, medium.jpg 640w 2x, medium.jpg 1x, large.jpg 2x">

注意啊注意:千万不要去关心上面的w描述符的含义,因为新的srcset属性中w描述符含义与之完全不同,为了避免理解冲突,心中跟我默念3遍:忘掉它、忘掉它、忘掉它,无视它、无视它、无视它。大家可以把精力放在下面,新的srcset规范以及新的sizes属性语法含义等。


恰如其分的时间点

我们去caniuse上查看srcset属性的浏览器支持情况,会发现有黄黄绿绿的颜色:

caniuse上srcset的浏览器支持情况


可以看到,Chrome浏览器下,从版本38开始是绿色的,而之前是黄绿色。黄绿色表示仅支持旧的srcset规范,绿色表示支持全新的srcset规范,包括sizes属性,w描述符。

而Chrome 38稳定版就在上周发布(腾讯软件管家显示10月16号也就是前几天发布的),于是,我们就有条件实践srcset新规范特性,有利于快速学习。

因此,我才选择在这个时间点写这篇文章,推产品也是如此,需要一个合适的时间点,太早的死在沙滩上,太晚的落后跟不上。

因此,若要学习本文内容,看看您的Chrome浏览器是否是38+.

于此同时,苹果刚发布了4x的显示器,如果使用传统srcset,需要1x, 2x, 3x, 4x, 我勒个去,HTML立马变成了臃肿的大胖子。与时俱进势在必行!


全新的智能srcset、sizes属性, w描述符

旧的srcset是人主导,而现在新的srcset是浏览器主导,你主需要提供图片资源、以及断点,其他都交给浏览器智能解决,什么响应宽度啊、设备像素比啊,你都不要关心了,浏览器会自动匹配最佳显示图片。你的表情现在是不是这样子啊:
酷毙了 表情

如下HTML示例:

<img class="image" src="mm-width-128px.jpg"
     srcset="mm-width-128px.jpg 128w, mm-width-256px.jpg 256w, mm-width-512px.jpg 512w"
     sizes="(max-width: 360px) 340px, 128px">

其中1:
srcset用来指向提供的图片资源,注意,仅仅是资源指向,没有以前的1x, 2x什么的,这个都交给浏览器了,我们不需要关心!例如这里,指向了3个尺寸图片,分别实际尺寸128像素,256像素和512像素。

其中2:
sizes用来表示尺寸临界点,主要跟响应式布局打交道。语法如下:

sizes="[media query] [length], [media query] [length] ... etc"

例如上述代码中,size = "(max-width: 360px) 340px, 128px"表示当视区宽度不大于360像素时候,图片的宽度限制为340像素,其他情况下,使用128像素(对应下面demo页面第1张图)。

如果sizes="128px", 则尺寸就一直是128像素,图片只会根据设备像素比发生变化。

注意,这里所有的值都是指宽度值,且单位任意,em, px, cm, vw, ...都是可以的,甚至可以CSS3的calc计算(对应下面demo页面第2张图),例如:

sizes="(max-width: 360px) calc(100vw - 20px), 128px"

表示当视区宽度不大于360像素时候,图片宽度为整个视区宽度减去20像素的大小。

OK,上面2个属性具体如何起作用的呢?首先,你需要狠狠地点击这里:srcset与sizes新释义w描述符示意demo

1. 设备像素比的对应显示
按照Part2的提示,F12点击切换设备模式,我们先看下大宽度尺寸下的显示,例如,我们选择个iPad 1:

iPad1选择截图示意


其中fit前面的钩钩去掉,以更清晰的显示。此时,大家可以看到,图片显示的是128像素宽度的。为什么呢?

还记得咱们的sizes属性值吗?最后光秃秃没有媒体查询的值就是128px, 目前视图宽度是1024像素,远远大于360像素这个临界宽度值,因此,图片占据宽度是128像素。同时,最最重要的是,这里的设备像素比是1.
设备像素比是1

因此,我们可以正儿八经显示实际宽度是128像素的那张图了。最终显示如下:

128像素实际宽度图片被加载了
//zxx: 上下两张图上面已经提到过,代码差异仅仅是sizes的一个临界宽度值不一样,上面的是340px,下面的是calc(100vw - 20px),有助于大家深入理解w描述符,后面有大量戏份,当然,这里,大家可暂时不用关心。

OK,保持宽度不变,我们变一个小魔术,下面,把设备像素比1改成2然后刷新页面:
改变设备像素比为2

于是,当当当当,见证奇迹的时刻到了,图片256了:

设备像素比为2的时候加载的是256实际宽度图片


同样的,我们修改设备像素比是3再刷新页面,会发现图片加载的是512宽度那种:

设备像素比为3时候加载的图片


如果改成4+,还是上面这种512像素宽度的图片,因为这是我们给浏览器提供的最大w对应的图片了。

大家注意到木有,我们完全没有指定浏览器那个设备像素比使用哪个图片,浏览器非常smart帮我们加载了最佳显示的图片。这就是最新的srcset的释义,更智能更强大。

2. sizes的媒体查询

下面我们深入理解下sizes属性的作用机制。

首先,我们修改设备为Google Nexus5, 此时视区宽度为360像素,正好是sizes设置的临界宽度值,修改设备像素比为1(去除其他测试干扰因素),刷新页面,会发现页面加载的是512这张图:

360宽度下加载512像素图片

为什么加载是512呢?

依次看来,首先第一张图,对应值是(max-width: 360px) 340px, 意思通俗易懂,视区宽度不大于360像素时候,图片实际尺寸340像素。此demo两侧各有10像素空白,因此,正好图片满屏显示的感觉。下面问题来了,为什么加载的是512这种图,而不是256?

大家还记不记得srcset中每张图片资源后面的w描述符的值大小?没错,分别是128w, 256w, 512w. 正好这里解释下w描述符的意思,根据我个人的理解(注意,是个人理解,仅供参考),w用来描述文件的宽度,我们可以形象理解为规格,就像手机一样,有大小不一样的尺寸与规格。根据我浅薄的经验,我们可以直接等同于像素去理解。可能你会疑问,那为何不直接256px而是256w, 因为,请注意,这里的256w并不是指图片的宽度,而是图片的宽度规格,例如,一张图片实际宽度是256像素,但是,这种图片是png24无损图片,或100%质量JPG图片,则,我们可以使用512w表示这张图片,质量好规格就高,不难理解吧!如果是512px显然就有问题了,明明图片256像素,搞个512px,歧义到王母娘娘哪儿去了!因此,需要一个没人见过的w表示,同时,需要意识到,w不是单位,而是一个描述符(descriptor)。

回到主线,图片340像素,可以看出340规格,340w, 于是256w这张图片显示就规格不够,简称“不够格”;512w > 340w,满足最优显示准则,于是,加载的就是512px这张图。

如果你希望视图360像素宽度时候加载的是256这张图片,很简单,修改其规格256w为340w, done!

OK, 注意注意,前方高能!!

下面,不是下饺子,修改宽度为一个吉利的数字 ? 250, 然后刷一下(注意设备像素比要为1)~~会发现,上下两张图的差异来了,如下截图:


上下使用图片尺寸不一样了


虽然图片都是100%父容器显示,但加载的图片却不一样。咦?为何会不一样呢?

其实很好理解,前者是340px, 后者是calc(100vw - 20px),一个是定值,一个动态的。前者永远是340w规格,而后者在尺寸是250像素时候,实际像素是230px, 可以看成230w,比256w小,于是就加载了256这种图片啦!

因此,如果大家希望图片的加载进一步智能,建议使用动态单位。

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有5人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板