picture标签需包含至少一个img作为强制fallback,且source必须置于img前;media用于断点适配,srcset+sizes实现分辨率响应式加载;IE不支持,需降级处理。

picture标签的基本结构和必要子元素
picture 本身不渲染内容,它只是容器,真正起作用的是里面的 source 和 img。必须有且仅有一个 img 作为兜底,否则页面会留空——这是最常见的“写了picture却没显示图片”的原因。
-
source元素必须写在img之前,浏览器按顺序匹配,遇到第一个满足条件的就停止 - 每个
source至少要提供media或srcset(或两者),否则会被忽略 -
img的src和alt仍需保留,它不是可选的“备用”,而是强制的 fallback
用 media 属性做断点式屏幕适配
适合按视口宽度切换完全不同构图的图片(比如桌面端用横幅图,移动端用裁剪后的竖构图)。
-
media值是 CSS 媒体查询语法,例如(max-width: 768px),注意括号不能省 - 匹配逻辑是“从上到下”,所以要把更具体的规则(如
(min-width: 1200px))放在前面,宽泛的(如(max-width: 768px))放后面 - 不支持
media="(prefers-color-scheme: dark)"这类非尺寸特性单独驱动图片切换——它只管尺寸,其他特性得靠 JS 或 CSS 配合
<picture> <source media="(min-width: 1200px)" srcset="hero-desktop.jpg"> <source media="(min-width: 768px)" srcset="hero-tablet.jpg"> <img src="hero-mobile.jpg" alt="活动主图"> </picture>
用 srcset + sizes 实现响应式分辨率适配
这才是解决“同一张图、不同像素密度/视口宽度下加载合适尺寸”的主流方式,比单纯用 media 更精细。
-
srcset列出多个资源及其宽度描述符,例如"small.jpg 480w, medium.jpg 768w, large.jpg 1200w" -
sizes告诉浏览器“在不同视口下,这张图预计占多宽”,例如sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 33vw" - 浏览器结合
sizes计算出目标渲染宽度,再从srcset中选最接近的资源,不依赖 JS 或 UA 判断
容易漏掉的是 sizes:如果只写 srcset 不写 sizes,浏览器默认按 100vw 计算,结果可能在窄屏下加载了大图。
立即学习“前端免费学习笔记(深入)”;
常见错误与兼容性注意点
- 把
img 写成自闭合标签:<img src="x.jpg" /> ❌,必须写全 <img src="x.jpg" alt="">,否则部分 Safari 版本会忽略整个 picture
- 在
source 上误加 src:它只认 srcset 和 media,src 属性会被静默忽略
- 以为
picture 能自动压缩或转格式:它不处理编码,type="image/webp" 只是提示浏览器“如果支持就用这个”,不支持时仍会回退到 img 的 src
- IE 完全不支持
picture,哪怕加了 polyfill(如 picturefill),也建议在构建流程中对关键图片额外输出 jpg 备份,并用 <img> 直接降级
img 写成自闭合标签:<img src="x.jpg" /> ❌,必须写全 <img src="x.jpg" alt="">,否则部分 Safari 版本会忽略整个 picture
source 上误加 src:它只认 srcset 和 media,src 属性会被静默忽略picture 能自动压缩或转格式:它不处理编码,type="image/webp" 只是提示浏览器“如果支持就用这个”,不支持时仍会回退到 img 的 src
picture,哪怕加了 polyfill(如 picturefill),也建议在构建流程中对关键图片额外输出 jpg 备份,并用 <img> 直接降级实际项目里,最常被低估的是 sizes 的动态性——它写死在 HTML 里,但如果你的图片宽度受 CSS Grid 或 JS 布局影响,那它很可能不准。这时候不如直接用 JS 控制 img.src。



















