img 的 srcset、sizes 属性和 picture 元素

HTML 5.1 新增加了 img 元素的 srcsetsizes 属性和 picture 元素,使得响应式图片的实现更为简单便捷,很多主流浏览器的新版本也对这些新增加的内容支持良好。
下面通过一些例子来简要说下用法,例子里用 PLACEHOLD.IT 来获取不同像素的图片。

srcset 和 sizes 属性

srcset 是一个包含一个或多个源图的源图容器,不同源图用逗号分隔,每一个源图由下面两部分组成:
1、图片 URL
2、 x (像素比描述)或 w (图片像素宽度描述)描述符(与图片 URL 相隔一个空格), w 描述符的加载策略是通过 sizes 属性里的声明来计算选择的

上述第2点如果没有给出,则是默认的 1x
以下情况是不正确的:

  • 在同一个 srcset 里的不同图片出现有的用 x 描述符有的用 w 描述符
  • 同一个图片既使用了 x 描述符也使用了 w 描述符

对于不正确的情况,不同的浏览器使用不同的处理方法。

sizes 写法与 srcset 差不多,也是用逗号分隔的一个或多个 string ,每个 string 由下面两部分组成:
1、媒体查询。最后一个 string 不能有这个,作为 fallback
2、图片 size (大小)信息。需要注意的是这里不能使用 % 来描述图片大小,如果要用百分比来表示,要使用类似于 vw (100vw = 100%设备宽度(viewport))这样的单位来描述,其它的像是 pxem 等可以正常使用。

sizes 里给出的不同媒体查询选择图片大小的建议只对 w 描述符起作用,也就是说,如果 srcset 里用的是 x 描述符或根本没有定义 srcset ,这个 sizes 是没有意义的。

x 描述符

<img
    srcset=“
        http://placehold.it/2500 5x,
        http://placehold.it/1500 3x,
        http://placehold.it/1000 2x,
        http://placehold.it/500 1x
    "
    src="http://placehold.it/500/abc"
/>

上面代码的意思就是:5像素比(现在很多安卓手机比如小米、华为的所谓高清2k屏就是5像素比以上的)的设备使用2500x2500像素的图片,3像素比的设备使用1500x1500像素的图片,2像素比的设备使用1000x1000像素的图片,1像素比(普通的笔记本电脑显示屏就是1像素比的)的设备使用500x500像素比的图片。
对于不支持 srcset 的浏览器,显示 src 的图片(这个图片是500x500像素、RGB 颜色 abc 的)。
而对于 srcset 里没有给出像素比的设备,不同浏览器的选择策略不同。比如例子中没有给出1.5像素比的设备要使用哪张图,浏览器可以选择2像素比的也可以选择1像素比的(当然也可以选择5像素比或者使用 src 的图片,但是这显然不是一个好的选择)。

w 描述符和 sizes

w 描述符可以简单理解为描述源图的像素大小(无关宽度还是高度,大部分情况下可以理解为宽度)。

<img
    srcset=“
        http://placehold.it/2000 2000w,
        http://placehold.it/1500 1500w,
        http://placehold.it/1000 1000w,
        http://placehold.it/500 500w
    "
    sizes=“
        (max-width: 500px) 500px,
        (max-width: 1000px) 1000px,
        (max-width: 1500px) 1500px,
        2000px
    "
    src="http://placehold.it/500/abc"
/>

上述例子的意思是:对于 viewport 在 500px 及以下的使用 500w 的图片,以此类推,最后一个是前面的媒体查询都不符合的情况下使用 2000w 的图片。
这里如果没有相对应的 w 描述,一般选择第一个大于它的。如上述例子中如果有一个媒体查询是 700px 的,一般加载 1000w 对应的源图。(这里之所以用“一般”这个词,是因为文档里没有规定是这样的,而根据参考和我的尝试——mac Safari 10.0.1、windows Chrome 55.0、android Chrome 55.0、windows Firefox 50.1选择加载第一个大于它的,Microsoft Edge 38选择加载的是 500w ,可能是第一个小于它的也可能是最接近的——我认为一般是选择加载第一个大于它的。)
下面说一个使用百分比的例子:

