1. Introduction
Animated images (as enabled by [GIF], [PNG], [WebP]…) are in common use on the web. By default, user agents autoplay these images, which can be jarring for users, especially in use cases where there are multiple images on a single page (e.g. image galleries), and violates WCAG 2.2 § Success Criterion 2.2.2 Pause, Stop, Hide. Currently, site authors have no control over this.
This leads to a user desire to control such animations. However, due to the diversity of usage, there is a wide range of use cases and desired UIs and user experiences, so making this an automatic or opt-in user agent feature would not be sufficient.
To offer their users the best experience, websites need to control the playback experience, separately for each different uses of animated images.
This specification proposes a CSS property ('image animation') and a pseudo-class (:animated-image) to enable authors to control animations, and to target this control and any UI they wish to associate with it to relevant elements.
For further exploration of the motivations and of the alternatives considered, see also the separately maintained explainer and presentation on this topic.
2. Controlling Image Animations: the image-animation property
| Name: | image-animation |
|---|---|
| Value: | normal | paused | running |
| Initial: | normal |
| Applies to: | content images and elements with decorative images |
| Inherited: | yes |
| Percentages: | n/a |
| Computed value: | as specified |
| Canonical order: | per grammar |
| Animation type: | discrete |
This property allows authors to control whether animated images are displayed in their animated state or paused.
Both content images and decorative images are affected by this property. When an element contains several decorative images (e.g. multiple background images or border images), or if it contains both a content image and one or more decorative images, the computed value of the property on that element affects them all.
Note: It is therefore not possible to pause decorative images of an element while letting the animation run on the content image of the same element, nor vice-versa.
In the case of non-animated images, the different values of this property have no effect. This property does not affect videos nor programmatic images either.
- normal
-
The animation of animated images is run normally,
as determined by the image format and the host language.
Further, all animated images with the same absolute URL, the same image data, and with an image-animation computed value of normal' must be rendered synchronized to the same timeline as a group, with the timeline starting at the time of the least recent addition to the group.
Note: The above requirement is based on a [HTML] rendering expectation defined in HTML § 15.4.2 Images. As [HTML] does not generally require user agents to present documents in any particular way, and therefore does not normatively require the above behavior. This specification does.
- paused
- Animated images are rendered as if they were static images: the user agent must not run any animation it contains.
- running
-
Like normal,
the animation of animated images is run normally,
as determined by the image format and the host language,
However, animation timelines are scoped per element: among the content image and decorative images of a single element, any animated images with the same absolute URL, the same image data, and with an image-animation computed value of running must be rendered synchronized to the same timeline as a group, distinct from the timeline of images in other elements, with the timeline starting at the time of the least recent addition to the group.
img elements are kept animating.
:root{ /* propagates through the document by inheritance */ image-animation: paused; } img{ image-animation : normal; }
img elements
displaying instances of the same image
(same absolute URL and same image data),
all styled with image-animation: normal.
One of the elements has its image-animation property temporarily switched to paused, stopping the animation of its image. Other images are unaffected, and their animation continues.
The image-animation property of the paused element is later changed to running. At that point, that image resumes its animation, without regard to how far along their timeline other images are, and is now out of sync.
Later still, the image-animation property of that element is changed to normal. At that point, the image’s animation snaps back to being synchronized with the other instances.
The image-animation property affects not only raster image formats,
but also to vector images,
including SVG (see [SVG2]).
However, this is only the case for distinct SVG resources loaded as content images or decorative images,
and does not include svg elements inlined into HTML documents.
(However, if set on the svg element,
it does inherit,
and does affect any animated content image
loaded via the SVG image element.)
3. Telling Animated Images Apart: the :animated-image pseudo-class
The :animated-image pseudo-class represents content image elements where a animated image has been loaded. For the animated-image pseudo-class to match, the image must not only be in a format that is capable of animation, but must also be an actually animated image.
On elements which do not represent content images, the animated-image pseudo-class never matches.
In this simplistic example, images that can animate are initially paused, and a filter is applied to them to make them look dull and grayed out. Upon hovering or focusing the image, the filter is removed and the image is allowed to play.
img : animated-image{ image-animation : paused; filter : grayscale ( 10 % ) contrast ( 50 % ) brightness ( 80 % ); } img:animated-image:hover, img:animated-image:focus{ filter : none; image-animation : running; }
function setImageFocusability( event) { var img= event. target; if ( img. matches( ":animated-image" ) { img. tabIndex= 0 ; } else { img. removeAttribute( "tabindex" ); } } document. querySelectorAll( "img" ). forEach( ( i) => { setImageFocusability({ target: i}); i. addEventListener( 'load' , setImageFocusability); i. addEventListener( 'error' , setImageFocusability); });
Whether :animated-image matches is not affected by the current playing state of the image, nor by the value of the image-animation property. However, if some user agent setting has globally disabled image animations, even images that could otherwise be animated are considered static images, and do not match.
4. Terminology
- static image
-
Images where a single frame is intended
to be displayed as the final viewing experience.
A JPEG image is a static image.
- animated image
-
Images where multiple frames are intended
to be displayed sequentially as part of the final viewing experience,
possibly though not necessarily looping.
An animated PNG image, or an animated [GIF] image are animated images.
Support for progressive rendering or multi-pass loading does not make an image qualify as animated.
- content image
-
An element of the host language representing a static image
or an animated image,
at the exclusion of videos or programmatic images.
The
img[HTML] element, including when it is nested in thepictureelement; theobject[HTML] element, in cases where it represents an image; or theimage[SVG2] element represent content images. - decorative image
-
An image inserted into the document rendering by CSS,
through such properties as
background-imageorborder-image. - video
-
An element of the host language representing a moving picture, typically though not necessarily accompanied by sound, typically though not necessarily presented with interactive controls (for playing, pausing, seeking, controlling the volume, presenting in full screen…), possibly though not necessarily accompanied by captions or subtitles.
Note: From a conceptual point of view, and only based on file formats, videos and animated images have considerable overlap, and cannot not necessarily be distinguished from one another in principle. The distinction here is based on author intent, as expressed through the choice of element in the document.
The
video[HTML] element represents a video.Assuming a user agent which would support both usages, the samevideo/mp4file would be considered a video if presented via thevideoelement, or a decorative image if used as a CSSbackground-image. - programmatic image
-
An image created programmatically via an API of the host language,
as opposed to one loaded from an external resource.
The
canvas[HTML] element represents a programmatic image.
Should the video element
when it represents its poster frame
be treated as a content image,
a decorative image,
or as (a state of) a video and not an image at all?
5. Accessibility Considerations
- The features introduced by this specification enable authors to address what would otherwise be a violation of WCAG 2.2 § Success Criterion 2.2.2 Pause, Stop, Hide.
-
Web pages can already contain animated images,
and appropriate
alttext is already expected to be provided. No change is expected nor necessary to accommodate for pausing/resuming animations. Descriptions like ”Cartoon coyote being squashed by a falling anvil“, “cute dancing hamster”, “under construction”, or “rotating loading indicator” remain equally appropriate and evocative whether the animation is running or not. - Currently, screen readers typically do not chose to announce animated images differently from non-animated images, though this could be implemented if found desirable. Similarly, it is not expected that they would announce paused or playing images any differently, though this could be implemented if found desirable.
-
As discussed in § 3 Telling Animated Images Apart: the :animated-image pseudo-class,
authors building UI to control image animation
need to take the usual precautions
in order to build an accessible UI.
As it is not possible to directly make an element focusable in CSS,
proper keyboard navigation will require element attributes to be set as well.
An alternative solution,
instead or in addition to letting authors build their own UI
on elements where the :animated-image pseudo class matches,
would be to enable authors to instruct the user agent
to provide the UI itself when appropriate.
For example, an additional controlled value for the image-animation property could be defined. When this value would be specified, initially, the image animation would not run, as if paused has been specified. Additionally, if the underlying content image actually is an animated one, the user agent would provide some UI to allow the user to play and pause the animation, and would also make the element focusable.
If necessary, this can be added to a later version of this specification. However, it is uncertain whether authors would broadly use this, as they frequently prefer to design UI controls specifically tailored to their site. This specification therefore chose to defer working out the complexity of such a solution until author demand is confirmed.
6. Privacy Considerations
The image-animation property enables control over image animation cross origin,
without leaking any information about whether the image is actually animatable or not.
The computed value does not change based on this information.
The running value has effects that are visibly different on animated images
vs static images,
but none of these differences are observable by the page itself.
However, the :animated-image pseudo class does reveal whether a content image is animated or static, which the page could not otherwise know cross-origin. This could be restricted via CORS, but this specification chose not to impose such restriction, for the following reasons:
-
There is not much to be gained from this information that isn’t already known.
-
Whether an image is present at the target URL at all can reveal important information about the user (e.g. whether they are logged in in a particular domain), but that is already knowable from image dimensions, and animatability does not meaningfully add to this risk.
-
It is in practice very unlikely that a site would be designed to serve both a static and an animated image from the same URL, choosing which to serve based on some user-dependent private information which would thereby get leaked.
-
-
Similar information is already being shared for videos: the HTML
videoelement exposes duration even for cross-origin videos. A static image is arguably a special case of an animated one with a duration of 0, so exposing that information is analogous. -
There is a proposal to allow images in the
<video>element. If implemented, it means the situation would not just be analogous, but that whether an image is animated would already be knowable cross-origin anyway.
7. Security Considerations
This specification is not known to introduce any new security issue.