直接写max-width: 100%仍撑破容器,是因为该属性需明确参照宽度,而父容器未设宽、flex/grid中min-width: auto默认值或grid列锁死最小宽度,均导致图片失去缩放基准。

为什么直接写 max-width: 100% 还是撑破容器
这不是 CSS 写错了,而是浏览器在计算 max-width: 100% 时,需要一个明确的“参照宽度”。如果父容器没设宽、或处于 Flex/Grid 中默认 min-width: auto,图片就找不到可缩放的基准,结果还是按原始尺寸渲染。
- 常见失效场景:
<div><img src="big.jpg"></div>,但外层<div> 没设 <code>width或max-width - Flex 子项必须加
min-width: 0(加在父容器的 flex item 上,不是<img>本身) - Grid 中若列定义为
minmax(400px, 1fr),会锁死最小宽度,导致图片无法收缩 - 老 iOS(max-width: 100% 支持不稳定,需补
width: 100%并配合height: auto - 正确做法:打开 DevTools → Elements → 选中
<img>→ 右侧 Computed 面板查width值,在每个断点下记下像素值,再换算成vw或固定px - 媒体条件必须和 CSS 媒体查询严格一致:
(max-width: 768px)就不能写成(max-width: 767px)或(max-width: 769px) - 兜底值不能带媒体条件,
33vw合法,(min-width: 769px) 33vw是无效语法 - 旧版 Edge 对空格敏感,建议写成
(max-width:768px)而非(max-width: 768px) - 用 ImageMagick 批量生成:
convert huge.tiff -resize 768x -quality 85 -interlace Plane 768w.jpg - 务必加
-interlace Plane输出渐进式 JPEG,首屏可快速模糊呈现 - 优先输出 AVIF:
convert huge.tiff -resize 768x -quality 60 -define avif:lossless=false 768w.avif,体积比 JPEG 小 40%+ - 禁止上线 TIFF/PNG 原图——无压缩、无流式解码支持,手机极易内存溢出白屏
-
loading="lazy"必须加——首屏外图片延迟加载,避免阻塞初始渲染 -
decoding="async"必须加——把解码任务扔到后台线程,UI 不卡顿 - 二者缺一不可:
<img src="1920w.jpg" loading="lazy" decoding="async"> - 如果用
<picture></picture>,属性要写在<img>标签上,不是<source></source>
sizes 值写错会导致加载完全失准
浏览器只认 sizes 里写的数字,不看 CSS 渲染后的实际宽度。你写了 sizes="100vw",它就真按视口全宽选图——哪怕图片只占 320px 宽,也大概率加载 3840w 版本。
大图必须服务端预生成多尺寸 JPEG/AVIF
前端无法实时压缩或降采样。所有响应式能力都依赖服务端已产出的多档位文件。跳过这步,srcset 和 sizes 就只是摆设。
loading="lazy" 和 decoding="async" 不是可选项
170MB TIFF 加载时主线程直接卡死,用户点不动、滑不了。这两个属性是硬性保障,不是锦上添花。











