The narrow band where a loop beats both a still and a video#
Between a screenshot and a video there is a thin slice of documentation that an animated GIF fills better than either, and a much larger territory where reaching for a GIF is a mistake you pay for in bandwidth and accessibility complaints. Documentation is really a set of routing decisions, one per passage, and the pillar on video in docs lays out the whole surface; whether a given passage wants motion at all is its own four-axis call. The GIF's job description, once you draw its edges, turns out to be unusually specific.
A still image wins whenever the thing you are showing does not move. A GIF only earns its extra weight when the motion is the message: a panel sliding in, a value updating, the before-and-after of a single click. That is the same test a full video passes, so the real question is why you would loop a GIF rather than embed a video. The answer is placement. A GIF is an image as far as the surrounding markup cares, so it renders and autoplays anywhere an <img> tag works and a <video> tag might not: a GitHub README, a notebook cell, an email, a chat message, a wiki that strips <video>. It needs no player, no controls, and no user gesture to start.
So the band is narrow: a short (under about ten seconds), wordless, looping motion, embedded on a surface where a real video element is unavailable or unwanted. Outside that band a still is lighter and a video is both lighter and more capable. A table makes the boundaries concrete.
| Criterion | Still screenshot | Animated GIF | Muted video |
|---|---|---|---|
| Shows motion or a transition | No | Yes | Yes |
| Autoplays inline with no player | Yes | Yes | Only where <video> is allowed |
| Works in email or plain Markdown | Yes | Yes | Rarely |
| Weight for 10s of UI motion | Tiny | Largest | ~10x under the GIF |
| Reader can pause or stop it | N/A (static) | No | Yes |
| Respects a reduce-motion setting | N/A | No | Yes, with markup |
| Text a crawler can read | With alt | With alt | With track or transcript |
Two of those rows are where a GIF quietly fails the reader, and both are accessibility rows. Before the file-size argument, they are the reason to treat the GIF as a last resort rather than a default.
Why identical motion costs an order of magnitude more as a GIF#
The exact size math, encode by encode, is worked out for the README case; the short version is structural, not a tuning failure. A GIF stores each pixel as one 8-bit index into a palette capped at 256 colors, and it compresses motion only by skipping pixels that did not change, never by predicting a frame from its neighbor7. Modern codecs predict every frame from the ones around it, so the same motion costs a fraction. Google's own guidance puts a representative clip at 3.7 MB as a GIF against 551 KB as MP4 and 341 KB as WebM, an 85 to 90 percent cut from identical pixels4. MDN is blunt that for animation you should "consider WebP, AVIF or APNG," and that for lossless animation "GIF is less performant"7.
On a docs site you serve to real users that difference is a Core Web Vitals line item, not a rounding error. But size is the argument people already accept. The one they skip is the one that earns a page a complaint from a reader who cannot make the motion stop.
The Level A rule every autoplaying GIF breaks#
WCAG 2.2 Success Criterion 2.2.2, Pause, Stop, Hide, is a Level A requirement, the floor of conformance rather than an aspiration. It says that for "any moving, blinking or scrolling information that (1) starts automatically, (2) lasts more than five seconds, and (3) is presented in parallel with other content, there is a mechanism for the user to pause, stop, or hide it"1.
Read those three conditions against a docs GIF. It starts automatically, because a GIF's loop is baked into the file and begins the instant the image renders. It sits in parallel with other content, because it lives in the middle of a page of prose. The only escape clause is the five-second limit, and it is a trap: a GIF loops, so a four-second animation set to repeat becomes moving content that never stops, well past five seconds, for as long as the page is open. A single-play four-second clip is fine; the same clip on a loop is a 2.2.2 failure, and looping is the entire reason people reach for GIF in the first place.
There is no pause button on an <img>. A reader cannot stop the animation, cannot slow it, and on most current browsers cannot even hit a key to freeze it the way older browsers once allowed. The motion runs in their peripheral vision while they try to read the paragraph beside it. For a reader with ADHD that is a concentration tax; for a reader with a vestibular disorder it can be a physical one. The criterion exists because unstoppable parallel motion is a documented barrier, not a matter of taste.
Motion for people who switched motion off#
The second accessibility row is subtler and, for a docs team, more damning, because here the reader has already told you what they want. Every major operating system carries a reduce-motion accessibility setting, and browsers expose it to the page through the prefers-reduced-motion media feature, which is "used to detect if a user has enabled a setting on their device to minimize the amount of non-essential motion"3. MDN names the reason directly: such animations "can trigger discomfort for those with vestibular motion disorders," and "scaling or panning large objects can be vestibular motion triggers"3. Panning a large object is exactly what a scrolling-dashboard GIF does.
A raw animated GIF cannot see that preference. It is an image; it exposes no hook a media query can grab. A reader who switched motion off system-wide, deliberately, still gets your loop at full speed. WCAG's Level AAA criterion 2.3.3, Animation from Interactions, points at honoring prefers-reduced-motion as the mechanism2; a GIF is structurally incapable of honoring it. That is the gap between a video-based loop and a GIF that no encoding setting can close.
Ship the loop as a muted video, not a GIF#
The fix keeps everything the GIF gave you, autoplay, silent loop, inline rendering, and hands back the two things it took away. On any surface that allows a <video> element, which is every docs framework and every page you host yourself, replace the GIF with a muted, looping, inline video. web.dev's recommended pattern is exactly this, with WebM and an MP4 fallback4:
<video autoplay muted loop playsinline poster="dashboard.png">
<source src="dashboard.webm" type="video/webm">
<source src="dashboard.mp4" type="video/mp4">
</video>
autoplay starts it, loop repeats it, playsinline stops it grabbing the whole screen, and muted is mandatory: browsers block autoplay for anything with an audible track5. The poster frame gives the element the Largest Contentful Paint candidate a bare looping video otherwise lacks. This single swap satisfies 2.2.2, because a <video> exposes native controls a reader can reach, and it is the same order of magnitude smaller the file-size section promised.
Then honor the reader who turned motion off. A <picture> element picks a <source> by media condition and falls back to its <img>, and that condition can be prefers-reduced-motion exactly as it can be prefers-color-scheme6:
<picture>
<source srcset="card-still.png" media="(prefers-reduced-motion: reduce)">
<img src="card-drag.gif" alt="Dragging a card to the next column marks it done">
</picture>
A reader with reduced motion enabled gets a crisp still; everyone else gets the loop. If the surface genuinely allows nothing but an image, a GitHub README being the common case, that is the one place a committed GIF is still the right call, and its size budget and stable-embed rules have their own writeup. Everywhere else, the GIF is a habit, not a requirement.
Two rules travel with the loop wherever it lands. Write real alt text describing the action, not "demo.gif," because a looping animation with no text description is invisible to a screen reader and to search. And keep the clip to one action; a docs loop is closer to a single-action microvideo than to a tutorial, and the captions and transcript work that makes any tutorial clip accessible applies the moment your loop carries meaning a still cannot.
Keeping the loop honest after the UI moves#
A stale loop is worse than a stale screenshot. A screenshot that has fallen behind is a quiet, correctable error; an animated loop that has fallen behind demonstrates the wrong thing, over and over, with the authority that motion carries. The highest-value docs loops sit on the interfaces that change most, so a library of them rots on the same schedule a video library does, and the only maintenance model that scales is regenerating each clip from a spec instead of re-recording it. Our own engine, aidemo, is one instance of that approach and honest about its edges: it captures a browser and nothing outside one, its storyboard comes from a coding agent that a person then edits as text rather than on a drag-and-drop timeline, and a single script emits the loop as a video or a GIF. The mechanism is the point, not the tool. A docs loop earns its place by showing motion a still cannot, in a format a reader can stop, at a size a page can afford, depicting a UI that still exists.
Sources#
- W3C — Understanding WCAG 2.2 SC 2.2.2 Pause, Stop, Hide (Level A)
- W3C — Understanding WCAG 2.2 SC 2.3.3 Animation from Interactions (Level AAA)
- MDN — prefers-reduced-motion media feature
- web.dev — Replace animated GIFs with video for faster page loads
- MDN — The video embed element (autoplay, muted, loop, playsinline)
- MDN — The picture element (media conditions on source)
- MDN — Image file type and format guide (GIF color depth and animation)
FAQ#
Should I use a GIF or a video in my documentation?#
Use a GIF only when you need short, wordless, looping motion on a surface that cannot render a <video> element, such as a GitHub README, an email, or a wiki that strips video. On any page you host yourself, ship a muted, looping, inline video instead: it is roughly ten times smaller for the same motion and, unlike a GIF, a reader can pause it. When nothing on screen moves, a plain screenshot beats both.
Are animated GIFs an accessibility problem?#
Yes, when they autoplay and loop. WCAG 2.2 Success Criterion 2.2.2 (Level A) requires a way to pause, stop, or hide any motion that starts automatically, runs past five seconds, and sits alongside other content, and a looping GIF meets all three while offering no pause control at all. A raw <img> GIF also ignores a reader's system reduce-motion setting, which a video or a <picture> swap can honor. Add descriptive alt text so the animation is not invisible to screen readers.
How do I make an animated GIF respect a user's reduced-motion setting?#
A raw GIF cannot respond to prefers-reduced-motion on its own, so serve a static image instead when the setting is on. Wrap the animation in a <picture> and give the animated source a media="(prefers-reduced-motion: reduce)" sibling that points at a still frame, falling back to the animation in the <img>. The cleaner option is to drop the GIF entirely for a muted looping <video>, which exposes real controls and can be dimmed or paused with a reduced-motion CSS rule.



