Fullscreen API

Living Standard — Last Updated 29 April 2016

Participate:
GitHub whatwg/fullscreen (file an issue, open issues)
IRC: #whatwg on Freenode
Commits:
GitHub whatwg/fullscreen/commits
@fullscreenapi

Abstract

The Fullscreen API standard defines an API for elements to display themselves fullscreen.

Table of Contents

  1. 1 Conformance
  2. 2 Terminology
  3. 3 Model
  4. 4 API
  5. 5 UI
  6. 6 Rendering
    1. 6.1 New stacking layer
    2. 6.2 ::backdrop pseudo-element
    3. 6.3 :fullscreen pseudo-class
    4. 6.4 User-agent level style sheet defaults
  7. 7 Security and Privacy Considerations
  8. References
  9. Acknowledgments

1 Conformance

All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.

The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this specification are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]

2 Terminology

Most terminology used in this specification is from CSS, DOM, HTML, and Web IDL. [CSS] [DOM] [HTML] [WEBIDL]

The term context object means the object on which the method or attribute being discussed was called. When the context object is unambiguous, the term can be omitted.

A browsing context A is called a descendant browsing context of a browsing context B if and only if B is an ancestor browsing context of A.

3 Model

All elements have an associated fullscreen flag. Unless stated otherwise it is unset.

All iframe elements have an associated iframe fullscreen flag. Unless stated otherwise it is unset.

All documents have an associated fullscreen enabled flag. Unless stated otherwise it is unset.

HTML defines the exact conditions under which the fullscreen enabled flag is set. A document from a top-level browsing context will have it set. For a nested browsing context it is only set if the iframe element that is responsible for creating the nested browsing context has its allowfullscreen attribute set. That attribute is defined by HTML as well. [HTML]

All documents have an associated fullscreen element. The fullscreen element is the topmost element in the document's top layer whose fullscreen flag is set, if any, and null otherwise.

To fullscreen an element within a document, set the element's fullscreen flag and add it to document's top layer.

To unfullscreen an element within a document, unset the element's fullscreen flag and iframe fullscreen flag (if any), and remove it from document's top layer.

To unfullscreen a document, unfullscreen all elements, within document's top layer, whose fullscreen flag is set.


To fully exit fullscreen a document document, run these steps:

  1. If document's fullscreen element is null, terminate these steps.

  2. Unfullscreen elements whose fullscreen flag is set, within document's top layer, except for document's fullscreen element.

  3. Exit fullscreen document.

Whenever the removing steps run with an oldNode, run these steps:

  1. Let nodes be oldNode's inclusive descendants that have their fullscreen flag set, in tree order.

  2. For each node in nodes, run these substeps:

    1. If node is its node document's fullscreen element, exit fullscreen that document.

    2. Otherwise, unfullscreen node within its node document.

Whenever the unloading document cleanup steps run with a document, fully exit fullscreen document.


Fullscreen is supported if there is no previously-established user preference, security risk, or platform limitation.

4 API

partial interface Element {
  Promise<void> requestFullscreen();
};

partial interface Document {
  [Replaceable] readonly attribute boolean fullscreenEnabled;
  [Replaceable] readonly attribute Element? fullscreenElement;

  Promise<void> exitFullscreen();

  attribute EventHandler onfullscreenchange;
  attribute EventHandler onfullscreenerror;
};
promise = element . requestFullscreen()

Displays element fullscreen and fulfills promise when done.

document . fullscreenEnabled

Returns true if document has the ability to display elements fullscreen and fullscreen is supported, or false otherwise.

document . fullscreenElement

Returns document's fullscreen element.

promise = document . exitFullscreen()

Stops document's fullscreen element from being displayed fullscreen and fulfills promise when done.

A fullscreen element ready check for an element element returns true if all of the following are true, and false otherwise:

