Pointer-driven Animations

Editor’s Draft,

More details about this document
This version:
https://drafts.csswg.org/pointer-animations-1/
Latest published version:
https://www.w3.org/TR/pointer-animations-1/
Feedback:
CSSWG Issues Repository
Inline In Spec
Editor:
(Wix.com)
Suggest an Edit for this Spec:
GitHub Editor

Abstract

Defines CSS properties and an API for creating animations that are tied to the pointer position over a specified range. That range can be relative to the viewport or an element’s bounding box.

CSS is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, etc.

Status of this document

This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

Please send feedback by filing issues in GitHub (preferred), including the spec code “pointer-animations” in the title, like this: “[pointer-animations] …summary of comment…”. All issues and comments are archived. Alternately, feedback can be sent to the (archived) public mailing list www-style@w3.org.

This document is governed by the 03 November 2023 W3C Process Document.

1. Introduction

This specification defines mechanisms for driving the progress of an animation based on the pointer position’s progress over a specified range. These pointer-driven animations use a timeline based on the pointer position, and are based on length, rather than time. In this way they operate similarly to, and share similar concepts with scroll-driven animations. This module provides both an imperative API building on the Web Animations API as well as a declarative API building on CSS Animations. [CSS-ANIMATIONS-2] [WEB-ANIMATIONS-1]

1.1. Relationship to other specifications

Web Animations [WEB-ANIMATIONS-1] defines an abstract conceptual model for animations on the Web platform, with elements of the model including animations and their timelines, and associated programming interfaces. This specification extends the Web Animations model by defining pointer progress timelines and allowing them to drive progress in animations to create pointer-driven animations.

This specification introduces both programming interfaces for interacting with these concepts, as well as CSS properties that apply these concepts to CSS Animations [CSS-ANIMATIONS-1]. To the extent the behavior of these CSS properties is described in terms of the programming interfaces, User Agents that do not support scripting may still conform to this specification by implementing the CSS features to behave as if the underlying programming interfaces were in place.

This specification was derived from, and inspired by the concepts and features introduced in the Scroll-Driven Animations module [SCROLL-ANIMATIONS-1] for specifying progress-based timelines and animations.

Like most operations in CSS besides selector matching, features in this specification operate over the flattened element tree.

1.2. Value Definitions

This specification follows the CSS property definition conventions from [CSS2] using the value definition syntax from [CSS-VALUES-3]. Value types not defined in this specification are defined in CSS Values & Units [CSS-VALUES-3]. Combination with other CSS modules may expand the definitions of these value types.

In addition to the property-specific values listed in their definitions, all properties defined in this specification also accept the CSS-wide keywords as their property value. For readability they have not been repeated explicitly.

2. Pointer Progress Timelines

Pointer progress timelines are timelines linked to progress in the pointer position over an element’s principal box along a particular axis.

The pointer range is the size of the element’s principal box along the axis of the pointer progress timeline.

The pointer offset is the position of the pointer relative to the start of the element’s pointer range, as defined by offsetX and offsetY in [CSSOM-VIEW-1]. The startmost pointer offset represents 0% progress and the endmost pointer offset represents 100% progress.

Pointer progress timelines can be referenced in animation-timeline anonymously using the pointer() functional notation or by name (see Scroll-driven Animations § 4.2 Named Timeline Scoping and Lookup) after declaring them using the pointer-timeline properties. In the Web Animations API, they can be represented anonymously by a PointerTimeline object.

2.1. Pointer Progress Timeline Ranges

pointer progress timelines define the following named timeline ranges:

fill
Represents the full range of the pointer progress timeline:
fit
Represents a range that is the same size as fill, but its points of 0% and 100% progress are offset according to the value of animation-range-center property, so that the point of 50% progress remains at the center of the range.
cover
Represents the largest possible range of the pointer progress timeline that fully covers the element’s principal box according to the value of animation-range-center property as follows:
  • If the distance between the point of 50% progress and the element’s start padding edge is greater than the distance between the point of 50% progress and the element’s end padding edge, then the 0% progress point is at the element’s start padding edge, and the 100% progress point is at the same distance from the 50% progress point on the opposite side.

  • Otherwise, the 100% progress point is at the element’s end padding edge, and the 0% progress point is at the same distance from the 50% progress point on the opposite side.

