响应式图片
devicePixelRatio推荐阅读:https://developers.google.com/web/fundamentals/design-and-ux/responsive/images?hl=zh-cn
Img 的 sizes 和 srcset
<img src="100.png" sizes="50%" srcset="100.png 100w, 200.png 200w, 400.png 400w">
sizes
这个属性可以写一些css,例如“100px”,“50vm”,‘20rem","30vm",甚至是媒体查询 "(min-width: 600px) 25vw, (min-width: 500px) 50vw, 100vm"。
srcset
顾名思义,就是一堆图片来源的预设。例如:“100.png 100w”, 表示预设 100.png 这张图片,并且告诉浏览器,这张图片的宽度是100。
我们来看看mdn的描述:
这个“x”,其实就是我们的像素密度(window.devicePixelRatio),一般windows的机子都是1,苹果的机子是2(得益于它们的Retina屏)。
选择策略
以上面的例子来说:<img src="100.png" sizes="50%" srcset="100.png 100w, 200.png 200w, 400.png 400w" />
1. img 的 sizes 是父元素的 50%(注意这个 sizes 和实际渲染的大小无关),假设父元素宽度是210px,我们计算到 sizes 是 105px。
2. 计算每一张候选图片的 “x" 值,100.png --> 100/105,200.png --> 200/105,400.png --> 400/105
3. 假设我们是用不起 macbook 的穷人,我们的 devicePixelRatio 是 1,也就是说我们屏幕的 “x”值 就是 1
4. 发现比较接近 1 的有 2 个:100/105 < 1 < 200/105
5. 往上取最近的一个: 200.png --> 200/105 (因为如果选100的话,浏览器就认为把100px放到105px中显示,图片会失真,因此,浏览器会选一张不会失真的图片)
ps: 是不是觉得很难理解,没关系。因为这个很难用,所以 H5 它又推出了 Picture 标签。
Picture标签
Picture是H5的新标签,除了IE,其他浏览器都基本兼容了,不用考虑IE的童鞋,推荐使用Picture。
它抛弃了 sizes 属性,srcset 也不用 w 单位了,直接用媒体查询和像素密度来作为判断依据。
这样就清晰明了多了。
<picture> <source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x"> <source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x"> <img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x"> </picture>
上面的例子中:
如果浏览器宽度至少为 800px,则将根据设备像素密度使用 head.jpg
或 head-2x.jpg
如果浏览器宽度在 450px 和 800px 之间,则将根据设备像素密度使用 head-small.jpg
或 head-small-2x.jpg
对于屏幕宽度小于 450px,且不支持 picture
元素向后兼容的情况,浏览器将渲染 img
元素,因此要始终包含该元素。