Reduced-motion cuts for autoplay heroes
Ship a still poster, a reduced-motion loop, and a full hero from one brief so prefers-reduced-motion does not mean running three campaigns.
An autoplaying hero is two problems wearing one file. It is a WCAG problem because moving content that starts on its own, lasts more than five seconds, and sits next to a headline and a nav has to be pausable under Success Criterion 2.2.2 Pause, Stop, Hide (Level A). It is a brand problem because the same loop that looks expensive on a quiet office monitor is the loop that makes a motion-sensitive visitor close the tab. Shipping one 15-second orbit and calling the poster "the accessible version" is how teams end up maintaining three campaigns by accident: the video, the still that does not match it, and a later "reduced motion" recut nobody budgeted.
The fix is one brief, three derived assets, and a page that chooses among them. The copy, the product, the grade, and the shot list stay the same. Only the camera's contribution to motion changes.
What the page actually has to do
prefers-reduced-motion: reduce is a CSS media query, documented in WCAG technique C39 as a way to meet SC 2.3.3 Animation from Interactions (Level AAA). Autoplay heroes are usually not interaction-triggered. They start because the page loaded, or because the player scrolled into view. That is 2.2.2's territory: a mechanism to pause, stop, or hide moving content that began without a click.
Those two criteria stack on a marketing page:
- If the hero autoplays for more than five seconds next to other content, the user needs a real pause control. Hover-to-pause that restarts when the pointer leaves does not count; the Understanding document is explicit that tying pause to focus makes the rest of the page unusable.
- If the operating system says reduce motion, the honest response is not to autoplay at all. Serve the poster, or a loop whose camera does not reorient the visual field.
Versely's own launch film follows the second rule in code: prefers-reduced-motion opts out of autoplay entirely and leaves the poster and controls in place. That is the pattern to copy on a brand page, not a special player feature you have to buy.
Muted autoplay is a separate browser policy. Muting satisfies SC 1.4.2 Audio Control for sound that starts on its own. It does nothing for the motion.
Three assets from one brief
Write the hero once, as coverage, not as a camera stunt.
1. The still poster. This is the first frame the reduced-motion visitor ever sees, and the fallback if the file never plays. Pull it from a held pose, not from the peak of a whip. The in-browser frame extractor reads the file on the visitor's own device and exports a PNG at the video's native resolution; nothing is uploaded. The extracting frames workflow is the same idea inside a generation pipeline. Use a frame that already contains the product and the type, so the paused page is not a different ad.
2. The reduced-motion loop. Same staging, camera locked or eased. Subject motion is allowed; camera-authored reorientation is not. Two reliable recipes:
- A locked-off plate: "The camera is entirely motionless. Steam rises from the cup. Her hand sets it down." Models that are not told to hold still will invent a drift. Say the tripod out loud.
- A first-and-last-frame loop: identical framing at both ends, so the clip can cycle without a whip at the seam. The first-last-frame transition path is built for that pin.
A slow ease is acceptable if it settles. A product orbit that never stops is not a reduced-motion loop, even at a lower speed. If you are unsure, convert a test encode to a sequence of stills in your head: if the background walks, it is still a camera move.
3. The full cut. This is the version with the push, the orbit, the crash. It plays after a click, or on a campaign landing where the visitor arrived to watch a film. It does not autoplay for a reduced-motion user.
Animated stills versus generated video is the adjacent decision when even a locked loop is more motion than the page needs. A Ken Burns on a still is still motion. A true still poster is not.
Do not maintain three campaigns
The cost of this work explodes when each asset gets its own brief, its own color grade, and its own round of copy. Keep one source of truth:
| Layer | Shared across all three | Allowed to differ |
|---|---|---|
| Script and on-screen type | Yes | Never |
| Product, talent, wardrobe | Yes | Never |
| Grade and brand kit | Yes | Never |
| Camera move | No | Locked / eased / full |
| Duration | Mostly | The loop can be shorter than the film |
| Audio | Optional on the loop | Full mix on click-to-play |
Generate the reduced-motion pass first. If the still story does not hold without the whip, the whip was doing the selling, and the page will fail the moment autoplay is off. Fix the staging, then generate the energetic version as a variant, not as the master.
On the video editor, that is one timeline with alternate camera clips, not three projects. Preview at 480p with preview: true while you check whether the lock actually holds; that preview is free and carries a short per-user cooldown. The final export is a single charge per file you actually ship. Two files, two exports, one brief.
Name them so a developer can wire the query without a meeting: hero-full.mp4, hero-reduced.mp4, hero-poster.png. Put the poster in the poster attribute. In CSS, default the <video> to preload="none" for reduced-motion users so the loop is not even buffered.
A minimal page shape:
@media (prefers-reduced-motion: reduce) {
.hero-video { display: none; }
.hero-poster { display: block; }
}
If you would rather keep a quiet loop playing, swap the src instead of hiding the element, and keep the pause control visible either way. Do not rely on the media query as your only pause mechanism for visitors who did not set the OS toggle; 2.2.2 is for everyone, not only people who found the setting.
Check it the way a visitor will
Open the page with the OS reduced-motion setting on, not with a DevTools override you will forget. Confirm:
- Nothing autoplays.
- The poster matches the first frame of the reduced loop, so a late play() does not jump.
- The pause control is a button, keyboard reachable, and does not steal the rest of the page.
- On a phone, the loop does not restart on scroll-back if the visitor paused it. Scroll-triggered replay is a common regression; treat a manual pause as sticky.
Then turn the setting off and confirm the full cut still has a pause control if it autoplays for more than five seconds. Passing the media query is not an exemption from 2.2.2.
That same 480p preview pass (preview: true, free, short per-user cooldown) is how you catch a locked-off render that still drifts before you pay for the export you will actually host. The preview-before-export workflow is the same habit.
FAQ
Does a looping GIF poster satisfy reduced motion?
Only if it does not loop motion. An animated GIF that pans is still a camera move, and it usually lacks a pause control, which is a 2.2.2 problem if it runs longer than five seconds next to other content. A static PNG or a video with controls is the safer poster.
Can the reduced-motion file just be the first frame of the full cut?
As a poster, yes. As the loop, only if that first frame was already a hold. If the full cut opens on a whip, the first frame is a smear. Generate a real locked take.
Is preload="metadata" enough for reduced-motion users?
It avoids downloading the whole file, which is good. It does not stop autoplay by itself. Pair it with a matchMedia('(prefers-reduced-motion: reduce)') check that skips play(), the same way a player should skip autoplay when the query matches.
Do I need a third cut for captions?
No. Captions are a track or a burn-in, not a motion variant. Keep one caption pass, apply it to both video files, and put any on-screen legal copy in the poster as well so the still state is not missing a claim the loop makes.