::before + transform 是唯一可靠实现 ken burns 动画的方案,通过伪元素承载背景图并用 scale() 和 translate() 实现 gpu 加速动画,避免 background-image 相关属性的性能缺陷。

background-image 本身不能做 Ken Burns 动画
CSS 不支持对 background-image、background-size 或 background-position 做高性能动画——这些属性触发重排重绘,且 cover 是关键字,无法插值过渡。直接写 transition: background-size 10s 看不到缩放效果,控制台也无报错,纯属无效。
::before + transform 是唯一可靠方案
把背景图挪到伪元素上,用 transform: scale() 和 translate() 控制动效,GPU 加速、不干扰主内容、兼容性好(Chrome/Firefox/Safari/Edge 均支持)。
-
position: relative必须加在父容器上,否则::before无法绝对定位 -
overflow: hidden要设在父容器,防止放大后边缘溢出 -
z-index: -1确保伪元素在内容下方,不影响点击或文本层 - 动画时长建议 12–16s,太短显突兀,太长难感知;
ease-in-out比linear更自然
示例关键片段:
#form1 > div:nth-child(3) > div > div.wel-video {
position: relative;
overflow: hidden;
}
#wel-video::before {
content: '';
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
background-image: url(images/dahua.jpg);
background-size: cover;
background-position: center;
z-index: -1;
animation: kenburns 14s ease-in-out infinite;
}
@keyframes kenburns {
0% { transform: scale(1) translate(0, 0); }
50% { transform: scale(1.25) translate(-3%, -3%); }
100% { transform: scale(1) translate(0, 0); }
}
全屏场景下必须处理的三个陷阱
全屏(height: 100vh)会让 Ken Burns 效果更容易失效或错位:
- 移动端 Safari 的
100vh包含地址栏高度,窗口进入全屏时高度突变 → 改用min-height: 100vh; height: 100%;并确保所有父级有明确高度 - 图片未加载完成就执行动画,
background-size: cover在伪元素上可能初始渲染异常 → 可加opacity: 0初始态,监听img.onload后再设opacity: 1 - 窗口 resize 后未重算动画关键帧 → 如果你后续要 JS 动态控制缩放比例(比如响应不同 DPR),必须节流监听
resize并更新 CSS 变量
不要用 background-position 动画模拟平移
有人试图用 @keyframes 动画 background-position: 0% 0% → 100% 100% 实现“移动感”,这本质是裁剪式扫过,不是真正的 Ken Burns。它无法配合缩放,视觉生硬,且在高 DPR 屏幕上容易出现像素抖动。真要平移,必须和 scale() 同步走 transform: scale() translate(),否则中心偏移失控。
scale(1.5))会导致边缘明显模糊,尤其 JPG 原图分辨率不高时;放大太小(scale(1.05))又几乎看不出效果。实际项目里,1.2–1.3 是多数情况下的安全区间。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











