Ingo Steinke, web developer
Posted on October 18, 2023
We should respect reduced motion preferences on every website, but while we have full control of a custom website, WordPress projects often use existing plugins for image optimization. They can optimize everything ... except for animated GIFs.
DEV adds a stop button to this animated GIF, but WordPress doesn't.
WordPress + plugins < DEV
Using WordPress plugins can save time and possible errors compared to writing custom code from scratch. Website owners can use the existing UI to upload arbitrary pictures, crop and resize, let the plugin generate optimized files in the background and enjoy what-you-see-is-what-you-get editing.
A WordPress plugin like TinyPNG will add markup to offer alternative image versions like webp vs. jpg. But popular image optimizing plugins don't care about GIF ... yet? The GIF format should have been replaced by PNG or webp for years, but there are still a lot of animated GIFs around, causing different kinds of problems beyond annoying some of your website visitors.
Why does it matter?
- file size: an animated GIF can easily be several MB
- no respect for reduced motion preference
- missing stop option
Most popular GIF animations play as endless loops, although they don't need to. There are possible options to stop it after playing the animation.
Current web browsers don't offer options to pause or prevent animations, at least not without special plugins. Users can set a reduced motion preference option, but that doesn't change much until we actively care about reduced motion in our website setup.
WordPress has been quite strict and critical about SVG uploads by default, but it allows users to upload GIF images without showing any warning at all.
Accessibility: "Dizzy Users Close Browsers"
Dizzy Users Close Browsers, so we better respect the pause, stop, or hide principle.
In this talk, Piccia Neri shares how she enjoyed GIF animations but found out they made her feel dizzy, and how we can improve our websites' accessibility without giving up playful details in web design. (That's just one topic of her talk, so take your time to watch it, if you didn't see her at beyond Tellerrand conference in Berlin this year).
Frontend markup, backend logic, or both
We could use a source set to offer an alternative still image version without animation and modern, more efficient, animation formats.
Accept and vary on the server side
If we want to offer different image formats depending on browser support, we can add backend logic to send different images based on the Accept HTTP header and adding a vary: accept
header to our response.
Here is a switch for GIF vs. (animated) webp based on browser capabilities. We can request this script instead of the original image.
<?php // image.php
header('Status: 200 OK');
header('Vary: Accept');
$request_headers = getallheaders();
if (
(request_headers["Accept"] &&
is_string($request_headers["Accept"]) &&
str_contains($request_headers["Accept"], 'webp')
) || (
$request_headers["accept"] &&
is_string($request_headers["accept"]) &&
str_contains($request_headers["accept"], 'webp')
)
) {
serve_webp();
} else {
serve_gif();
}
<img src="image.php">
Picture / Source / Image
Without adding backend code, we can add more frontend markup wrapping a picture element around our image markup. CSS-tricks shared a good example and explanation how to use GIFS and prefers-reduced-motion:
<picture>
<source srcset="img/waterfall.avif" type="image/avif">
<source srcset="img/waterfall.webp" type="image/webp">
<img src="img/waterfall.jpg" alt="a waterfall">
</picture>
Currently, we can't generate the aforementioned markup without generating an alternative image that does not move. There is no option for website owners to upload alternative versions of one media item yet.
Best practice for a default WordPress setup?
WordPress should automatically generate an alternative that takes the first frame of the animation and exports it as a static image. But it doesn't.
I opened a support issue to add static fallback for animated images if a user prefers reduced motion in TinyPNG.
As a workaround of a workaround, I could use add_filter( 'post_thumbnail_html'
and add such a CSS class name manually. To do it properly, I would have to open each image file stream and check each GIF, webp or avif for an animation signature. More pragmatically, I currently check for a .gif
string anywhere inside the thumbnail section which of only works because TinyPNG leaves animated GIFs untouched and does not make animated webp’s out of theme.
As a more pragmatic, quick and simple workaround, I decided to hide the GIF for users that prefer reduced motion. No image, no animation.
You can’t have animated images if there are no images.
Or in CSS:
@media (prefers-reduced-motion) {
.has-gif img {
visibility: hidden;
}
}
I needed to add the has-gif
class in our markup.
<figure class="news_postimage<?PHP
if (str_contains(get_the_post_thumbnail(),'.gif"')) {
echo ' newspost_image--has-gif';
} ?>">
<?php the_post_thumbnail() ?>
What did I do here?
I added a figure element and called the_post_thumbnail function to let WordPress core and the image optimization plugins do their work.
Conclusion
Another pragmatic solution for a problem that shouldn't exist in the first place. GIFs are bad! But sometimes they're fun. That's why people use them.
That's why we need to deal with reality and still make our websites work properly regarding accessibility and performance optimization.
Posted on October 18, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.