加了 max-width: 100% 后图片变糊,根本原因是浏览器在高 dpr 屏上拉伸低分辨率图,srcset 未生效(w 描述符误用或路径错误)、image-rendering 被 ui 框架重置为 smooth/crisp-edges,或使用 background-image(不响应 srcset 和 image-rendering)。

加了 max-width: 100% 后图片变糊,不是 CSS 写错了,而是浏览器在高 DPR 屏上拉伸了低分辨率图——max-width 只控制布局尺寸,不触发高清资源加载,也不改变渲染插值方式。
srcset 没生效:w 描述符误用导致永远加载 1x 图
多数人写了 srcset 却没起作用,是因为用了 w 描述符但没按物理像素写宽。比如 iPhone 14 视口 CSS 宽是 390px,DPR=3,若写 srcset="a@1x.jpg 390w, a@2x.jpg 780w",浏览器会认为“780w 图只在 780px 宽屏幕才用”,结果永远选第一张。
- 简单场景直接用
x描述符:<img src="a@1x.jpg" srcset="a@1x.jpg 1x, a@2x.jpg 2x, a@3x.jpg 3x"> - 必须用
w(如配合sizes)时,srcset中的宽度要按物理像素算:390px × 3 =1170w,对应图尺寸应为 1170×… - 别混用
w和x,浏览器会忽略x部分 - 构建工具(Vite/webpack)不解析
srcset路径,需手动确保a@2x.jpg文件存在且路径一致
image-rendering 被覆盖:UI 框架悄悄重置了渲染行为
给 <img> 加了 max-width: 100% 后,某些 UI 框架(如 Tailwind 默认配置)或重置样式表会注入 image-rendering: smooth 或 crisp-edges,反而破坏默认插值逻辑。
- 显式覆盖:用
img { image-rendering: -webkit-optimize-contrast; image-rendering: crisp-edges; } -
-webkit-optimize-contrast在 Safari/iOS 最稳,crisp-edges是 Chrome/Firefox fallback - 避免写
smooth或留空——那是默认双线性插值,正是模糊源头 - 这个属性只影响已加载图片的渲染质量,不改变
srcset选图逻辑
背景图用错方案:background-image 不响应 DPR
如果模糊的是 background-image,max-width: 100% 根本不起作用——背景图不走 srcset,也不响应 image-rendering。
- 优先换成
<img>+object-fit:<img src="bg.jpg" srcset="bg@2x.jpg 2x" style="max-width:90%"> - 非要用 CSS 背景图,必须三层兜底:
background-image: url("bg@1x.jpg");→background-image: -webkit-image-set(url("bg@1x.jpg") 1x, url("bg@2x.jpg") 2x);→background-image: image-set(url("bg@1x.jpg") 1x, url("bg@2x.jpg") 2x); -
-webkit-版本必须放在最前,否则 Safari 16.4+ 可能跳过整条声明 - 路径必须用
url()包裹,含@的文件名如"bg@2x.jpg"必须加引号
最容易被忽略的是:父容器有 transform、scale 或 flex/grid 布局偏差时,max-width: 100% 算出的实际渲染尺寸 ≠ 原始像素尺寸,image-rendering 就失效了;而 background-image 在任何情况下都不认这个属性——它只认 media query 或 image-set(),且后者在 Firefox 完全不支持。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











