配了八年 GIF,每次想暂停它都要写一堆 JS——今天 CSS 一个属性把这件事彻底原生化了
网页里 GIF 和 WebP 动图默认自动播放、无限循环,想让用户自己暂停?以前只能靠 JavaScript 监听交互再切换 src 或用 canvas 重绘。CSS Image Animation 模块给这件事写进了浏览器原生能力,一个属性搞定。
问题:动图控制一直是 JS 的活儿
CSS 能控制文字、盒子、动画帧,但管不了 GIF/WebP/APNG 自己怎么播。用户打开页面,动画自己跑;想让它停?要么浏览器全局设置,要么写一坨 JS 手动干预。这在无障碍场景下尤其尴尬——prefers-reduced-motion 用户希望能暂停页面上非必要的动效,但开发者根本没有标准手段。
方案:image-animation + :animated-image
CSS Image Animation Module Level 1 刚进 Chrome 154(其他浏览器还在跟进),给了两个新东西:
image-animation 控制播放行为,三个值:
/* 默认行为,动图正常播 */
img { image-animation: normal; }
/* 暂停在当前帧 */
img { image-animation: paused; }
/* 强制播放,不与其他实例同步 */
img { image-animation: running; }
:animated-image 伪类匹配实际加载了动图的 <img> 元素——只有当图片真的是动图时才生效,静态图不匹配。这让你可以精准地给「会动的图」加 UI,不用担心静态图也被套上样式。
一个真实场景的用法:
/* 全局:装饰性动图默认暂停 */
:root { image-animation: paused; }
/* 内容图保持正常播放 */
img.content { image-animation: normal; }
/* 给所有动图加一个浏览器原生的播放提示 */
img:animated-image::after {
content: "▶";
position: absolute;
bottom: 4px;
right: 4px;
font-size: 10px;
color: white;
background: rgba(0,0,0,0.5);
border-radius: 3px;
padding: 2px 4px;
pointer-events: none;
}
配合 prefers-reduced-motion 的正确姿势:
@media (prefers-reduced-motion: reduce) {
:root { image-animation: paused; }
/* 重要的 loading 动图保持播 */
.loading-indicator { image-animation: normal; }
}
image-animation: running 还有一个细节:同 URL 的动图在同一元素内会同步播放,但切到 running 后会解除同步,每个实例独立走自己的时间线。这在做「同一动图多个实例各自播各自的」场景下很有用。
三个落地下一步
- 先做无障碍降级:把
image-animation: paused写到全局根规则,配合prefers-reduced-motionmedia query,先让有需求的用户不受干扰 - 用
:animated-image做 play/pause 切换:给动图包一层,hover 时切running,离开切paused,不用任何 JS 就能实现基础的交互控制 - 审计页面动图:跑一遍线上页面,找出哪些 GIF 是装饰性(可暂停)哪些是内容性(应保持播),分类套用不同策略
现在 Chrome 154+ 已稳定,Safari 也在路上。零 JS 成本地把动图控制权拿回来,这件事 CSS 今天自己会了。
评论区
0 条评论
登录后可评论。