# Layout Instability API

## Draft Community Group Report, 1 January 1970

This version:
  https://wicg.github.io/layout-instability
Editors:
  Steve Kobes (Google) skobes@chromium.org
  Nicolás Peña Moreno (Google) npm@chromium.org
  Emily Hanley (Google) eyaich@chromium.org

Copyright © 1970 the Contributors to the Layout Instability API Specification, published by the Web Platform Incubator Community Group under the W3C Community Contributor License Agreement (CLA). A human-readable summary is available.

## Abstract

This document defines an API that provides web page authors with insights into the stability of their pages based on movements of the elements on the page.

## Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

## 1. Introduction

This section is non-normative.

The shifting of DOM elements on a webpage detracts from the user’s experience, and occurs frequently on the web today. This shifting is often due to content loading asynchronously and displacing other elements on the page.

The layout Instability API identifies these unstable pages by reporting a value (the "layout shift") for each animation frame in the user’s session. This specification presents a method for a user agent to compute the layout shift value.

The layout shift value is expected to have a general correspondence to the severity of layout instability at a particular time. The method of computing it considers both the area of the region impacted by instability and the distance by which elements on the page are shifted.

The developer can use the layout shift values that are reported by this API to compute a cumulative score (the "cumulative layout shift score").

The cumulative layout shift score is expected to have a general correspondence to the severity of layout instability for the lifetime of a page.

### 1.1. End of session signal

This section is non-normative.

The developer can compute a cumulative layout shift score by summing the layout shift values as they are reported to the observer.

A "final" score for the user’s session can be reported by listening to the visibilitychange event, and taking the value of the cumulative layout shift score at that time.

This strategy is illustrated in the usage example.

### 1.2. Usage example

This section is non-normative.

    // Stores the current layout shift score for the page.
    let cumulativeLayoutShiftScore = 0;

    // Detects new layout shift occurrences and updates the
    // `cumulativeLayoutShiftScore` variable.
    const observer = new PerformanceObserver((list) => {
      for (const entry of list.getEntries()) {
        // Only count layout shifts without recent user input.
        if (!entry.hadRecentInput) {
          cumulativeLayoutShiftScore += entry.value;
        }
      }
    });

    observer.observe({type: 'layout-shift', buffered: true});

    // Sends the final score to your analytics back end once
    // the page’s lifecycle state becomes hidden.
    document.addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'hidden') {
        // Force any pending records to be dispatched.
        observer.takeRecords();

        // Send the final score to your analytics back end
        // (assumes `sendToAnalytics` is defined elsewhere).
        sendToAnalytics({cumulativeLayoutShiftScore});
      }
    });

The layout shift score is only one signal, which correlates in an approximate manner with the user experience of "jumpiness".

Developers should avoid relying on the precise value of the layout shift score, as the metric might evolve over time, and user agents might compromise precision in the interest of calculation efficiency.

## 2. Terminology

### 2.1. Basic Concepts

The starting point of a `Node` N in a coordinate space C is defined as follows:

- If N is an `Element` which generates one or more boxes, the starting point of N in C is the two-dimensional offset in pixel units from the origin of C to the flow-relative starting corner of the first fragment of the principal box of N.

- If N is a text node, the starting point of N in C is the two-dimensional offset in pixel units from the origin of C to the flow-relative starting corner of the first line box generated by N.

The visual representation of a `Node` N is defined as follows:

- If N is an `Element` which generates one or more boxes, the visual representation of N is the set of all points that lie within the bounds of any fragment of any box generated by N, in the coordinate space of the viewport, excluding any points that lie outside of the viewport.

- If N is a text node, the visual representation of N is the set of all points that lie within the bounds of any line box generated by N, in the coordinate space of the viewport, excluding any points that lie outside of the viewport.

A condition holds in the previous frame if it was true at the point in time immediately after the most recently completed invocation of the report the layout shift algorithm.

The previous frame starting point of a `Node` N in a coordinate space C is the point which, in the previous frame, was the starting point of N in C.

