1. 6 User interaction
    1. 6.1 The hidden attribute
    2. 6.2 Page visibility
      1. 6.2.1 The VisibilityStateEntry interface
    3. 6.3 Inert subtrees
      1. 6.3.1 Modal dialogs and inert subtrees
      2. 6.3.2 The inert attribute
    4. 6.4 Tracking user activation
      1. 6.4.1 Data model
      2. 6.4.2 Processing model
      3. 6.4.3 APIs gated by user activation
      4. 6.4.4 The UserActivation interface
      5. 6.4.5 User agent automation
    5. 6.5 Activation behavior of elements
      1. 6.5.1 The ToggleEvent interface
      2. 6.5.2 The CommandEvent interface
    6. 6.6 Focus
      1. 6.6.1 Introduction
      2. 6.6.2 Data model
      3. 6.6.3 The tabindex attribute
      4. 6.6.4 Processing model
      5. 6.6.5 Sequential focus navigation
      6. 6.6.6 Focus management APIs
      7. 6.6.7 The autofocus attribute
    7. 6.7 Assigning keyboard shortcuts
      1. 6.7.1 Introduction
      2. 6.7.2 The accesskey attribute
      3. 6.7.3 Processing model
    8. 6.8 Editing
      1. 6.8.1 Making document regions editable: The contenteditable content attribute
      2. 6.8.2 Making entire documents editable: the designMode getter and setter
      3. 6.8.3 Best practices for in-page editors
      4. 6.8.4 Editing APIs
      5. 6.8.5 Spelling and grammar checking
      6. 6.8.6 Writing suggestions
      7. 6.8.7 Autocapitalization
      8. 6.8.8 Autocorrection
      9. 6.8.9 Input modalities: the inputmode attribute
      10. 6.8.10 Input modalities: the enterkeyhint attribute
    9. 6.9 Find-in-page
      1. 6.9.1 Introduction
      2. 6.9.2 Interaction with details and hidden=until-found
      3. 6.9.3 Interaction with selection
    10. 6.10 Close requests and close watchers
      1. 6.10.1 Close requests
      2. 6.10.2 Close watcher infrastructure
      3. 6.10.3 The CloseWatcher interface

6 User interaction

6.1 The hidden attribute

Global_attributes/hidden

Support in one engine only.

FirefoxNoSafariNoChrome102+
OperaNoEdge102+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Global_attributes/hidden

Support in all current engines.

Firefox4+Safari5.1+Chrome10+
Opera?Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android4+Samsung Internet?Opera Android?

All HTML elements may have the hidden content attribute set. The hidden attribute is an enumerated attribute with the following keywords and states:

Keyword State Brief description
hidden Hidden Will not be rendered.
(the empty string)
until-found Hidden Until Found Will not be rendered, but content inside will be accessible to find-in-page and fragment navigation.

The attribute's missing value default is the Not Hidden state, and its invalid value default is the Hidden state.

When an element has the hidden attribute in the Hidden state, it indicates that the element is not yet, or is no longer, directly relevant to the page's current state, or that it is being used to declare content to be reused by other parts of the page as opposed to being directly accessed by the user. User agents should not render elements that are in the Hidden state.

The requirement for user agents not to render elements that are in the Hidden state can be implemented indirectly through the style layer. For example, a web browser could implement these requirements using the rules suggested in the Rendering section.

When an element has the hidden attribute in the Hidden Until Found state, it indicates that the element is hidden like the Hidden state but the content inside the element will be accessible to find-in-page and fragment navigation. When these features attempt to scroll to a target which is in the element's subtree, the user agent will remove the hidden attribute in order to reveal the content before scrolling to it by running the ancestor hidden-until-found revealing algorithm on the target node.

Web browsers will use 'content-visibility: hidden' instead of 'display: none' when the hidden attribute is in the Hidden Until Found state, as specified in the Rendering section.