contain
Represents the largest possible range that is fully contained within the element’s principal box according to the value of animation-range-center property as follows:
  • If the distance between the point of 50% progress and the element’s start padding edge is smaller than the distance between the point of 50% progress and the element’s end padding edge, then the 0% progress point is at the element’s start padding edge, and the 100% progress point is at the same distance from the 50% progress point on the opposite side.

  • Otherwise, the 100% progress point is at the element’s end padding edge, and the 0% progress point is at the same distance from the 50% progress point on the opposite side.

Insert diagrams.

In all cases, the writing mode used to resolve the start and end sides is the writing mode of the relevant principal box. Transforms are ignored, but relative and absolute positioning are accounted for.

[CSS-POSITION-3] [CSS-TRANSFORMS-1]

2.2. Calculating Progress for a Pointer Progress Timeline

Progress (the current time) for a pointer progress timeline is calculated as: pointer offset ÷ pointer range

If the 0% position and 100% position coincide (i.e. the denominator in the current time formula is zero), the timeline is inactive.

2.3. Anonymous Pointer Progress Timelines

2.3.1. The pointer() notation

The pointer() functional notation can be used as a <single-animation-timeline> value in animation-timeline and specifies a pointer progress timeline. Its syntax is

<pointer()> = pointer( [ <source> || <axis> ]? )
<axis> = block | inline | x | y
<source> = root | nearest | self

By default, pointer() references the inline axis of the element’s own pointer range. Its arguments modify this lookup as follows:

block
Specifies to use the measure of progress along the block axis of the pointer range.
inline
Specifies to use the measure of progress along the inline axis of the pointer range. (Default.)
x
Specifies to use the measure of progress along the horizontal axis of the pointer range.
y
Specifies to use the measure of progress along the vertical axis of the pointer range.
self
Specifies to use the element’s own principal box as the pointer range. (Default.)
nearest
Specifies to use the nearest element’s parent box as the pointer range.
root
Specifies to use the root element’s principal box as the pointer range.

Each use of pointer() corresponds to its own instance of PointerTimeline in the Web Animations API, even if multiple elements use pointer() to refer to the same pointer range with the same arguments.

2.3.2. The PointerTimeline Interface

enum PointerAxis {
  "block",
  "inline",
  "x",
  "y"
};

dictionary PointerTimelineOptions {
  Element? source;
  PointerAxis axis = "block";
};

[Exposed=Window]
interface PointerTimeline : AnimationTimeline {
  constructor(optional PointerTimelineOptions options = {});
  readonly attribute Element? source;
  readonly attribute PointerAxis axis;
};

A PointerTimeline is an AnimationTimeline that represents a pointer progress timeline. It can be passed to the Animation constructor or the animate() method to link the animation to a pointer progress timeline.

source, of type Element, readonly, nullable

The element whose pointer offset drives the progress of the timeline.

axis, of type PointerAxis, readonly

The axis that drives the progress of the timeline. See value definitions for <axis>, above.

Inherited attributes:

currentTime (inherited from AnimationTimeline)

Represents the pointer progress of the pointer range as a percentage CSSUnitValue, with 0% representing its startmost pointer offset. Null when the timeline is inactive.

PointerTimeline(options)

Creates a new PointerTimeline object using the following procedure:

  1. Let timeline be the new PointerTimeline object.

  2. Set the source of timeline to:

    If the source member of options is present,

    The source member of options.

    Otherwise,

    The root element.

  3. Set the axis property of timeline to the corresponding value from options.

If the source of a PointerTimeline is an element whose principal box does not exist then the PointerTimeline is inactive.

The values of source and currentTime are both computed when either is requested or updated.

2.4. Named Pointer Progress Timelines

Pointer progress timelines can also be defined declaratively and then referenced by name by elements within the name’s scope (see Scroll-driven Animations § 4.2 Named Timeline Scoping and Lookup).

Such named pointer progress timelines are declared in the coordinated value list constructed from the pointer-timeline-* properties, which form a coordinating list property group with pointer-timeline-name as the coordinating list base property. See CSS Values 4 § A Coordinating List-Valued Properties.

2.4.1. Naming a Pointer Progress Timeline: the pointer-timeline-name property

Name: pointer-timeline-name
Value: [ none | <dashed-ident> ]#
Initial: none
Applies to: all elements
Inherited: no
Percentages: n/a
Computed value: the keyword none or a list of CSS identifiers
Canonical order: per grammar
Animation type: not animatable

