<pre class='metadata'>
Title: CSS Image Animation Module Level 1
Shortname: css-image-animation
Level: 1
group: csswg
Status: ED
Prepare for TR: no
Work Status: exploring
ED: https://drafts.csswg.org/css-image-animation-1/
TR: https://www.w3.org/TR/css-image-animation-1/
Previous Version: https://webplatform.design/projects/image-animation/image-animation-property/spec/overview
Editor: Florian Rivoal, http://florian.rivoal.net, w3cid 43241
Complain About: accidental-2119 yes, missing-example-ids yes
Infer CSS Dfns: yes
Markup Shorthands: markdown yes, css yes
Abstract: This CSS module proposes facilities to control the rendering of animated images.
</pre>
<pre class="link-defaults">
	spec:html; type:element; text:body
</pre>
<pre class=biblio>
{
	"IMAGE-ANIMATION-EXPLAINER": {
		"authors": [
		  "Florian Rivoal",
		  "Lea Verou"
		],
		"href": "https://drafts.csswg.org/css-image-animation-1/explainer",
		"title": "CSS Image Animation Explainer"
	  },
	"IMAGE-ANIMATION-TALK": {
		"authors": [
		  "Lea Verou",
		  "Florian Rivoal"
		],
		"href": "https://github.com/webplatformco/project-image-animation/tree/main/image-animation-property",
		"title": "We need to be able to control Image Animation on the Web Platform!"
	  }
}
</pre>