The previous frame visual representation of a `Node` N is the set which, in the previous frame, was the visual representation of N.

### 2.2. Unstable Nodes

A `Node` N has shifted in a coordinate space C if the starting point of N in C differs from the previous frame starting point of N in C by 3 or more pixel units in either the horizontal or vertical direction.

Otherwise, N has not shifted in C.

A `Node` N is unstable if:

- N is either

  - an `Element` which generates one or more boxes, or

  - a text node; and

- N has shifted in the coordinate space of the viewport; and

- N has shifted in the coordinate space of the initial containing block; and

- there does not exist an `Element` P such that

  1. currently and in the previous frame, P is in the containing block chain of N, and

  2. currently and in the previous frame, P has a local coordinate system or a scrollable overflow region, and

  3. P is not unstable, and

  4. N has not shifted in the coordinate space of the local coordinate system or scrollable overflow region of P.

The unstable node set of a `Document` D is the set containing every unstable shadow-including descendant of D.

NOTE: In the first frame, the previous frame starting point does not exist for any node, and therefore the unstable node set is empty.

### 2.3. Layout Shift Value

The viewport base distance is the greater of the visual viewport width or the visual viewport height.

The move vector of a `Node` N is the two-dimensional offset in pixel units from

- the previous frame starting point of N in the coordinate space of the viewport, to

- the starting point of N in the coordinate space of the viewport.

The move distance of a `Node` N is the greater of

- the absolute value of the horizontal component of the move vector of N, or

- the absolute value of the vertical component of the move vector of N.

The maximum move distance of a `Document` D is the greatest move distance of any `Node` in the unstable node set of D, or 0 if the unstable node set of D is empty.

The distance fraction of a `Document` D is the lesser of

- the maximum move distance of D divided by the viewport base distance, or

- 1.0.

The impact region of a `Document` D is the set containing

- every point in the visual representation of any `Node` in the unstable node set of D, and

- every point in the previous frame visual representation of any `Node` in the unstable node set of D.

The impact fraction of a `Document` D is the area of the impact region divided by the area of the viewport.

The layout shift value of a `Document` D is the impact fraction of D multiplied by the distance fraction of D.

NOTE: The layout shift value takes into account both the fraction of the viewport that has been impacted by layout instability as well as the greatest distance by which any given element has moved. This recognizes that a large element which moves only a small distance can have a low impact on the perceived instability of the page.

### 2.4. Input Exclusion

An excluding input is any event from an input device which signals a user’s active interaction with the document, or any event which directly changes the size of the viewport.

Excluding inputs generally include mousedown, keydown, and pointerdown. However, an event whose only effect is to begin or update a fling or scroll gesture is not an excluding input.

The user agent may delay the reporting of layout shifts after a pointerdown event until such time as it is known that the event does not begin a fling or scroll gesture.

The mousemove and pointermove events are also not excluding inputs.

## 3. `LayoutShift` interface

    [Exposed=Window]
    interface LayoutShift : PerformanceEntry {
      readonly attribute long value;
      readonly attribute boolean hadRecentInput;
      readonly attribute DOMHighResTimeStamp lastInputTime;
      [Default] object toJSON();
    };

All attributes have the values which are assigned to them by the steps to report the layout shift.

A user agent implementing the Layout Instability API MUST include `"layout-shift"` in `supportedEntryTypes` for Window contexts. This allows developers to detect support for the Layout Instability API.

## 4. Processing model

Within the update the rendering step of the event loop processing model, a user agent implementing the Layout Instability API MUST perform the following step after the step that invokes the mark paint timing algorithm:

1. For each fully active `Document` in docs, invoke the algorithm to report the layout shift for that `Document`.

### 4.1. Report the layout shift

When asked to report the layout shift for an active `Document` D, run the following steps:

1. If the current layout shift value of D is not 0:

   1. Create a new `LayoutShift` object newEntry.

   2. Set newEntry’s `name` attribute to `"layout-shift"`.

   3. Set newEntry’s `entryType` attribute to `"layout-shift"`.

   4. Set newEntry’s `startTime` attribute to current high resolution time.

   5. Set newEntry’s `duration` attribute to 0.

   6. Set newEntry’s `value` attribute to the current layout shift value of D.

   7. Set newEntry’s `lastInputTime` attribute to the time of the most recent excluding input, or 0 if no excluding input has occurred during the browsing session.

   8. Set newEntry’s `hadRecentInput` attribute to `true` if `lastInputTime` is less than 500 milliseconds in the past, and `false` otherwise.

   9. Queue the PerformanceEntry newEntry object.

## 5. Security & privacy considerations

Layout instability bears an indirect relationship to resource timing, as slow resources could cause intermediate layouts that would not otherwise be performed. Resource timing information can be used by malicious websites for statistical fingerprinting. The layout instability API only reports instability in the current browsing context. It does not directly provide any aggregation of instability scores across multiple browsing contexts. Developers can implement such aggregation manually, but browsing contexts with different origins would need to cooperate to share instability scores.

## Conformance

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.

## Index

### Terms defined by this specification

- distance fraction, in §2.3
- excluding input, in §2.4
- hadRecentInput, in §4.1
- has not shifted, in §2.2
- has shifted, in §2.2
- impact fraction, in §2.3
- impact region, in §2.3
- in the previous frame, in §2.1
- lastInputTime, in §4.1
- LayoutShift, in §3
- layout shift value, in §2.3
- maximum move distance, in §2.3
- move distance, in §2.3
- move vector, in §2.3
- previous frame starting point, in §2.1
- previous frame visual representation, in §2.1
- report the layout shift, in §4.1
- starting point, in §2.1
- toJSON(), in §3
- unstable, in §2.2
- unstable node set, in §2.2
- value, in §4.1
- viewport base distance, in §2.3
- visual representation, in §2.1

https://drafts.csswg.org/css-break-4/#fragment Referenced in:

- 2.1. Basic Concepts (2)

https://drafts.csswg.org/css-display-3/#box Referenced in:

- 2.1. Basic Concepts (2) (3)
- 2.2. Unstable Nodes

https://drafts.csswg.org/css-display-3/#containing-block-chain Referenced in:

- 2.2. Unstable Nodes

https://drafts.csswg.org/css-display-3/#principal-box Referenced in:

- 2.1. Basic Concepts

https://drafts.csswg.org/css-display-3/#text-nodes Referenced in:

- 2.1. Basic Concepts (2)
- 2.2. Unstable Nodes

https://drafts.csswg.org/css-overflow-3/#scrollable-overflow-region Referenced in:

- 2.2. Unstable Nodes (2)

https://www.w3.org/TR/css-text-3/#line-breaking Referenced in:

- 2.1. Basic Concepts (2)

https://drafts.csswg.org/css-transforms-1/#local-coordinate-system Referenced in:

- 2.2. Unstable Nodes (2)

https://www.w3.org/TR/css-values-4/#pixel-unit Referenced in:

- 2.1. Basic Concepts (2)
- 2.2. Unstable Nodes
- 2.3. Layout Shift Value

https://drafts.csswg.org/css-writing-modes-4/#flow-relative Referenced in:

- 2.1. Basic Concepts (2)

https://www.w3.org/TR/CSS2/visudet.html#containing-block-details Referenced in:

- 2.2. Unstable Nodes

https://www.w3.org/TR/cssom-view-1/#viewport Referenced in:

- 2.1. Basic Concepts (2) (3) (4)
- 2.2. Unstable Nodes
- 2.3. Layout Shift Value (2) (3)
- 2.4. Input Exclusion

https://dom.spec.whatwg.org/#document Referenced in:

- 2.2. Unstable Nodes
- 2.3. Layout Shift Value (2) (3) (4) (5)
- 4. Processing model (2)
- 4.1. Report the layout shift

https://dom.spec.whatwg.org/#element Referenced in:

- 2.1. Basic Concepts (2)
- 2.2. Unstable Nodes (2)

https://dom.spec.whatwg.org/#node Referenced in:

- 2.1. Basic Concepts (2) (3) (4)
- 2.2. Unstable Nodes (2)
- 2.3. Layout Shift Value (2) (3) (4) (5)

https://dom.spec.whatwg.org/#concept-shadow-including-descendant Referenced in:

- 2.2. Unstable Nodes

https://w3c.github.io/hr-time/#idl-def-domhighrestimestamp Referenced in:

- 3. LayoutShift interface

https://w3c.github.io/hr-time/#dfn-current-high-resolution-time Referenced in:

- 4.1. Report the layout shift

https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model Referenced in:

- 4. Processing model

https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering Referenced in:

- 4. Processing model

https://w3c.github.io/paint-timing/#mark-paint-timing Referenced in:

- 4. Processing model

https://w3c.github.io/performance-timeline/#the-performanceentry-interface Referenced in:

- 3. LayoutShift interface

https://w3c.github.io/performance-timeline/#dom-performanceentry-duration Referenced in:

- 4.1. Report the layout shift

https://w3c.github.io/performance-timeline/#dom-performanceentry-entrytype Referenced in:

- 4.1. Report the layout shift

https://w3c.github.io/performance-timeline/#dom-performanceentry-name Referenced in:

- 4.1. Report the layout shift

https://w3c.github.io/performance-timeline/#dom-performanceentry-starttime Referenced in:

- 4.1. Report the layout shift

https://w3c.github.io/performance-timeline/#supportedentrytypes-attribute Referenced in:

- 3. LayoutShift interface

https://w3c.github.io/resource-timing/#sec-privacy-security Referenced in:

- 5. Security & privacy considerations

https://wicg.github.io/visual-viewport/index.html#dom-visualviewport-height Referenced in:

- 2.3. Layout Shift Value

https://wicg.github.io/visual-viewport/index.html#dom-visualviewport-width Referenced in:

- 2.3. Layout Shift Value

https://heycam.github.io/webidl/#Default Referenced in:

- 3. LayoutShift interface

https://heycam.github.io/webidl/#Exposed Referenced in:

- 3. LayoutShift interface

https://heycam.github.io/webidl/#idl-boolean Referenced in:

- 3. LayoutShift interface

https://heycam.github.io/webidl/#idl-long Referenced in:

- 3. LayoutShift interface

https://heycam.github.io/webidl/#idl-object Referenced in:

- 3. LayoutShift interface

### Terms defined by reference

- [css-break-4] defines the following terms:
  - fragment
- [css-display-3] defines the following terms:
  - box
  - containing block chain
  - principal box
  - text node
- [css-overflow-3] defines the following terms:
  - scrollable overflow region
- [css-text-3] defines the following terms:
  - line box
- [css-transforms-1] defines the following terms:
  - local coordinate system
- [css-values-4] defines the following terms:
  - pixel units
- [css-writing-modes-4] defines the following terms:
  - flow-relative
- [CSS2] defines the following terms:
  - initial containing block
- [cssom-view-1] defines the following terms:
  - viewport
- [DOM] defines the following terms:
  - Document
  - Element
  - Node
  - shadow-including descendants
- [hr-time-2] defines the following terms:
  - DOMHighResTimeStamp
  - current high resolution time
- [HTML] defines the following terms:
  - event loop processing model
  - update the rendering
- [paint-timing] defines the following terms:
  - mark paint timing
- [performance-timeline-2] defines the following terms:
  - PerformanceEntry
  - duration
  - entryType
  - name
  - startTime
  - supportedEntryTypes
- [resource-timing-1] defines the following terms:
  - statistical fingerprinting
- [VISUAL-VIEWPORT] defines the following terms:
  - visual viewport height
  - visual viewport width
- [WebIDL] defines the following terms:
  - Default
  - Exposed
  - boolean
  - long
  - object

## References

### Normative References

[CSS-BREAK-4]
  Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 4. 18 December 2018. WD. URL: https://www.w3.org/TR/css-break-4/
