srcset 和 sizes 让浏览器按设备像素比和布局宽度自主选图:srcset 提供带 w/x 的候选图,sizes 定义图片显示宽度,二者配合避免模糊;需避免混用单位、缺失 sizes、仅用 x 描述,且 WebP/AVIF 必须用 picture 回退,同时保留 width/height 防布局偏移。

用 srcset 和 sizes 让浏览器自己选图
高分辨率屏(如 Retina、Windows HiDPI)下,普通 <img> 会模糊,本质是像素密度翻倍但图片没跟上。浏览器需要知道“这张图在不同设备宽度或像素比下该加载哪张”,srcset 就是干这个的——它不强制指定屏幕类型,而是提供一组候选资源和它们的宽度/像素密度描述,由浏览器按当前 devicePixelRatio 和布局宽度自主选择。
关键不是堆高清图,而是给对的信息:
-
srcset中每个选项必须带w(自然宽度)或x(像素比),不能混用;混用会导致整个属性被忽略 -
sizes必须存在才能用w单位,否则浏览器无法换算物理宽度 → 像素比映射 - 不要只写
2x:单靠x描述无法适配响应式布局(比如图片在小屏占满宽度、大屏只占 50%)
<img
src="photo-400w.jpg"
srcset="photo-400w.jpg 400w,
photo-800w.jpg 800w,
photo-1200w.jpg 1200w"
sizes="(max-width: 480px) 100vw,
(max-width: 960px) 50vw,
33vw"
alt="风景">避免 background-image 在 CSS 里硬写多套分辨率
CSS 的 background-image 没有原生 srcset,强行用 @media 写多套规则容易漏覆盖、难维护,且无法利用浏览器的预加载机制(<img> 的 srcset 能在 HTML 解析阶段就发起请求)。
真正可行的方案只有两个:
立即学习“前端免费学习笔记(深入)”;
- 改用
<picture>+<source>,把背景图逻辑前移到 HTML 层(适合语义化图片,比如 banner) - 用
image-set()函数(Chrome 21+/Safari 6.1+/Edge 12+ 支持,Firefox 仅支持url()fallback)
.hero {
background-image: image-set(
"hero-1x.jpg" 1x,
"hero-2x.jpg" 2x,
"hero-3x.jpg" 3x
);
/* Firefox fallback */
background-image: url("hero-1x.jpg");
}注意:image-set() 不支持宽度描述(w),也不触发预加载,纯靠运行时计算,对首屏性能不友好。
WebP / AVIF 图片必须配合 <picture> 回退
高分辨率图体积更大,用 WebP 或 AVIF 能压掉 30–50% 大小,但它们不被所有浏览器支持。直接替换 src 会挂掉旧浏览器,必须用 <picture> 显式声明回退链。
顺序很重要:浏览器从上到下匹配第一个支持的格式,所以最新格式放最上面:
<picture> <source srcset="photo.avif" type="image/avif"> <source srcset="photo.webp" type="image/webp"> <img src="photo.jpg" srcset="photo-400w.jpg 400w, photo-800w.jpg 800w" alt="风景"> </picture>
别忘了:每个 <source> 仍要配 srcset 和 sizes,否则高分屏下 WebP/AVIF 版本依然会模糊。
工具链里别漏掉 width 和 height 属性
现代 CSS 容器查询和 aspect-ratio 可以控制宽高比,但很多 CMS 或构建工具生成的 <img> 还是空着 width/height。这会导致:
- 页面加载时图片区域无尺寸,触发 layout shift(CLS 指标变差)
- 浏览器无法准确估算图片渲染所需空间,影响
sizes计算精度 - 某些懒加载库(如 native
loading="lazy")依赖尺寸做可视区判断
安全做法:在 HTML 中写上原始图片的固有尺寸(不是 CSS 设置的尺寸),让浏览器提前 reserve 空间:
<img
src="photo-400w.jpg"
srcset="photo-400w.jpg 400w,
photo-800w.jpg 800w"
sizes="100vw"
width="400"
height="300"
alt="风景">如果图片比例固定,也可以用 aspect-ratio: 4/3 配合 width: 100%,但前提是确保父容器有明确宽度约束——这点很容易在 flex/grid 布局中失效。