Introduction {#intro}
=====================
<div class=non-normative><em>This section is non-normative.</em>

	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 [[WCAG22#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 <abbr title="user interfaces">UIs</abbr> and user experiences,
	so making this an automatic or opt-in user agent feature [[IMAGE-ANIMATION-EXPLAINER#provide-this-as-a-ua-setting|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 <abbr title="user interface">UI</abbr> 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
	[[IMAGE-ANIMATION-EXPLAINER inline|explainer]]
	and [[IMAGE-ANIMATION-TALK inline|presentation]]
	on this topic.

	<div class=advisement>
		Nothing in this specification precludes user agents offering users
		a setting to control image animation globally,
		such as an option to turn all [=animated images=] into [=static images=].
	</div>
</div>

Controlling Image Animations: the 'image-animation' property {#image-animation}
===============================================================================

	<pre class="propdef">
	Name: image-animation
	Value: normal | paused | stopped | running
	Initial: normal
	Applies to: [=content images=] and elements with [=decorative images=]
	Inherited: yes
	Computed Value: as specified
	Animation Type: discrete
	</pre>

	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.

	When this property is applied to the [=root element=],
	its effects on background [=decorative images=] are propagated to the [=canvas background=].

	Note: For legacy reasons,
	the 'background' property propagates not only from the [=root element=],
	but also from the HTML <{body}> element.
	However, newer properties like 'image-animation' <em>only</em> propagate from the [=root element=].
	Setting it on the <{body}> will not propagate,
	even if that is where the 'background' is set.

	<dl dfn-for=image-animation dfn-type=value>
		<dt><dfn>normal</dfn>
		<dd>
			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 <a href="https://url.spec.whatwg.org/#syntax-url-absolute">absolute URL</a>,
			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/rendering#images-3]].
			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.

		<dt><dfn>stopped</dfn>
		<dd>
			[=Animated images=] are rendered as if they were [=static images=]:
			the user agent must not run any animation it contains.
			If the image contains a [=cover frame=],
			that is what the user agent must use;
			otherwise, it must display the image
			as it would be in the initial state of the animation.

		<dt><dfn>paused</dfn>
		<dd>
			The user agent must not run the animation
			contained in the [=Animated images=],
			and must continue to display the image
			as it was when this value started to apply,
			effectively pausing the animation.

			If the animation had not been playing
			prior to this value being applied,
			the behavior is the same as ''stopped''.

		<dt><dfn>running</dfn>
		<dd>
			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 <a href="https://url.spec.whatwg.org/#syntax-url-absolute">absolute URL</a>,
			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.

			If images are added to the element while the computed value is ''running'',
			the timeline starts at the time of the least recent addition to the group.

			If the element is created or made visible after having previously been set to ''display: none'',
			with images already added and with 'image-animation' already set to ''running'',
			the timeline starts when the element is included in the layout.

			If this property is switched to ''running'' from another value,
			the beginnig of this timeline is set
			so that the animation continues from the state that was displayed
			at the timem of the switch.
	</dl>

	<div class=example id=prefers>
		An author can use this property to suppress non-essential image animations
		in response to user preferences expressed by the '@media/prefers-reduced-motion' media feature.
		Here, [=decorative images=] are made [=static images|static=],
		while <{img}> elements are kept animating.

		<pre class=lang-css>
		:root { /* propagates through the document by inheritance */
			image-animation: paused;
		}
		img {
			image-animation: normal;
		}
		</pre>
	</div>

	<div class=example id=stop-start>
		A given HTML page contains several <{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.
	</div>

	The 'image-animation' property affects not only raster image formats,
	but also to vector images,
	<span class=non-normative>including SVG (see [[SVG2]])</span>.
	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 image|animated=] [=content image=]
	loaded via the SVG <{image}> element.)


Telling Animated Images Apart: the '':animated-image'' pseudo-class {#animated-image-pseudo}
==============================================================================

	The <dfn>:animated-image</dfn> 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.

	<div class=example id=minimalist-ui>
		This pseudo class can be used for authors
		to selectively provide some user interface
		to enable users to play paused images.

		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.

		<pre class=lang-css>
		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;
		}
		</pre>
	</div>

	<div class=advisement>
		It is important for authors building <abbr title="user interface">UI</abbr>
		to control the animation of images
		to take the needs of keyboard users into consideration,
		and to avoid making the interaction rely solely on mouse interactions.

		<div class=example id=minimalist-ui-keyboard>
			In the <a href=#minimalist-ui>above example</a>,
			play is triggered not only by hovering the image
			but also by focusing it.
			To make this fully functional,
			it would be necessary to make animatable images focusable.
			This could be accomplished with something
			like the following code snippet.

			<pre class=lang-javascript>
			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);
			});
			</pre>
		</div>
	</div>

	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.


Terminology {#terminology}
==========================

	<dl>
		<dt><dfn>static image</dfn>
		<dd>
			Images where a single frame is intended
			to be displayed as the final viewing experience.

			<p class=example id=ex-s-i>
			A JPEG image is a [=static image=].

		<dt><dfn>animated image</dfn>
		<dd>
			Images where multiple frames are intended
			to be displayed sequentially as part of the final viewing experience,
			possibly though not necessarily looping.

			<p class=example id=ex-a-i>
			An <a spec=png-3>animated PNG</a> 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 image|animated=].

		<dt><dfn>content image</dfn>
		<dd>
			An element of the host language representing a [=static image=]
			or an [=animated image=],
			at the exclusion of [=videos=] or [=programmatic images=].

			<p class=example id=ex-c-i>
			The <{img}> [[HTML]] element,
			including when it is nested in the <{picture}> element;
			the <{object}> [[HTML]] element, in cases where it <a spec=html>represents</a> an image;
			or the <{image}> [[SVG2]] element
			represent [=content images=].

			When it represents its <a spec=html>poster frame</a> (and only then),
			the HTML <{video}> element
			is considered a [=content image=].

		<dt><dfn>decorative image</dfn>
		<dd>
			An image inserted into the document rendering by CSS,
			through <span class=non-normative>such properties as `background-image` or `border-image`</span>.

		<dt><dfn>video</dfn>
		<dd>

			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.

			<p class=example id=ex-v>
			The <{video}> [[HTML]] element represents a [=video=].

			<div class=example id=video-or-not>
				Assuming a user agent which would support both usages,
				the same <code>video/mp4</code> file
				would be considered a [=video=] if presented via the <{video}> element,
				or a [=decorative image=] if used as a CSS `background-image`.
			</div>

		<dt><dfn>programmatic image</dfn>
		<dd>
			An image created programmatically via an API of the host language,
			as opposed to one loaded from an external resource.

			<p class=example id=ex-p-i>
			The <{canvas}> [[HTML]] element represents a [=programmatic image=].

		<dt><dfn>cover frame</dfn>
		<dd>
			Some [=animated image=] formats make it possible
			for the creator of the image
			to specify a [=static image=],
			referred to in this document as the [=cover frame=],
			to display when the animation is not running,
			distinctly from the initial state of the animation.
	</dl>


Accessibility Considerations {#a11y}
====================================
<div class=non-normative><em>This section is non-normative.</em>

	<ul>
		<li>
			The features introduced by this specification enable authors
			to address what would otherwise be a violation
			of [[WCAG22#pause-stop-hide]].

		<li>
			Web pages can already contain animated images,
			and appropriate <{img/alt}> text 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.

		<li>
			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.

		<li>
			As discussed in [[#animated-image-pseudo]],
			authors building <abbr title="user interface">UI</abbr> to control image animation
			need to take the usual precautions
			in order to build an accessible <abbr title="user interface">UI</abbr>.
			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 <abbr title="user interface">UI</abbr>
			on elements where the '':animated-image'' pseudo class matches,
			would be to enable authors to instruct the user agent
			to provide the <abbr title="user interface">UI</abbr> 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 image|animated=] one,
			the user agent would provide some <abbr title="user interface">UI</abbr> 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 <abbr title="user interface">UI</abbr> 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.
	</ul>
</div>


Privacy Considerations {#priv}
==============================
<div class=non-normative><em>This section is non-normative.</em>

	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 image|animated=] or [=static image|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 <{video}> element 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.
</div>


Security Considerations {#sec}
==============================
<div class=non-normative><em>This section is non-normative.</em>

	This specification is not known to introduce any new security issue.
</div>

Changes {#changes}
==================

Since the <a href="https://www.w3.org/TR/2026/WD-css-image-animation-1-20260409/">First 
	Public Working Draft of 9 April 2026</a>

<ul>
	<li><em>none</em></li>
</ul>
