现代css倒影应弃用已失效的-webkit-box-reflect,优先采用::after伪元素+transform:scaley(-1)方案;需配合position:relative容器、mask-image渐隐及canvas/svg备用方案。

-webkit-box-reflect 已失效,别再用它了。现代浏览器(Chrome 90+、Firefox 100+、Edge 110+、Safari 15.4+)中该属性要么被移除,要么行为不可靠,写上去等于没写。
用 ::after 伪元素 + transform: scaleY(-1) 最实用
这是目前兼容性最好、代码最轻、维护成本最低的方案,适用于静态图、商品列表、悬停触发等大多数场景。
- 必须把原图包在
position: relative容器里,否则伪元素无法精确定位 -
::after要设content: ""、position: absolute、top: 100%、width: 100%,高度按需设(常见height: 60%) - 翻转前加
transform-origin: top,避免倒影上下错位 - 渐隐不能只靠
opacity:要用mask-image: linear-gradient(to bottom, black, transparent)或-webkit-mask-image,否则边缘生硬 - Safari 对
mask-image支持稳定,Chrome 没问题,Firefox 需开启layout.css.masking.enabled(生产环境慎用)
canvas 绘制倒影适合需要像素级控制的场景
比如生成分享海报、动态水波扭曲、或倒影要叠加模糊+色偏等后处理效果时,canvas 是唯一靠谱路径。
- 必须监听
img.onload,否则drawImage读不到像素,画布为空白 - 别直接
ctx.drawImage(img, x, y, w, h)翻转——它不支持镜像;正确做法是ctx.translate(0, imgHeight * 1.1)+ctx.scale(1, -1)+ctx.drawImage(img, 0, 0) - 倒影高度建议为原图的
0.3–0.5倍,过长会失真 - 渐变遮罩用
ctx.createLinearGradient(0, 0, 0, canvas.height),从顶部不透明到底部全透明 - 多个相同图片重复渲染?用
Map缓存src → canvas映射,避免重复绘制
SVG 方案适合批量静态图且不想引入 JS
把原图和倒影都塞进同一个 <svg></svg>,用 <image></image> 引入(不是 HTML <img>),再配 transform="scale(1,-1)" 和 <fegaussianblur></fegaussianblur>。
- 倒影
y坐标必须手动调:比如原图y="0",倒影就得设y="120"(假设原图高 100px + 间距 20px),否则会叠在原图上 -
<fegaussianblur></fegaussianblur>的stdDeviation控制模糊度,值超过3在移动端易掉帧 - 不支持 IE,但 Chrome/Firefox/Edge/Safari 16+ 全兼容
- 无法响应
:hover动态切换——滤镜是静态定义的,不能靠 CSS 触发开关
真实项目里最容易被忽略的点:倒影不是“画出来就完事”,而是要匹配内容生命周期。图片懒加载、宽高未定、服务端返回 base64 图片、甚至 img.naturalWidth === 0 的瞬间,都可能让翻转坐标算错或 canvas 空白。别省那几行判断逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