Specifies names for the named pointer progress timelines associated with this element.

2.4.2. Axis of a Pointer Progress Timeline: the pointer-timeline-axis property

Name: pointer-timeline-axis
Value: [ block | inline | x | y ]#
Initial: block
Applies to: all elements
Inherited: no
Percentages: n/a
Computed value: a list of the keywords specified
Canonical order: per grammar
Animation type: not animatable

Specifies the axis of any named pointer progress timelines derived from this element’s principal box. If this element’s principal box does not exist, then the corresponding named pointer progress timeline is inactive.

Values are as defined for pointer().

2.4.3. Pointer Timeline Shorthand: the pointer-timeline shorthand

Name: pointer-timeline
Value: [ <'pointer-timeline-name'> <'pointer-timeline-axis'>? ]#
Initial: see individual properties
Applies to: all elements
Inherited: see individual properties
Percentages: see individual properties
Computed value: see individual properties
Animation type: see individual properties
Canonical order: per grammar

This property is a shorthand for setting pointer-timeline-name and pointer-timeline-axis in a single declaration.

3. Privacy Considerations

There are no known privacy impacts of the features in this specification.

4. Security Considerations

There are no known security impacts of the features in this specification.

Appendix A: Animation Range Centering

This section should move to CSS-ANIMATIONS-2 and WEB-ANIMATIONS-2.

The section Scroll-driven Animations §  Attaching Animations to Timeline Ranges introduces the concept of attaching a set of animation keyframes to an animation attachment range, which creates a single linear range of progress for the animation.

Pointer-driven animations adds a new ability, to set the focal point - the point of 50% progress - of the animation to a specific point, rather than the default center of the animation attachment range, which can be done using the animation-range-center property.

The animation range center subject is the element whose principal box is the range relative to which the center of the active range is calculated, and is represented by the <timeline-range-center-subject> value type, which indicates a CSS identifier representing one of the following:

source
The element whose pointer offset drives the progress of the timeline.
target
The element to which the animation is applied.

The point of 50% progress can be smaller than the 0% progress point or larger than the 100% progress point. In such cases, the animation attachment range is cut off at the 50% progress point.

Specifying an Animation’s Timeline Range Center: the animation-range-center property

Name: animation-range-center
Value: [ normal | [ <length-percentage> | <timeline-range-center-subject> <length-percentage>? ] ]#
Initial: normal
Applies to: all elements
Inherited: no
Percentages: relative to the corresponding dimension of the specified timeline range center subject, else relative to the start of the animation attachment range
Computed value: list, each item either the keyword normal or a timeline range center subject and a length-percentage value
Canonical order: per grammar
Animation type: not animatable

Specifies the center point of the animations’s attachment range, i.e. where the 50% progress point of the animations’s range is.

Values have the following meanings:

normal
The 50% progress point of the animation’s active interval is at the center of the animation attachment range.
<length-percentage>
The 50% progress point of the animation’s active interval is at the specified point on the timeline measuring from the start of the animation attachment range. Percentages are relative to the size of the animation attachment range.
<timeline-range-name> <length-percentage>?
The 50% progress point of the animation’s active interval is at the specified point relative to the start padding edge of the specified animation range center subject’s principal box. If the <length-percentage> is omitted, it defaults to 50%.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Advisements are normative sections styled to evoke special attention and are set apart from other normative text with <strong class="advisement">, like this: UAs MUST provide an accessible alternative.

Tests

Tests relating to the content of this specification may be documented in “Tests” blocks like this one. Any such block is non-normative.


Conformance classes

Conformance to this specification is defined for three conformance classes:

style sheet
A CSS style sheet.
renderer
A UA that interprets the semantics of a style sheet and renders documents that use them.
authoring tool
A UA that writes a style sheet.

A style sheet is conformant to this specification if all of its statements that use syntax defined in this module are valid according to the generic CSS grammar and the individual grammars of each feature defined in this module.

A renderer is conformant to this specification if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by this specification by parsing them correctly and rendering the document accordingly. However, the inability of a UA to correctly render a document due to limitations of the device does not make the UA non-conformant. (For example, a UA is not required to render color on a monochrome monitor.)