The requestFullscreen() method, when invoked, must run these steps:

  1. Let pending be the context object.

  2. Let error be false.

  3. Let promise be a new promise.

  4. If any of the following conditions are true, set error to true:

  5. Return promise, and run the remaining steps in parallel.

  6. If error is false: Resize pending's top-level browsing context's document's viewport's dimensions to match the dimensions of the screen of the output device. Optionally display a message how the end user can revert this.

  7. As part of the next animation frame task, run these substeps:

    1. If either error is true or the fullscreen element ready check for pending returns false, fire an event named fullscreenerror on pending's node document, reject promise with a TypeError exception, and terminate these steps.

    2. Let fullscreenElements be an ordered set initially consisting of pending.

    3. While the first element in fullscreenElements is in a nested browsing context, prepend its browsing context container to fullscreenElements.

    4. Let eventDocs be an empty list.

    5. For each element in fullscreenElements, in order, run these subsubsteps:

      1. Let doc be element's node document.

      2. If element is doc's fullscreen element, terminate these subsubsteps.

        No need to notify observers when nothing has changed.

      3. Otherwise, append doc to eventDocs.

      4. If element is pending and pending is an iframe element, set element's iframe fullscreen flag.

      5. Fullscreen element within doc.

    6. For each doc in eventDocs, in order, fire an event named fullscreenchange on doc.

    7. Fulfill promise with undefined.

    Animation frame task is not really defined yet, including relative order within that task, see bug 26440.

    Implementations with out-of-process browsing contexts are left as an exercise to the reader. Input welcome on potential improvements.

The fullscreenEnabled attribute's getter must return true if the context object has its fullscreen enabled flag set and fullscreen is supported, and false otherwise.

The fullscreenElement attribute's getter must return context object's fullscreen element.

To collect documents to unfullscreen given doc, run these steps:

  1. If doc's top layer consists of more than a single element that has its fullscreen flag set, return the empty set.

  2. Let docs be an ordered set consisting of doc.

  3. While docs's last document has a browsing context container whose node document's top layer consists of a single element that has its fullscreen flag set and does not have its iframe fullscreen flag set (if any), append that node document to docs.

  4. Return docs.

To exit fullscreen a document doc, run these steps:

  1. Let promise be a new promise.

  2. If doc's fullscreen element is null, reject promise with a TypeError exception, and return promise.

  3. Let resize be false.

  4. Let docs be the result of collecting documents to unfullscreen given doc.

  5. Let topLevelDoc be doc's top-level browsing context's document.

  6. If topLevelDoc is in docs, set resize to true.

  7. Return promise, and run the remaining steps in parallel.

  8. If resize is true, resize topLevelDoc's viewport to its "normal" dimensions.

  9. As part of the next animation frame task, run these substeps:

    1. Let exitDocs be the result of collecting documents to unfullscreen given doc.

    2. If resize is true and topLevelDoc is not in exitDocs, fully exit fullscreen topLevelDoc, reject promise with a TypeError exception, and terminate these steps.

    3. If exitDocs is the empty set, append doc to exitDocs.

    4. If exitDocs's last document has a browsing context container, append that browsing context container's node document to exitDocs.

    5. Let descendantDocs be an ordered set consisting of doc's descendant browsing contexts' documents whose fullscreen element is non-null, if any, in reverse tree order.

    6. For each descendantDoc in descendantDocs, in order, unfullscreen descendantDoc.

    7. For each exitDoc in exitDocs, in order, unfullscreen exitDoc's fullscreen element.

    8. For each descendantDoc in descendantDocs, in order, fire an event named fullscreenchange on descendantDoc.

    9. For each exitDoc in exitDocs, in order, fire an event named fullscreenchange on exitDoc.

    10. Fulfill promise with undefined.

    This results in events being fired from the innermost to the outermost document.

The exitFullscreen() method, when invoked, must return the result of running exit fullscreen on the context object.


The following are the event handlers (and their corresponding event handler event types) that must be supported on documents as attributes:

event handler event handler event type
onfullscreenchange fullscreenchange
onfullscreenerror fullscreenerror

5 UI

User agents are encouraged to implement native media fullscreen controls in terms of requestFullscreen() and exitFullscreen().

If the end user instructs the user agent to end a fullscreen session initiated via requestFullscreen(), fully exit fullscreen the top-level browsing context's document.

6 Rendering

This section is to be interpreted equivalently to the Rendering section of HTML. [HTML]

Long term CSS will define the top layer concept and its associated ::backdrop pseudo-element as part of CSS' stacking context model. Patching CSS as done here is sketchy as hell.

6.1 New stacking layer

This specification introduces a new stacking layer to the Elaborate description of Stacking Contexts of CSS 2.1. It is called the top layer, comes after step 10 in the painting order, and is therefore rendered closest to the user within a viewport. Each document has one associated viewport and therefore also one top layer. [CSS]

The terminology used in this and following subsection attempts to match CSS 2.1 Appendix E.

The top layer consists of an ordered set of elements, rendered in the order they have been added to the set. The last element added is rendered closest to the user.

The z-index property has no effect in the top layer.

Each element and ::backdrop pseudo-element in a top layer has the following characteristics:

To add an element to a top layer, add, or move if already present, element on top of top layer.

To remove an element from a top layer, remove element from top layer.

6.2 ::backdrop pseudo-element

Each element in a top layer has a ::backdrop pseudo-element. This pseudo-element is a box rendered immediately below the element (and above the element before the element in the set, if any), within the same top layer.

The ::backdrop pseudo-element can be used to create a backdrop that hides the underlying document for an element in a top layer (such as an element that is displayed fullscreen).

It does not inherit from any element and is not inherited from. No restrictions are made on what properties apply to this pseudo-element either.

6.3 :fullscreen pseudo-class

The :fullscreen pseudo-class must match any element that has its fullscreen flag set.

This makes it different from the fullscreenElement API, which returns a document's fullscreen element.

6.4 User-agent level style sheet defaults

@namespace "http://www.w3.org/1999/xhtml";

*|*:not(:root):fullscreen {
  position:fixed !important;
  top:0 !important; right:0 !important; bottom:0 !important; left:0 !important;
  margin:0 !important;
  box-sizing:border-box !important;
  min-width:0 !important;
  max-width:none !important;
  min-height:0 !important;
  max-height:none !important;
  width:100% !important;
  height:100% !important;
  object-fit:contain !important;
  transform:none !important;
}

iframe:fullscreen {
  border:none !important;
  padding:0 !important;
}

::backdrop {
  position:fixed;
  top:0; right:0; bottom:0; left:0;
}

*|*:not(:root):fullscreen::backdrop {
  background:black;
}

7 Security and Privacy Considerations

User agents should ensure, e.g. by means of an overlay, that the end user is aware something is displayed fullscreen. User agents should provide a means of exiting fullscreen that always works and advertise this to the user. This is to prevent a site from spoofing the end user by recreating the user agent or even operating system environment when fullscreen. See also the definition of requestFullscreen().

To enable content in a nested browsing context to go fullscreen, it needs to be specifically allowed via the allowfullscreen attribute of the HTML iframe element. This prevents e.g. content from third parties to go fullscreen without explicit permission.

References

[CSS]
CSS, Bert Bos, Tantek Çelik, Ian Hickson et al.. W3C.
[DOM]
DOM, Anne van Kesteren, Aryeh Gregor and Ms2ger. WHATWG.
[HTML]
HTML, Ian Hickson. WHATWG.
[MATHML]
Mathematical Markup Language (MathML), David Carlisle, Patrick Ion and Robert Miner. W3C.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner. IETF.
[SVG]
Scalable Vector Graphics (SVG), O. Andersson, R. Berjon, E. Dahlström et al.. W3C.
[WEBIDL]
Web IDL, Cameron McCormack. W3C.

Acknowledgments

Many thanks to Robert O'Callahan for designing the initial model and being awesome.

Thanks to Andy Earnshaw, Chris Pearce, Darin Fisher, Edward O'Connor, fantasai, Giuseppe Pascale, Glenn Maynard, Ian Hickson, Ignacio Solla, João Eiras, Josh Soref, Matt Falkenhagen, Mihai Balan, Øyvind Stenhaug, Pat Ladd, Philip Jägenstedt, Rafał Chłodnicki, Riff Jiang, Rune Lillesveen, Sigbjørn Vik, Simon Pieters, Tab Atkins, Vincent Scheib, and Xidorn Quan for also being awesome.

This standard is written by Anne van Kesteren (Mozilla, annevk@annevk.nl). Tantek Çelik (Mozilla, tantek@cs.stanford.edu) sorted out legal hassles.

Per CC0, to the extent possible under law, the editor has waived all copyright and related or neighboring rights to this work.