结论:image-rendering不修复锯齿,仅切换插值算法;pixelated仅放大生效,缩小退回到auto导致模糊,应改用crisp-edges实现双向禁用插值,且须作用于或背景容器,避开transform、flex隐式缩放及canvas等无效场景。

直接说结论: image-rendering 本身不“修复锯齿”,它只是切换插值算法;真正起效的前提是——你用对了值、用对了场景、没被其他 CSS 干扰,而且图片本身是位图(非 SVG)。
为什么加了 image-rendering: pixelated 还是模糊?
这不是 bug,是规范行为:pixelated 只在**放大时生效**,缩小就退回到 auto(双线性插值),结果就是发灰、边缘糊。常见于:
- 响应式中把 64×64 图标缩到 32×32 显示
- Retina 屏下 CSS 尺寸未做 dpr 适配,实际渲染尺寸被浏览器自动缩小
- 父容器用了
flex或grid,导致图片被隐式挤压(比如max-width: 100%+ 容器变窄)
此时应换用 crisp-edges —— 它是目前唯一能在**放大和缩小两个方向都禁用平滑插值**的标准值,效果接近最近邻,硬边保留好。
crisp-edges 和 pixelated 怎么选?
关键看你要什么效果,不是哪个“更高级”:
-
crisp-edges:适合图标、像素文字截图、UI 线条图——目标是锐利、无色边、不失真,缩放双向都稳 -
pixelated:只用于明确要“马赛克感”的放大场景(如 16×16 像素图放大到 128×128),禁止任何缩小逻辑 - 别混用:同时写
crisp-edges和pixelated没意义,后者会被前者覆盖(CSS cascade 规则) - 兼容性补丁:Safari 旧版需加
image-rendering: -webkit-optimize-contrast,但新项目可省略
哪些地方加 image-rendering 才有效?
它只对最终合成阶段的栅格内容起作用,不是万能开关:
- ✅ 有效:直接作用于
<img>元素、background-image的<div> <li>❌ 无效:<code><canvas></canvas>元素本身(哪怕你给 canvas 加了image-rendering: pixelated)——Canvas 内部绘制由ctx.imageSmoothingEnabled = false控制 - ❌ 无效:CSS
transform: scale()缩放会绕过image-rendering,必须用width/height控制原始尺寸 - ⚠️ 注意时机:必须等图片加载完成(
img.onload后)再设置样式,否则可能不生效 - 父容器用了
overflow: hidden+border-radius,导致浏览器开启 subpixel 渲染,插值逻辑被重置 - CSS 中同时设置了
object-fit: cover和width/height,触发两次缩放(先按比例裁切,再拉伸填充),image-rendering只管第二次 - 图片是 JPEG,且压缩率过高(比如 30%),本身高频细节已丢失,再怎么调插值也救不回
- 在 Chrome DevTools 里手动修改样式能看到效果,但实际页面加载时因 CSS 优先级或 JS 动态插入顺序,被其他规则覆盖
容易被忽略的干扰项
即使写了 crisp-edges,也可能白搭:
最稳妥的做法:位图素材尽量用 PNG(无损),缩放前确认原始尺寸与目标尺寸为整数倍关系,crisp-edges 配合 width/height 显式声明,避开 transform 和 flex 隐式缩放。