An authoring tool is conformant to this specification if it writes style sheets that are syntactically correct according to the generic CSS grammar and the individual grammars of each feature in this module, and meet all other conformance requirements of style sheets as described in this module.

Partial implementations

So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid (and ignore as appropriate) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents must not selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.

Implementations of Unstable and Proprietary Features

To avoid clashes with future stable CSS features, the CSSWG recommends following best practices for the implementation of unstable features and proprietary extensions to CSS.

Non-experimental implementations

Once a specification reaches the Candidate Recommendation stage, non-experimental implementations are possible, and implementors should release an unprefixed implementation of any CR-level feature they can demonstrate to be correctly implemented according to spec.

To establish and maintain the interoperability of CSS across implementations, the CSS Working Group requests that non-experimental CSS renderers submit an implementation report (and, if necessary, the testcases used for that implementation report) to the W3C before releasing an unprefixed implementation of any CSS features. Testcases submitted to W3C are subject to review and correction by the CSS Working Group.

Further information on submitting testcases and implementation reports can be found from on the CSS Working Group’s website at http://www.w3.org/Style/CSS/Test/. Questions should be directed to the public-css-testsuite@w3.org mailing list.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[CSS-ANIMATIONS-2]
David Baron; Brian Birtles. CSS Animations Level 2. URL: https://drafts.csswg.org/css-animations-2/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. URL: https://drafts.csswg.org/css-box-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. URL: https://drafts.csswg.org/css-cascade-5/
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 4. URL: https://drafts.csswg.org/css-display/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 3. URL: https://drafts.csswg.org/css-position-3/
[CSS-SCOPING-1]
Tab Atkins Jr.; Elika Etemad. CSS Scoping Module Level 1. URL: https://drafts.csswg.org/css-scoping/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. URL: https://drafts.csswg.org/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. URL: https://drafts.csswg.org/css-values-4/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. URL: https://drafts.csswg.org/css-writing-modes-4/
[CSS2]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. URL: https://drafts.csswg.org/css2/
[CSSOM-VIEW-1]
Simon Pieters. CSSOM View Module. URL: https://drafts.csswg.org/cssom-view/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SCROLL-ANIMATIONS-1]
Brian Birtles; et al. Scroll-driven Animations. URL: https://drafts.csswg.org/scroll-animations-1/
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. Selectors Level 4. URL: https://drafts.csswg.org/selectors/
[WEB-ANIMATIONS-1]
Brian Birtles; et al. Web Animations. URL: https://drafts.csswg.org/web-animations-1/
[WEB-ANIMATIONS-2]
Brian Birtles; Robert Flack. Web Animations Level 2. URL: https://drafts.csswg.org/web-animations-2/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

Informative References

[CSS-ANIMATIONS-1]
David Baron; et al. CSS Animations Level 1. URL: https://drafts.csswg.org/css-animations/
[CSS-TRANSFORMS-1]
Simon Fraser; et al. CSS Transforms Module Level 1. URL: https://drafts.csswg.org/css-transforms/

Property Index

Name Value Initial Applies to Inh. %ages Anim­ation type Canonical order Com­puted value
animation-range-center [ normal | [ <length-percentage> | <timeline-range-center-subject> <length-percentage>? ] ]# normal all elements no relative to the corresponding dimension of the specified timeline range center subject, else relative to the start of the animation attachment range not animatable per grammar list, each item either the keyword normal or a timeline range center subject and a length-percentage value
pointer-timeline [ <'pointer-timeline-name'> <'pointer-timeline-axis'>? ]# see individual properties all elements see individual properties see individual properties see individual properties per grammar see individual properties
pointer-timeline-axis [ block | inline | x | y ]# block all elements no n/a not animatable per grammar a list of the keywords specified
pointer-timeline-name [ none | <dashed-ident> ]# none all elements no n/a not animatable per grammar the keyword none or a list of CSS identifiers

IDL Index

enum PointerAxis {
  "block",
  "inline",
  "x",
  "y"
};

dictionary PointerTimelineOptions {
  Element? source;
  PointerAxis axis = "block";
};

[Exposed=Window]
interface PointerTimeline : AnimationTimeline {
  constructor(optional PointerTimelineOptions options = {});
  readonly attribute Element? source;
  readonly attribute PointerAxis axis;
};

Issues Index

Insert diagrams.
This section should move to CSS-ANIMATIONS-2 and WEB-ANIMATIONS-2.