[CSS-DISPLAY-3]
  Tab Atkins Jr.; Elika Etemad. CSS Display Module Level 3. 28 August 2018. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-OVERFLOW-3]
  David Baron; Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 31 July 2018. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-TEXT-3]
  Elika Etemad; Koji Ishii; Florian Rivoal. CSS Text Module Level 3. 12 December 2018. WD. URL: https://www.w3.org/TR/css-text-3/
[CSS-TRANSFORMS-1]
  Simon Fraser; et al. CSS Transforms Module Level 1. 14 February 2019. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS-VALUES-4]
  Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 31 January 2019. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-4]
  Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 24 May 2018. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
  Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. REC. URL: https://www.w3.org/TR/CSS2/
[CSSOM-VIEW-1]
  Simon Pieters. CSSOM View Module. 17 March 2016. WD. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
  Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[HR-TIME-2]
  Ilya Grigorik; James Simonsen; Jatinder Mann. High Resolution Time Level 2. 1 March 2018. CR. URL: https://www.w3.org/TR/hr-time-2/
[HTML]
  Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[PAINT-TIMING]
  Shubhie Panicker. Paint Timing 1. 7 September 2017. WD. URL: https://www.w3.org/TR/paint-timing/
[PERFORMANCE-TIMELINE-2]
  Ilya Grigorik. Performance Timeline Level 2. 23 April 2019. WD. URL: https://www.w3.org/TR/performance-timeline-2/
[RESOURCE-TIMING-1]
  Arvind Jain; et al. Resource Timing Level 1. 30 March 2017. CR. URL: https://www.w3.org/TR/resource-timing-1/
[RFC2119]
  S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[VISUAL-VIEWPORT]
  Visual Viewport API. Living Standard. URL: https://wicg.github.io/visual-viewport/
[WebIDL]
  Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

## IDL Index

    [Exposed=Window]
    interface LayoutShift : PerformanceEntry {
      readonly attribute long value;
      readonly attribute boolean hadRecentInput;
      readonly attribute DOMHighResTimeStamp lastInputTime;
      [Default] object toJSON();
    };

#starting-point Referenced in:

- 2.1. Basic Concepts
- 2.2. Unstable Nodes
- 2.3. Layout Shift Value

#visual-representation Referenced in:

- 2.1. Basic Concepts
- 2.3. Layout Shift Value

#in-the-previous-frame Referenced in:

- 2.1. Basic Concepts (2)
- 2.2. Unstable Nodes (2)

#previous-frame-starting-point Referenced in:

- 2.2. Unstable Nodes
- 2.3. Layout Shift Value

#previous-frame-visual-representation Referenced in:

- 2.3. Layout Shift Value

#has-shifted Referenced in:

- 2.2. Unstable Nodes (2)

#has-not-shifted Referenced in:

- 2.2. Unstable Nodes

#unstable Referenced in:

- 2.2. Unstable Nodes (2)

#unstable-node-set Referenced in:

- 2.3. Layout Shift Value (2) (3) (4)

#viewport-base-distance Referenced in:

- 2.3. Layout Shift Value

#move-vector Referenced in:

- 2.3. Layout Shift Value (2)

#move-distance Referenced in:

- 2.3. Layout Shift Value

#maximum-move-distance Referenced in:

- 2.3. Layout Shift Value

#distance-fraction Referenced in:

- 2.3. Layout Shift Value

#impact-region Referenced in:

- 2.3. Layout Shift Value

#impact-fraction Referenced in:

- 2.3. Layout Shift Value

#layout-shift-value Referenced in:

- 4.1. Report the layout shift (2)

#excluding-input Referenced in:

- 4.1. Report the layout shift

#layoutshift Referenced in:

- 3. LayoutShift interface
- 4.1. Report the layout shift

#report-the-layout-shift Referenced in:

- 2.1. Basic Concepts
- 3. LayoutShift interface
- 4. Processing model

#dom-layoutshift-value Referenced in:

- 3. LayoutShift interface

#dom-layoutshift-lastinputtime Referenced in:

- 3. LayoutShift interface
- 4.1. Report the layout shift

#dom-layoutshift-hadrecentinput Referenced in:

- 3. LayoutShift interface