Because this attribute is typically implemented using CSS, it's also possible to override it using CSS. For instance, a rule that applies 'display: block' to all elements will cancel the effects of the Hidden state. Authors therefore have to take care when writing their style sheets to make sure that the attribute is still styled as expected. In addition, legacy user agents which don't support the Hidden Until Found state will have 'display: none' instead of 'content-visibility: hidden', so authors are encouraged to make sure that their style sheets don't change the 'display' or 'content-visibility' properties of Hidden Until Found elements.

Since elements with the hidden attribute in the Hidden Until Found state use 'content-visibility: hidden' instead of 'display: none', there are two caveats of the Hidden Until Found state that make it different from the Hidden state:

  1. The element needs to be affected by layout containment in order to be revealed by find-in-page. This means that if the element in the Hidden Until Found state has a 'display' value of 'none', 'contents', or 'inline', then the element will not be revealed by find-in-page.

  2. The element will still have a generated box when in the Hidden Until Found state, which means that borders, margin, and padding will still be rendered around the element.

In the following skeletal example, the attribute is used to hide the web game's main screen until the user logs in:

  <h1>The Example Game</h1>
  <section id="login">
   <h2>Login</h2>
   <form>
    ...
    <!-- calls login() once the user's credentials have been checked -->
   </form>
   <script>
    function login() {
      // switch screens
      document.getElementById('login').hidden = true;
      document.getElementById('game').hidden = false;
    }
   </script>
  </section>
  <section id="game" hidden>
   ...
  </section>

The hidden attribute must not be used to hide content that could legitimately be shown in another presentation. For example, it is incorrect to use hidden to hide panels in a tabbed dialog, because the tabbed interface is merely a kind of overflow presentation — one could equally well just show all the form controls in one big page with a scrollbar. It is similarly incorrect to use this attribute to hide content just from one presentation — if something is marked hidden, it is hidden from all presentations, including, for instance, screen readers.

Elements that are not themselves hidden must not hyperlink to elements that are hidden. The for attributes of label and output elements that are not themselves hidden must similarly not refer to elements that are hidden. In both cases, such references would cause user confusion.

Elements and scripts may, however, refer to elements that are hidden in other contexts.

For example, it would be incorrect to use the href attribute to link to a section marked with the hidden attribute. If the content is not applicable or relevant, then there is no reason to link to it.

It would be fine, however, to use the ARIA hidden. While hiding the descriptions implies that they are not useful alone, they could be written in such a way that they are useful in the specific context of being referenced from the elements that they describe.

Similarly, a canvas element with the hidden attribute could be used by a scripted graphics engine as an off-screen buffer, and a form control could refer to a hidden form element using its form attribute.

Elements in a section hidden by the hidden attribute are still active, e.g. scripts and form controls in such sections still execute and submit respectively. Only their presentation to the user changes.

HTMLElement/hidden

Support in all current engines.

Firefox4+Safari5.1+Chrome6+
Opera11.6+Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12+

The hidden getter steps are:

  1. If the hidden attribute is in the Hidden Until Found state, then return "until-found".

  2. If the hidden attribute is set, then return true.

  3. Return false.

The hidden setter steps are:

  1. If the given value is a string that is an ASCII case-insensitive match for "until-found", then set the hidden attribute to "until-found".

  2. Otherwise, if the given value is false, then remove the hidden attribute.

  3. Otherwise, if the given value is the empty string, then remove the hidden attribute.

  4. Otherwise, if the given value is null, then remove the hidden attribute.

  5. Otherwise, if the given value is 0, then remove the hidden attribute.

  6. Otherwise, if the given value is NaN, then remove the hidden attribute.

  7. Otherwise, set the hidden attribute to the empty string.

The ancestor hidden-until-found revealing algorithm is to run the following steps on currentNode:

  1. While currentNode has a parent node within the flat tree:

    1. If currentNode has the hidden attribute in the Hidden Until Found state, then:

      1. Fire an event named beforematch at currentNode with the

        Remove the hidden attribute from currentNode.

    2. Set currentNode to the parent node of currentNode within the flat tree.

6.2 Page visibility

A traversable navigable's system visibility state, including its initial value upon creation, is determined by the user agent. It represents, for example, whether the browser window is minimized, a browser tab is currently in the background, or a system element such as a task switcher obscures the page.

