关于srcset & sizes的资料其实很多,但也很少,其中详细讲解其选择图片的机制的文章,更是少数了,连MDN都是粗粗一笔带过,到底哪里文章说的是正确的,哪里有误导人的,其实很难找到一个参考。html
因而乎本身亲自去动手研究一下了,不能光看资料,可信度仍是值得考虑。git
固然出于本人能力限制,也许研究不够透彻致使带来的错误之处,请多多指出,本人虚心请教。github
H5中img有两个新属性,srcset
和sizes
,主要做用:chrome
文本有一些名词概念,可能须要事先有了解,方能更好的理解。可先大体浏览此 你得知道的各类像素、分辨率等概念浏览器
(1)格式一:图片源地址 空格 图片像素宽度[, 图片源地址 空格 图片像素宽度, ...],如bash
srcset="1.jpg 580w, 2.png 618w"
复制代码
表示图片1.jpg
的像素宽度为580px
,图片2.png
的像素宽度为618px
,两个图片源之间用逗号隔开。测试
千万注意:描述图片的像素宽度是用'w'单位,且必定要是图片的真实像素宽度,若是私自改动,那么会影响浏览器对图片的选择!spa
其实上述例子相似给了个默认的sizes
属性(具体下面再讲)code
srcset="1.jpg 580w, 2.png 618w" sizes="100vw"
复制代码
(2)格式二:图片源地址 空格 屏幕像素密度[, 图片源地址 空格 屏幕像素密度, ...],如htm
srcset="1.jpg 1x, 2.png 2x"
复制代码
表示图片1.jpg
为DPR为1时下显示的图片;2.png
为DPR为2时显示的图片,若是没有更大的DPR设置的图片源,那么当大于当前设置的DPR最高值时,会采用当前设置的最大DPR的图片源。如这里若是屏幕DPR为3,那么仍是会用2.png
。
在浏览器支持srcset
的状况下,src
值就成为了一个1x
状况下的候选图片,在没有符合条件的状况下,会采用该值。
关于'x'的图片选择,很简单,按照上述规则就行了。可是关于'w'的图片选择,就没有那么单纯了,须要结合下述的sizes
属性一块儿来分析。
只有当设置了srcset
,且单位为w
时,sizes
的设置才会起效。浏览器究竟是怎么选择图片的呢,是先根据sizes
设定的条件下,找出此刻图片显示的宽度,而后根据这个宽度去srcset
里找符合条件的图片。
什么样的才是叫符合条件呢?
srcset中设置的图片像素宽度('w'的值),组成了相应的半开半闭区间(a, b]。 图片的显示宽度(sizes规定的值)看落在哪一个区间内,取区间中最大值对应的图片。若没有最大值(如∞),则取上个区间最大值。
如
<img src="4.jpg" srcset="3.jpg 229w,2.png 618w,1.jpg 1000w", sizes="300px">
复制代码
上面设置图片要显示成300px
(sizes
里的值),在srcset
里的几个临界值中造成了(0, 229px]
、(229px, 618px]
、(618px, 1000px]
、(1000px, ∞]
。300px
落在了(229px, 618px]
中,取最大值618
,所以最终选择的图片就是2.png
若是sizes
改为1200px
,按照上述规则,最终会选取1000w
的1.jpg
注意:srcset里的顺序不重要,不会受到影响。
好了,咱们知道浏览器的选取规则。仍是说一下sizes
的语法结构:
[媒体查询 空格 ]图片显示宽度[, [媒体查询 空格 ]图片显示宽], ..., 其他条件宽度值]
图片的宽度值单位不能为%
,其他正常单位可使用
举例:
sizes="(max-width: 500px) 400px, (max-width: 900px) 700px, 1200px"
复制代码
上面的意思就是,在屏幕小于等于500px状况下,图片显示成400px宽;在屏幕小于等于900px状况下,图片显示成700px宽;其他状况显示成1200px宽。
所以,可根据这种sizes
值,判断在哪一个屏幕大小下显示什么宽度的图片,而后根据这个宽度值去srcset
里找知足条件的图片源。
这个例子
<img src="4.jpg" srcset="3.jpg 229w,2.png 618w,1.jpg 1000w", sizes="(max-width: 500px) 400px, (max-width: 900px) 700px, 1200px">
复制代码
在屏幕小于等于500px状况下,图片显示成400px宽,选取2.png
;在屏幕小于等于900px状况下,图片显示成700px宽,选取1.jpg
;其他状况显示成1200px宽,仍是选取1.jpg
。
注意:sizes里的媒体查询条件顺序是很重要的,只要知足了越靠前的某个条件,那么后面的条件会被忽略的
还有,若是sizes
属性没有值,或者在有媒体条件下,其他条件宽度没有设值,那么默认是100vw
<img src="4.jpg" srcset="3.jpg 229w,2.png 618w">
<!--等同于-->
<img src="4.jpg" srcset="3.jpg 229w,2.png 618w" sizes="100vw">
复制代码
<img src="4.jpg" srcset="3.jpg 229w,2.png 618w", sizes="(max-width: 500px) 400px">
<!--等同于-->
<img src="4.jpg" srcset="3.jpg 229w,2.png 618w", sizes="(max-width: 500px) 400px, 100vw">
复制代码
这种时候,就是直接根据屏幕的宽度来决定选取哪一个图片源了。
上述内容,都是在DPR为1的状况下说明的,主要针对PC端吧。那若是是手机端,DPR不仅仅是1,还有2,3的状况。这时候其实上述内容的规则仍是不会变的,可是咱们须要作一些值的转化才能套用上述规则。这里主要是说'w'的状况下浏览器如何去选择
以该例子说明
<img src="4.jpg" srcset="3.jpg 229w,2.png 618w" sizes="(max-width: 600px) 114px">
复制代码
首先咱们要知道,srcset里的'w'符号,是表明的是图像的宽度像素,是个物理像素;sizes里的114px是表示逻辑像素!
而浏览器对图片的选择,是要转化为同一律念上的像素才能进行对比的,总不能拿着逻辑像素值去物理像素区间里作比较吧?
所以,在DPR不为1时,要转化一下像素值才能去区间里比较,套用上述规则。
如在DPR=2时,把114px转化为物理像素,即114px * 2 = 228px,用228px去(0, 229px]、(229px, 618px]、(618px, ∞]里作比较,落在了(0, 229px]中,取229px对应的3.jpg
若是你想用这两个属性好好控制图片,那你得遵循好如下规范,否则不少效果是你难以预测获得的,毕竟那么多浏览器,兼容性也各自不一样。
都是关于srcset
的值的规范:
若是你不信这个规范,毕竟不少其余文章没这么要求限制,你不免会产生怀疑,虽然打破这些规范,浏览器可能也会显示某种规律,可是,考虑到浏览器的兼容性问题,实在不建议不按照上述要求写。
【这块内容无关重要】 如下是我亲测的一些状况。感兴趣的你本身也能够试试看,固然我这里测试的浏览器有限
这里能够看到一个大致的状况: 兼容性
但还有一些值得一说的内容,毕竟上面的连接里是没有的
在chrome屏幕变化时(如你拖动浏览器窗口),图片能从设置的小屏到大屏进行图像替换,但大屏往小屏变化,不会进行图片替换。
以下述例子,从低于500px宽度的屏幕上是1.jgp,屏幕变化到500px-900px时,图片会替换为2.png,到900px以上的屏幕时,替换为3.jpg;但从900px上 -> 500px-900px -> 500px下,图片却不会进行替换。
<img src="4.jpg" srcset="1.jpg 400w,2.png 600w,3.jpg 900w">
复制代码
但Firefox不存在chrome的从大屏到小屏图片不替换的问题。
360浏览器支持很差,只会显示srcset中的最大屏的图片,如上述例子中的3.jpg
<img src="4.jpg" srcset="3.jpg 3x,1.jpg 2x">
复制代码
未经容许,请勿私自转载