picture 元素经常被当成「带多个 src 的 img」来用,样式与尺寸照习惯写在最外层,结果大半不生效。理解它的三层结构之后,写法就不容易错。

规则一:picture 不产生盒子
picture 是纯粹的容器,自身不渲染框,宽度高度、边框、圆角、object-fit 都不作用在它身上。真正承载图像的是末尾的 img,样式一律写在那一层:
picture { display: block; } /* 只做行内元素的流式修正 */
picture img {
width: 100%;
height: auto;
border-radius: 8px;
object-fit: cover;
}
给 picture 加边框、加背景图、加 max-width,样式表不会报错,页面上也没有变化。
规则二:source 自上而下匹配,命中即停
<picture>
<source type="image/webp" media="(min-width: 900px)" srcset="wide.webp">
<source type="image/webp" srcset="narrow.webp">
<source media="(min-width: 900px)" srcset="wide.jpg">
<img src="fallback.jpg" alt="封面">
</picture>
浏览器按顺序检查每个 source 的 media 与 type,第一个同时满足条件的 source 被采用,后面的不再检查。把宽屏条件写在窄屏之后,窄屏条件会永远先命中,宽屏资源拿不到。
规则三:sizes 写在 img 上
<img src="cover-800.jpg"
srcset="cover-800.jpg 800w, cover-1600.jpg 1600w"
sizes="(max-width: 700px) 100vw, 720px"
alt="封面">
sizes 描述资源在版式中的实际宽度,属于最终被渲染的那张图。写在 source 上也能解析,但两处同时写且不一致时,调试会很难归因,统一写在 img 上。
四类无效写法
- 给 picture 设 border、border-radius、box-shadow;
- 给 source 加 class 或 id,期待 CSS 命中;
- 在 source 上写 src 属性,真正生效的是 srcset;
- 省略末尾 img,picture 不会渲染任何内容。
检查清单
- 样式选择器以 picture img 结尾;
- source 顺序按条件从严到宽排列;
- sizes 只出现一次且写在 img 上;
- 末尾 img 的 src 与 alt 都在。