When a user agent determines that the system visibility state for traversable navigable traversable has changed to newState, it must run the following steps:

  1. Let navigables be the inclusive descendant navigables of traversable's active document.

  2. For each navigable of navigables in what order?:

    1. Let document be navigable's active document.

    2. Queue a global task on the user interaction task source given document's relevant global object to update the visibility state of document with newState.

A Document has a visibility state, which is either "hidden" or "visible", initially set to "hidden".

Document/visibilityState

Support in all current engines.

Firefox18+Safari7+Chrome33+
Opera20+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android20+

The visibilityState getter steps are to return this's visibility state.

Document/hidden

Support in all current engines.

Firefox18+Safari7+Chrome33+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android12.1+

The hidden getter steps are to return true if this's visibility state is "hidden", otherwise false.

To update the visibility state of Document document to visibilityState:

  1. If document's visibility state equals visibilityState, then return.

  2. Set document's visibility state to visibilityState.

  3. Queue a new VisibilityStateEntry whose visibility state is visibilityState and whose timestamp is the current high resolution time given document's relevant global object.

  4. Run the screen orientation change steps with document. [SCREENORIENTATION]

  5. Run the view transition page visibility change steps with document.

  6. Run any page visibility change steps which may be defined in other specifications, with visibility state and document.

    It would be better if specification authors sent a pull request to add calls from here into their specifications directly, instead of using the page visibility change steps hook, to ensure well-defined cross-specification call order. As of the time of this writing the following specifications are known to have page visibility change steps, which will be run in an unspecified order: Device Posture API and Web NFC. [DEVICEPOSTURE] [WEBNFC]

  7. Fire an event named visibilitychange at document, with its

    6.2.1 The VisibilityStateEntry interface

    VisibilityStateEntry

    Support in one engine only.

    FirefoxNoSafariNoChrome115+
    Opera?Edge115+
    Edge (Legacy)?Internet ExplorerNo
    Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

    The VisibilityStateEntry interface exposes visibility changes to the document, from the moment the document becomes active.

    For example, this allows JavaScript code in the page to examine correlation between visibility changes and paint timing:
    function wasHiddenBeforeFirstContentfulPaint() {
        const fcpEntry = performance.getEntriesByName("first-contentful-paint")[0];
        const visibilityStateEntries = performance.getEntriesByType("visibility-state");
        return visibilityStateEntries.some(e =>
                                                e.startTime < fcpEntry.startTime &&
                                                e.name === "hidden");
    }

    Since hiding a page can cause throttling of rendering and other user-agent operations, it is common to use visibility changes as an indication that such throttling has occurred. However, other things could also cause throttling in different browsers, such as long periods of inactivity.

    [Exposed=(Window)]
    interface VisibilityStateEntry : PerformanceEntry {
      readonly attribute DOMString name;                 // shadows inherited name
      readonly attribute DOMString entryType;            // shadows inherited entryType
      readonly attribute DOMHighResTimeStamp startTime;  // shadows inherited startTime
      readonly attribute unsigned long duration;         // shadows inherited duration
    };

    The VisibilityStateEntry has an associated DOMHighResTimeStamp timestamp.

    The VisibilityStateEntry has an associated "visible" or "hidden" visibility state.

    The name getter steps are to return this's visibility state.

    The entryType getter steps are to return "visibility-state".

    The startTime getter steps are to return this's timestamp.

    The duration getter steps are to return zero.

    6.3 Inert subtrees

    See also inert for an explanation of the attribute of the same name.

    A node (in particular elements and text nodes) can be inert. When a node is inert:

    • Hit-testing must act as if the 'pointer-events' CSS property were set to 'none'.

    • Text selection functionality must act as if the 'user-select' CSS property were set to 'none'.

    • If it is editable, the node behaves as if it were non-editable.

    • The user agent should ignore the node for the purposes of find-in-page.

    Inert nodes generally cannot be focused, and user agents do not expose the inert nodes to accessibility APIs or assistive technologies. Inert nodes that are commands will become inoperable to users, in the manner described above.

    User agents may allow the user to override the restrictions on find-in-page and text selection, however.

    By default, a node is not inert.

    A Document document is blocked by a modal dialog subject if subject is the topmost dialog element in document's top layer. While document is so blocked, every node that is connected to document, with the exception of the subject element and its flat tree descendants, must become inert.

    subject can additionally become inert via the inert attribute, but only if specified on subject itself (i.e., subject escapes inertness of ancestors); subject's flat tree descendants can become inert in a similar fashion.

    The dialog element's showModal() method causes this mechanism to trigger, by adding the dialog element to its node document's top layer.

    6.3.2 The inert attribute

    Global_attributes/inert

    Support in all current engines.

    Firefox112+Safari15.5+Chrome102+
    Opera?Edge102+
    Edge (Legacy)?Internet ExplorerNo
    Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

    The inert attribute is a boolean attribute that indicates, by its presence, that the element and all its flat tree descendants which don't otherwise escape inertness (such as modal dialogs) are to be made inert by the user agent.

    An inert subtree should not contain any content or controls which are critical to understanding or using aspects of the page which are not in the inert state. Content in an inert subtree will not be perceivable by all users, or interactive. Authors should not specify elements as inert unless the content they represent are also visually obscured in some way. In most cases, authors should not specify the inert attribute on individual form controls. In these instances, the disabled attribute is probably more appropriate.

    The following example shows how to mark partially loaded content, visually obscured by a "loading" message, as inert.

    <section aria-labelledby=s1>
      <h3 id=s1>Population by City</h3>
      <div class=container>
        <div class=loading><p>Loading...</p></div>
        <div inert>
          <form>
            <fieldset>
              <legend>Date range</legend>
              <div>
                <label for=start>Start</label>
                <input type=date id=start>
              </div>
              <div>
                <label for=end>End</label>
                <input type=date id=end>
              </div>
              <div>
                <button>Apply</button>
              </div>
            </fieldset>
          </form>
          <table>
            <caption>From 20-- to 20--</caption>
            <thead>
              <tr>
                <th>City</th>
                <th>State</th>
                <th>20-- Population</th>
                <th>20-- Population</th>
                <th>Percentage change</th>
              </tr>
            </thead>
            <tbody>
              <!-- ... -->
            </tbody>
          </table>
        </div>
      </div>
    </section>
    Screenshot of Population by City content with an overlaid loading message which visually obscures the form controls and data table which have not fully rendered, and thus are in the inert state.

    The "loading" overlay obscures the inert content, making it visually apparent that the inert content is not presently accessible. Notice that the heading and "loading" text are not descendants of the element with the inert attribute. This will ensure this text is accessible to all users, while the inert content cannot be interacted with by anyone.

    By default, there is no persistent visual indication of an element or its subtree being inert. Appropriate visual styles for such content is often context-dependent. For instance, an inert off-screen navigation panel would not require a default style, as its off-screen position visually obscures the content. Similarly, a modal dialog element's backdrop will serve as the means to visually obscure the inert content of the web page, rather than styling the inert content specifically.

    However, for many other situations authors are strongly encouraged to clearly mark what parts of their document are active and which are inert, to avoid user confusion. In particular, it is worth remembering that not all users can see all parts of a page at once; for example, users of screen readers, users on small devices or with magnifiers, and even users using particularly small windows might not be able to see the active part of a page and might get frustrated if inert sections are not obviously inert.

    HTMLElement/inert

    Support in all current engines.

    Firefox112+Safari15.5+Chrome102+
    Opera?Edge102+
    Edge (Legacy)?Internet ExplorerNo
    Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

    The inert IDL attribute must reflect the content attribute of the same name.

    6.4 Tracking user activation

    To prevent abuse of certain APIs that could be annoying to users (e.g., opening popups or vibrating phones), user agents allow these APIs only when the user is actively interacting with the web page or has interacted with the page at least once. This "active interaction" state is maintained through the mechanisms defined in this section.

    6.4.1 Data model

    For the purpose of tracking user activation, each Window W has two relevant values: