data-animate-image
Play/pause control for animated images. Add data-animate-image to any GIF, WebP, or APNG for a toggle button with automatic reduced-motion support.
Overview
The data-animate-image attribute adds a play/pause toggle button to animated images. Users can stop distracting animations with a single click, and the image automatically pauses when prefers-reduced-motion is active.
<img src="animation.gif" data-animate-image alt="Animated demo">
How It Works
- The init script wraps the
<img>in a.animate-image-wrappercontainer for positioning - A toggle
<button>is injected alongside the image - On load, the first frame is captured to a canvas and converted to a static PNG data URL
- When paused, the image
srcis swapped to the static frame; when played, it reverts to the original animated source - The
data-animate-image-pausedattribute tracks the paused state
<!-- Before enhancement --><img src="animation.gif" data-animate-image alt="Demo"> <!-- After enhancement (auto-generated wrapper) --><div class="animate-image-wrapper"> <img src="animation.gif" data-animate-image data-animate-image-init alt="Demo"> <button type="button" class="animate-image-toggle" aria-label="Pause animation"></button></div>
Attributes
| Attribute | Type | Description |
|---|---|---|
data-animate-image |
boolean | Marks an <img> for animation control enhancement. |
data-animate-image-paused |
boolean | Set initially to start the image paused. Also set/removed automatically when the user toggles playback. |
data-animate-image-init |
boolean | Set automatically to prevent double-binding. Do not set manually. |
Start Paused
Add data-animate-image-paused to the image to start it in a paused state. The first frame is captured on load and displayed as a static image until the user clicks play.
<img src="animation.gif" data-animate-image data-animate-image-paused alt="Paused by default">
Reduced Motion
The init script automatically pauses animated images when the user has requested reduced motion. This is detected via two mechanisms:
prefers-reduced-motion: reduce— the OS-level media querydata-motion-reducedattribute on<html>— for app-level motion controls
When either is active, images are auto-paused after the first frame is captured. The user can still manually play the animation using the toggle button.
Runtime changes to the prefers-reduced-motion media query are also detected — if the user enables reduced motion while viewing the page, animated images will pause automatically.
/* The init script checks for reduced motion preference: * * 1. prefers-reduced-motion: reduce (OS setting) * 2. data-motion-reduced attribute on html * * If either is true, the image is auto-paused after * the first frame is captured. The user can still * click the play button to resume manually. */
Dynamic Elements
Images added to the DOM after page load are automatically enhanced via a MutationObserver. No manual initialization is needed.
<section> <h2>Accessibility</h2> <ul> <li>The toggle button has an <code>aria-label</code> that updates to "Pause animation" or "Play animation" based on state</li> <li>Respects <code>prefers-reduced-motion: reduce</code> by auto-pausing — users who find motion distracting see a static image by default</li> <li>Also respects a page-level <code>data-motion-reduced</code> attribute on <code><html></code></li> <li>The toggle button is keyboard-accessible (focusable, activated with Enter/Space)</li> <li>Without JavaScript, the image displays normally — progressive enhancement ensures the animated content is never lost</li> <li>Falls back gracefully for cross-origin images where canvas capture may be blocked by CORS</li> </ul> </section>