背景
日常开发中,我们使用固定大小的图片,但是对于不同的设备,设备像素比(dpr)的不同,图片的清晰度会受到影响。
我们可以在img标签中使用srcset和sizes属性来解决这个问题。
1. 不同dpr下图片显示
我们先看一个案例,在正常情况下,我们固定图片的宽高,通过修改设备的dpr看看图片显示问题。
具体步骤如下:
- 新建一个index.html,设置图片宽高为
150px,图片使用宽高为150,(这里图片可以根据最后的数字生成对应大小的图片宽高)
index.html:
<style>
img{
width: 150px;
height: 150px;
}
</style>
<body>
<img src="https://picsum.photos/id/88/150" alt=""/>
</body>
</html>
- dpr为1时,正常显示:
- 将浏览器放大5倍,dpr此时为5(可以使用window.devicePixelRatio查看dpr),图片出现失真情况
这里我们需要理解一下下面的概念:
-
CSS 尺寸
在 HTML 或 CSS 中指定的图片逻辑宽度。通过width或sizes属性定义的值。 -
设备像素比 (DPR)
设备像素比是设备物理像素与 CSS 像素的比值:- DPR = 1:每个 CSS 像素映射到一个物理像素。
- DPR = 2:每个 CSS 像素映射到 2×2 个物理像素。
-
实际像素尺寸
为了确保图片在高 DPR 屏幕上依然清晰,浏览器会请求更高分辨率的图片,实际尺寸公式计算:
浏览器请求对应的图片大小是需要考虑设置的css大小和dpr的大小。
2. srcset属性
srcset 的值是一个字符串,用来定义一个或多个图像候选地址,以 , 分割,每个候选地址将在特定条件下使用。
案例:当我们的宽度固定为150px,我们修改设备的dpr,会使图片拉伸模糊,通过设置srcset这个值,可以将不同dpr,找到合适的图片显示。
具体步骤:
- srcset属性设置标准像素密度 (
2x 3x 4x)下使用的图像版本,默认就是1x可以省略不写
<img src="https://picsum.photos/id/88/150" srcset="
https://picsum.photos/id/88/300 2x,
https://picsum.photos/id/88/450 3x,
https://picsum.photos/id/88/600 4x" alt="" />
- 当放大两倍,此时dpr为2,找到2x对应图片
- 如果放大5倍,此时dpr为5,没有设置对应的图片,会选择适合的4x图片
上面案例是我们固定图片的宽度,当我们使用响应式宽度,图片是如何设置呢?就需要使用我们的sizes属性。
3. sizes属性
sizes 允许您为每个媒体条件指定图像的布局宽度。在布局状态更改以匹配不同介质条件时自动选择不同图像(甚至是不同方向或长宽比的图像)的能力。
案例:我们将图片的宽高设置为50vw 50vh,根据视口变化选择不同的图片。
- dpr为1,变化视口宽度
- dpr为2,变化视口宽度
3.1 未设置前
3.2 设置sizes属性
具体步骤如下:
- srcset中设置对应宽度图片,sizes中使用(max-width)进行匹配
img {
width: 50vw;
height: 50vw;
}
<img src="https://picsum.photos/id/88/150" srcset="
https://picsum.photos/id/88/150 150w,
https://picsum.photos/id/88/300 300w,
https://picsum.photos/id/88/600 600w,
https://picsum.photos/id/88/900 900w,
https://picsum.photos/id/88/1200 1200w" sizes="
(max-width: 300px) 150px,
(max-width: 600px) 300px,
(max-width: 900px) 450px,
(max-width: 1200px) 600px,
1200px" alt="" />
可以简写为:
<img src="https://picsum.photos/id/88/150" srcset="
https://picsum.photos/id/88/300 300w,
https://picsum.photos/id/88/600 600w,
https://picsum.photos/id/88/900 900w,
https://picsum.photos/id/88/1200 1200w" sizes="50vw" alt="" />
- dpr为1时,可以看到在因为不同的dpr对应的匹配是不同的。
浏览器根据视口宽度匹配 sizes 属性中的条件:
(max-width: 300px) 150px: 如果视口宽度 ≤ 300px,图片理想显示宽度是 150px。(max-width: 600px) 300px: 如果视口宽度 ≤ 600px,图片理想显示宽度是 300px。(max-width: 900px) 450px: 如果视口宽度 ≤ 900px,图片理想显示宽度是 450px。(max-width: 1200px) 600px: 如果视口宽度 ≤ 1200px,图片理想显示宽度是 600px。- 如果视口宽度 > 1200px,则使用默认值 1200px。
- dpr为2时
可以看到,视口宽度小于150,也显示300,没有显示150。
因为在高 DPR(设备像素比)环境下,浏览器会选择更高分辨率的图片来确保显示清晰度,不是严格按照视口宽度匹配。
4. 总结
总结一下:图片需要适应不同设备,我们可以使用 srcset 和 sizes 来实现图片高清显示。需要注意是某种情况下并不是严格按照规则进行匹配。
如有错误,请指正O^O!