Steve Faulkner has a clever idea here. You can show an (animated) GIF and overlay a pause/play button on top of it — which is really a
<summary> element. When toggled, a (non-animated) JPG inside covers the GIF, effectively “pausing” it.
Adrian Roselli calls it a “quick and dirty” way to pass WCAG Success Criterion 2.2.2 Pause, Stop, Hide.
I forked it, swapped out all the images so it shows the JPG first, and put
loading="lazy" on the images. It seems to effectively not load the GIF until you explicitly press play, so that’s an option too:
This library looks promising to pause / play GIFs: https://github.com/buzzfeed/libgif-js
This seems like the wrong way to go about this. In my opinion, using a video element with something like an MP3 file would be much more effective.
This also doesn’t seem to effectively pause the GIF at all. This is more akin to stopping the GIF. When you unpause it, you’ll notice it’s not at all where you expected it to be. This seems like a much worse UX than just converting the GIF to a video or not allowing GIFs.
Cute. One other option would be decide whether to start with a static or animated based on detecting reduced motion :)
Well, it’s not really a pause. The gif keeps playing in background and the paused frame is not where the user paused. It can works better for very short gifs, but can be confusing for longer ones.
A gif is intended to be a looping image. This is understood by most, if not all, users.
Stopping a gif (pausing in this case) and starting it from that exact point is of no concern to non-Dev users. It’s looping. It’ll return to that point within seconds.
Most gifs are short duration. Gif durations lasting over 5 seconds are advised to be replaced with video. The solution provided by this article is a good one when used in the appropriate context of short duration gifs.
I see this solution as one to be added to a dev’s toolkit for cases that calls for it. Falsely criticizing it for being totally useless (particularly because you didn’t think of it first) is frivolous and petty.
This wasn’t working for me on chrome, got a better result just flipping the script to default to static (closed) and add the open attribute after the prefers-reduced-motion check. https://codepen.io/phillipkent/pen/yLJwKNm
OH wait – I still like my way better, but the real problem I had in this pen is the extra ‘)’ in line 1 of the JS ♂️