filter: pixelate() 是最直接的 CSS 像素化方案,但仅 Safari 16.4+ 原生支持,Chrome 需开启实验标志,Firefox/Edge 不支持;image-rendering: pixelated 仅对缩放位图生效;Canvas 方案最兼容可控,需禁用抗锯齿并正确换算坐标。

filter: pixelate() 是目前最直接、最可控的 CSS 像素化方案,但只在 Safari 和部分新版 Chrome(需开启实验性功能)中可用;绝大多数场景下,你得用 image-rendering: pixelated 或 Canvas 手动实现——别指望纯 CSS 一行代码搞定全浏览器兼容的“真马赛克”。
filter: pixelate() 能不能直接用?
能,但有硬限制:截至 2026 年 5 月,仅 Safari 16.4+ 原生支持,Chrome 需手动开启 chrome://flags/#enable-experimental-web-platform-features,Firefox 和 Edge 完全不支持。启用后可这样写:
img {
filter: pixelate(8px);
transition: filter 0.3s;
}
img:hover {
filter: pixelate(0);
}注意:pixelate() 的参数是像素块边长(非缩放倍数),值为 0 表示无像素化;动画必须配合 transition,且不能和 blur() 等其他 filter 函数混用,否则会降级为 none。
常见错误现象:filter: pixelate(10) 写成无单位数字,或在不支持浏览器里静默失效,页面毫无反应。
立即学习“前端免费学习笔记(深入)”;
image-rendering: pixelated 为什么经常没效果?
因为这个属性只对「被缩放的位图」生效——原图尺寸不变时,它完全不起作用。典型误用:
img { width: 300px; height: 200px; image-rendering: pixelated; } /* ❌ 无效 */正确做法是先放大再缩小,例如:
img {
width: 600px; /* 放大 2x */
height: 400px;
image-rendering: pixelated;
}
img.zoomed {
width: 300px; /* 再缩回原尺寸 */
height: 200px;
}使用场景:适合小图标、像素画、二维码等低分辨率图放大展示;对照片类大图效果生硬,且无法做过渡动画。
- 必须确保图片真实被缩放(CSS 尺寸 ≠ 原图 intrinsic size)
- 移动端 Safari 对该属性支持不稳定,iOS 17 以下可能忽略
- 不能和
transform: scale()混用,后者绕过image-rendering控制
Canvas 实现可控马赛克的关键三步
这是真正跨浏览器、可编程、支持局部打码的方案,核心不在滤镜而在像素重采样。
容易踩的坑:
-
getImageData()会因跨域抛SecurityError,本地双击 HTML 文件必失败,必须走http://服务(如python3 -m http.server) - 直接
putImageData()放大无效——它只是贴图,不会重复像素;得用drawImage()+ctx.imageSmoothingEnabled = false - 鼠标坐标未校准:DOM 坐标 ≠ canvas 像素坐标,必须用
getBoundingClientRect()换算
简短示例(块大小 16px):
const ctx = canvas.getContext('2d');
ctx.imageSmoothingEnabled = false;
for (let y = 0; y < img.height; y += 16) {
for (let x = 0; x < img.width; x += 16) {
ctx.drawImage(img, x, y, 16, 16, x, y, 64, 64);
}
}性能提示:块尺寸越大越快,但边缘锯齿明显;blockSize = 8 是清晰度与速度的合理起点。
哪些方案看起来像马赛克,其实不是?
很多“伪马赛克”靠背景渐变或 SVG 模拟,它们本质是装饰层,不改变原图像素数据:
-
background: linear-gradient(...)叠加在图片上:只能做固定格子,无法随图片内容变化 -
backdrop-filter: blur()+radial-gradient():是模糊+噪点,不是像素块 - Base64 编码的 PNG 网格图作背景:静态纹理,和图片内容无关
这些方案轻量、兼容性好,但如果你需要“对人脸实时打码”或“点击区域马赛克切换”,它们就完全失效——真正的问题从来不是“怎么看起来像”,而是“怎么让像素真的变成块”。



