<img
    srcset=“
        http://placehold.it/2000 2000w,
        http://placehold.it/1500 1500w,
        http://placehold.it/1000 1000w,
        http://placehold.it/500 500w
    "
    sizes=“
        (max-width: 500px) 100vw,
        (max-width: 1000px) 80vw,
        (max-width: 1500px) 50vw,
        2000px
    "
    src="http://placehold.it/500/abc"
/>

这里图片的选择就是: viewport 宽度乘以1或0.8或0.5得到的像素来选择不同的 w 。比如 viewport 为 800px ,对应 size 80vw ,就是 800*0.8=640 像素,应该加载一个 640w 的源图,但是没有找到 640w ,这时候一般选择第一个大于 640w 的,也就是 1000w

对于没有给出 sizes 的,一般是按照 100vw 来选择加载图片。当然这里也是没有规定的、看浏览器的选择的。

picture 元素

picture 元素内部的 sourceimg 的关系像是相片与相框的关系,相框带有一个底图,我很有多不同尺寸(风格)相片,我试图找到第一个合适尺寸(合适风格)的相片放到相框里,如果没有找到就不放相片而用相框本身的底图,当然如果没有相框那就不能挂到墙上去,而 picture 告诉你这个相框只能在这些图片里找合适的。
picture 支持尺寸(媒体查询)和格式选择。
下面是尺寸选择的例子:

<picture>
    <source media="(max-width: 500px)" srcset="http://placehold.it/500” />
    <source media="(max-width: 1000px)" srcset="http://placehold.it/1000” />
    <source media="(max-width: 1500px)" srcset="http://placehold.it/1500” />
    <img src="http://placehold.it/500/abc” />
</picture>

每个 source 是一个选择,媒体查询对应 media ,浏览器找到一个适用的就使用对应的 srcset 里给出的图片,对于不支持 picture 元素的浏览器可以正确的加载 img 。显然,各种 img 的属性、样式什么的也都应该写在 img 里面。
下面是格式选择的例子:

<picture>
   <source type="image/vnd.ms-photo" srcset="http://placehold.it/500” />
   <source type="image/jp2" srcset="http://placehold.it/1000” />
   <source type="image/webp" srcset="http://placehold.it/1500” />
   <img src="http://placehold.it/500/abc” />
</picture>

vnd.ms-photojp2webp 等是一些新的图片格式,不像 pngjpg 等格式获得广泛支持,但它们又有很多优点,这时候要使用的话就要进行格式支持性判断,浏览器也是选择第一个支持的格式加载对应的 srcset 里给的图片,当然对 type 判断以后不管你给的是什么格式的图片都选择加载它,如果给了不符合的另外一个格式的图片也不能再加载后面可能支持的格式了。

对于 picture 有有一点要注意的是, img 的位置会影响最终加载结果。
像下面这样写:

<picture>
    <img src="http://placehold.it/500/abc” />
    <source media="(max-width: 500px)" srcset="http://placehold.it/500” />
    <source media="(max-width: 1000px)" srcset="http://placehold.it/1000” />
    <source media="(max-width: 1500px)" srcset="http://placehold.it/1500” />
</picture>

上面这个例子在我之前提到的浏览器里,我发现它们始终选择加载 img 里的 src 图片,即使 src 的图片不能用。也就是说,相框里的底图和相片的地位同等。
picture 元素也是向后兼容的,不支持该元素的浏览器相当于只看到了 img

参考:
HTML 文档(这个我是在 Dash for macOS 里看的)
[ISUX译]响应式图像

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • 图像(image) 常用的图像文件存储格式: CDR格式 该格式是CoreDraw软件专用的一种图形文件存储格式;...
    我才不是稻草人阅读 1,520评论 0 0
  • 原文“响应式(Responsive)”这个词我想大家没有听过一千遍,也有一百遍了。响应式是指实现不同屏幕分辨率的终...
    Www刘阅读 608评论 0 0
  • 原文链接:https://isux.tencent.com/web-image-application.html ...
    moriarty77阅读 293评论 0 0
  • ❤️ 【经期过长案例分享】 这个客人,女性,约40多岁,2017年02月24日初诊。 主诉:月经从13号开始,正常...
    橙色的房子阅读 164评论 0 1
  • 刚刚出操怎么样都像个没事人 回到寝室看了一本很喜欢的书《我不喜欢这世界,我只喜欢你》 就想起以前不管受了什么委屈,...
    西鸽阅读 197评论 0 0