1. 6.12 The popover attribute
      1. 6.12.1 The popover target attributes
      2. 6.12.2 Popover light dismiss
    2. 6.13 The command and commandfor attributes

6.12 The popover attribute

Global_attributes/popover

Support in all current engines.

Firefox🔰 114+Safaripreview+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

All HTML elements may have the popover content attribute set. When specified, the element won't be rendered until it becomes shown, at which point it will be rendered on top of other page content.

The popover attribute is a global attribute that allows authors flexibility to ensure popover functionality can be applied to elements with the most relevant semantics.

The following demonstrates how one might create a popover sub-navigation list of links, within the global navigation for a website.

<ul>
  <li>
    <a href=...>All Products</a>
    <button popovertarget=sub-nav>
     <img src=down-arrow.png alt="Product pages">
    </button>
    <ul popover id=sub-nav>
     <li><a href=...>Shirts</a>
     <li><a href=...>Shoes</a>
     <li><a href=...>Hats etc.</a>
    </ul>
  </li>
  <!-- other list items and links here -->
</ul>

When using popover on elements without accessibility semantics, for instance the div element, authors should use the appropriate ARIA attributes to ensure the popover is accessible.

The following shows the baseline markup to create a custom menu popover, where the first menuitem will receive keyboard focus when the popover is invoked due to the use of the autofocus attribute. Navigating the menuitems with arrow keys and activation behaviors would still need author scripting. Additional requirements for building custom menus widgets are defined in the WAI-ARIA specification.

<button popovertarget=m>Actions</button>
<div role=menu id=m popover>
  <button role=menuitem tabindex=-1 autofocus>Edit</button>
  <button role=menuitem tabindex=-1>Hide</button>
  <button role=menuitem tabindex=-1>Delete</button>
</div>

A popover can be useful for rendering a status message, confirming the action performed by the user. The following demonstrates how one could reveal a popover in an output element.

<button id=submit>Submit</button>
<p><output><span popover=manual></span></output></p>

<script>
 const sBtn = document.getElementById("submit");
 const outSpan = document.querySelector("output [popover=manual]");
 let successMessage;
 let errorMessage;

 /* define logic for determining success of action
  and determining the appropriate success or error
  messages to use */

 sBtn.addEventListener("click", ()=> {
  if ( success ) {
   outSpan.textContent = successMessage;
  }
  else {
   outSpan.textContent = errorMessage;
  }
  outSpan.showPopover();

  setTimeout(function () {
   outSpan.hidePopover();
  }, 10000);
 });
</script>

Inserting a popover element into an output element will generally cause screen readers to announce the content when it becomes visible. Depending on the complexity or frequency of the content, this could be either useful or annoying to users of these assistive technologies. Keep this in mind when using the output element or other ARIA live regions to ensure the best user experience.

The popover attribute is an enumerated attribute with the following keywords and states:

Keyword State Brief description
auto Auto Closes other popovers when opened; has light dismiss and responds to close requests.
manual Manual Does not close other popovers; does not light dismiss or respond to close requests.
hintHintCloses other hint popovers when opened, but not other auto popovers; has light dismiss and responds to close requests.

The popover attribute's state is not intended to be queried directly by specification algorithms. Instead, it is exposed indirectly through an element's popover state, which is influenced by the popover attribute's state, among other things.

The attribute's missing value default is the No Popover state, its invalid value default is the Manual state, and its empty value default is the Auto state.

HTMLElement/popover

Support in all current engines.

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

The popover IDL attribute must reflect the popover attribute, limited to only known values.

Every HTML element has a popover state, initially No Popover, with these potential values:

The value of an element element's popover state is determined by these steps:

  1. If element is a menulist element, then return Auto.

  2. Otherwise, return the state of element's popover attribute.

    This returns No Popover if the element has no popover attribute, because of this attribute's missing value default.

Every HTML element has a popover visibility state, initially hidden, with these potential values:

Every Document has a popover pointerdown target, which is an HTML element or null, initially null.

Every HTML element has a popover trigger, which is an HTML element or null, initially set to null.

Every HTML element has a popover hiding, which is a boolean, initially set to false.

Every HTML element has a popover shown via interest, which is a boolean, initially false.

The popover shown via interest boolean is true when the popover was shown by gaining interest. Only such popovers are hidden when interest is lost.

Every HTML element popover toggle task tracker, which is a toggle task tracker or null, initially null.

Every HTML element has a popover close watcher, which is a close watcher or null, initially null.

Every HTML element has an opened in popover mode, which is "auto", "hint", or null, initially null.

Every Document has a hiding popover nesting count, which is a number, initially 0.

Every Document has a showing popover, which is a boolean, initially false.

Every Document has a hint stack parent, which is an HTML element or null, initially null.

The hint stack parent tracks which item in the showing auto popover list is the 'parent' of the first item in the showing hint popover list, or null if the first item in showing hint popover list is not 'child' to an item in the showing auto popover list.

Therefore, when the hint stack parent is not null, it will have an opened in popover mode of "auto".

The following attribute change steps, given element, localName, oldValue, value, and namespace, are used for all HTML elements:

  1. If namespace is not null, then return.

  2. If localName is not popover, then return.

  3. TODO(domfarolino): Should this step apply to menulist elements? Do we respect the popover attribute and its value mutations on that element?

    If element's popover visibility state is in the showing state and oldValue and value are in different states, then run the hide popover algorithm given element, true, true, false, and null.

element.showPopover()
Shows the popover element by adding it to the top layer. If element's popover state is Auto, then this will also close all other Auto popovers unless they are an ancestor of element according to the topmost popover ancestor algorithm.
element.hidePopover()
Hides the popover element by removing it from the top layer and applying display: none to it.
element.togglePopover()
If the popover element is not showing, then this method shows it. Otherwise, this method hides it. This method returns true if the popover is open after calling it, otherwise false.

HTMLElement/showPopover

Support in all current engines.

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

The showPopover(options) method steps are:

  1. Let source be options["source"] if it exists; otherwise, null.

  2. Run show popover given this, true, and source.

To show popover, given an HTML element element, a boolean throwExceptions, and an HTML element or null source:

  1. Let document be element's node document.

  2. If document's showing popover is true, or document's hiding popover nesting count is not 0:

    1. If throwExceptions is true, then throw a "InvalidStateError" DOMException.

    2. Return.

    This prevents showing a popover during the show or hide of another popover.

  3. Let validityResult be the result of running check popover validity given element, false, and null. If this throws an exception, catch it, and set validityResult to that exception.

  4. If validityResult is not true:

    1. If throwExceptions is true and validityResult is a DOMException, then throw validityResult.

    2. Return.

  5. Assert: element's popover trigger is null.

  6. Assert: element is not in document's top layer.

  7. Set document's showing popover to true.

  8. Let cleanupShowingSteps be the following steps:

    1. Set document's showing popover to false.

  9. If the result of firing an event named beforetoggle, using ToggleEvent, with the cancelable attribute initialized to true, the oldState attribute initialized to "closed", the newState attribute initialized to "open", and the source attribute initialized to source at element is false, then run cleanupShowingSteps and return.

  10. Set validityResult to the result of running check popover validity given element, false, and document. If this throws an exception, catch it, and set validityResult to that exception.

    Check popover validity is called again because firing the beforetoggle event could have disconnected this element or changed its popover attribute.

  11. If validityResult is not true:

    1. Run cleanupShowingSteps.

    2. If throwExceptions is true and validityResult is a DOMException, then throw validityResult.

    3. Return.

  12. Let shouldRestoreFocus be false.

  13. Let originalType be element's current popover state.

  14. Let effectiveType be originalType.

  15. If originalType is Auto or Hint:

    1. Let ancestor be the result of running the topmost popover ancestor algorithm given element, source, and true.

    2. If all of the following are true:

      then set effectiveType to the Hint state.

      Hint popovers are lower priority than Auto popovers, so an Auto popover cannot have a Hint popover as a 'parent'. To resolve this case, the effectiveType is 'downgraded' to Hint.

    3. Run hide popover stack until given document, ancestor, Hint, shouldRestoreFocus, and true.

    4. If effectiveType is the Auto state, then run hide popover stack until given document, ancestor, Auto, shouldRestoreFocus, and true.

    5. If originalType is not equal to the value of element's popover state, then:

      1. Run cleanupShowingSteps.

      2. If throwExceptions is true, then throw an "InvalidStateError" DOMException.

      3. Return.

    6. Set validityResult to the result of running check popover validity given element, false, and document. If this throws an exception, catch it, and set validityResult to that exception.

      Check popover validity is called again because running hide popover stack until above could have fired the beforetoggle event, and an event handler could have disconnected this element or changed its popover attribute.

    7. If validityResult is not true:

      1. Run cleanupShowingSteps.

      2. If throwExceptions is true and validityResult is a DOMException, then throw validityResult.

      3. Return.

    8. If the result of running topmost auto or hint popover on document is null, then set shouldRestoreFocus to true.

      This ensures that focus is returned to the previously-focused element only for the first popover in a stack.

    9. If effectiveType is Auto:

      1. Assert: document's showing auto popover list does not contain element.

      2. Set element's opened in popover mode to "auto".

      Otherwise:

      1. Assert: effectiveType is Hint.

      2. Assert: document's showing hint popover list does not contain element.

      3. Set element's opened in popover mode to "hint".

    10. Set element's popover close watcher to the result of establishing a close watcher given element's relevant global object, with:

  16. Set element's previously focused element to null.

  17. Let originallyFocusedElement be document's focused area of the document's DOM anchor.

  18. Add an element to the top layer given element.

  19. If effectiveType is Hint and ancestor's opened in popover mode is "auto", then set document's hint stack parent to ancestor.

  20. Set element's popover visibility state to showing.

  21. Set element's popover trigger to source.

  22. Set element's popover shown via interest to false.

  23. Set element's implicit anchor element to source.

  24. Run the popover focusing steps given element.

  25. If shouldRestoreFocus is true and element's popover state is not No Popover, then set element's previously focused element to originallyFocusedElement.

  26. Run cleanupShowingSteps.

  27. Queue a popover toggle event task given element, "closed", "open", and source.

To queue a popover toggle event task given an element element, a string oldState, a string newState, and an Element or null source:

  1. If element's popover toggle task tracker is not null:

    1. Set oldState to element's popover toggle task tracker's old state.

    2. Remove element's popover toggle task tracker's task from its task queue.

    3. Set element's popover toggle task tracker to null.

  2. Queue an element task given the DOM manipulation task source and element to run the following steps:

    1. Fire an event named toggle at element, using ToggleEvent, with the oldState attribute initialized to oldState, the newState attribute initialized to newState, and the source attribute initialized to source.

    2. Set element's popover toggle task tracker to null.

  3. Set element's popover toggle task tracker to a struct with task set to the just-queued task and old state set to oldState.

HTMLElement/hidePopover

Support in all current engines.

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

The hidePopover() method steps are:

  1. Run the hide popover algorithm given this, true, true, true, and null.

To hide a popover given an HTML element element, a boolean focusPreviousElement, a boolean fireEvents, a boolean throwExceptions, and an HTML element or null source:

  1. Let validityResult be the result of running check popover validity given element, true, and null. If this throws an exception, catch it, and let validityResult be that exception.

  2. If validityResult is not true:

    1. If throwExceptions is true and validityResult is a DOMException, then throw validityResult.

    2. Return.

  3. Let document be element's node document.

  4. Let nestedHide be element's popover hiding.

  5. Set element's popover hiding to true.

  6. If nestedHide is true, then set fireEvents to false.

  7. Increment document's hiding popover nesting count.

  8. Let cleanupSteps be the following steps:

    1. If nestedHide is false, then set element's popover hiding to false.

    2. Decrement document's hiding popover nesting count.

  9. Let autoPopoverListContainsElement be true if document's showing auto popover list contains element; otherwise false.

  10. Let hintPopoverListContainsElement be true if document's showing hint popover list contains element; otherwise false.

  11. If element's opened in popover mode is "auto" or "hint":

    1. If hintPopoverListContainsElement is true, then run hide popover stack until given document, element, Hint, focusPreviousElement, and fireEvents.

    2. If element is document's hint stack parent, then run hide popover stack until given document, null, Hint, focusPreviousElement, and fireEvents.

      If the document's hint stack parent is being hidden, then all hint popovers are hidden.

    3. If autoPopoverListContainsElement is true, then run hide popover stack until given document, element, Auto, focusPreviousElement, and fireEvents.

    4. Set validityResult to the result of running check popover validity given element, true, and document. If this throws an exception, catch it, and set validityResult to that exception.

      Check popover validity is called again because running hide popover stack until could have disconnected element or changed its popover attribute.

    5. If validityResult is not true:

      1. Run cleanupSteps.

      2. If throwExceptions is true and validityResult is a DOMException, then throw validityResult.

      3. Return.

  12. If fireEvents is true:

    1. Fire an event named beforetoggle, using ToggleEvent, with the oldState attribute initialized to "open", the newState attribute initialized to "closed", and the source attribute set to source at element.

    2. Set validityResult to the result of running check popover validity given element, true, and document. If this throws an exception, catch it, and set validityResult to that exception.

      Check popover validity is called again because firing the beforetoggle event could have disconnected element or changed its popover attribute.

    3. If validityResult is not true:

      1. Run cleanupSteps.

      2. If throwExceptions is true and validityResult is a DOMException, then throw validityResult.

      3. Return.

    4. If element's active interest source is not null, and the interest ready check for element's active interest source and element returns true, then lose interest in element's active interest source given element and false.

      Hiding the target of an active interest invoker causes that invoker to lose interest. The lose interest algorithm is told not to hide element, since it is already being hidden.

    5. Request an element to be removed from the top layer given element.

    6. Set element's implicit anchor element to null.

  13. Otherwise, remove an element from the top layer immediately given element.

  14. If element's active interest source is not null, and either fireEvents is false or the interest ready check for element's active interest source and element returns false, then reset interest state for element's active interest source.

    This step ensures that an interest invoker does not keep a hidden popover as its active interest target.

  15. Set element's popover trigger to null.

  16. Set element's popover shown via interest to false.

  17. Set element's opened in popover mode to null.

  18. Set element's popover visibility state to hidden.

  19. If element is document's hint stack parent, or document's showing hint popover list is empty, then set document's hint stack parent to null.

  20. If fireEvents is true, then queue a popover toggle event task given element, "open", "closed", and source.

  21. Let previouslyFocusedElement be element's previously focused element.

  22. If previouslyFocusedElement is not null:

    1. Set element's previously focused element to null.

    2. If focusPreviousElement is true and document's focused area of the document's DOM anchor is a shadow-including inclusive descendant of element, then:

      1. If previouslyFocusedElement's interest target element is element, then set previouslyFocusedElement's suppress next focus interest to true.

      2. Run the focusing steps for previouslyFocusedElement; the viewport should not be scrolled by doing this step.

  23. If element's popover close watcher is not null:

    1. Destroy element's popover close watcher.

    2. Set element's popover close watcher to null.

  24. Run cleanupSteps.

HTMLElement/togglePopover

Support in all current engines.

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

The togglePopover(options) method steps are:

  1. Let force be null.

  2. If options is a boolean, set force to options.

  3. Otherwise, if options["force"] exists, set force to options["force"].

  4. Let source be options["source"] if it exists; otherwise, null.

  5. If this's popover visibility state is showing, and force is null or false, then run the hide popover algorithm given this, true, true, true, and null.

  6. Otherwise, if force is null or true, then run show popover given this, true, and source.

  7. Otherwise:

    1. Let expectedToBeShowing be true if this's popover visibility state is showing; otherwise false.

    2. Run check popover validity given this, expectedToBeShowing, and null.

  8. Return true if this's popover visibility state is showing; otherwise false.

To hide popovers until, given a Document document, an HTML element or null endpoint, a boolean focusPreviousElement, and a boolean fireEvents:

  1. Let endpointIsHint be true if document's showing hint popover list contains endpoint; otherwise false.

  2. Run hide popover stack until given document, endpoint, Hint, focusPreviousElement, and fireEvents.

  3. Let autoEndpoint be endpoint.

  4. If endpointIsHint is true, then set autoEndpoint to document's hint stack parent.

    This means, if endpoint is a hint popover, auto popovers are closed, except those that are parent to that hint popover.

  5. Run hide popover stack until given document, autoEndpoint, Auto, focusPreviousElement, and fireEvents.

To hide popover stack until, given a Document document, an HTML element or null endpoint, an Auto or Hint stackType, a boolean focusPreviousElement, and a boolean fireEvents:

  1. Let popoverList be document's showing auto popover list if stackType is Auto; otherwise document's showing hint popover list.

  2. Let lastHideIndex be 0 if popoverList does not contain endpoint; otherwise the index of endpoint in popoverList plus 1.

  3. Let toHide be a slice of popoverList from lastHideIndex, in reverse order.

  4. Let toRemain be a slice of popoverList from 0 to lastHideIndex.

  5. For each popover of toHide: run the hide popover algorithm given popover, focusPreviousElement, fireEvents, false, and null.

  6. Let newPopoverList be document's showing auto popover list if stackType is Auto; otherwise document's showing hint popover list.

  7. Let toCheck be newPopoverList in reverse order.

  8. For each popover of toCheck:

    1. If toRemain contains popover, then continue.

    2. Run the hide popover algorithm given popover, focusPreviousElement, false, false, and null.

      This happens if popovers are shown whilst hiding popovers. For example, in beforetoggle events. This is usually a developer error, so user agents are encouraged to show a warning. In this additional hiding phase, fireEvents is ignored, and false is used instead.

The hide popover stack until algorithm is used in several cases to hide all popovers that don't stay open when something happens. For example, during light-dismiss of a popover, this algorithm ensures that we close only the popovers that aren't related to the node clicked by the user.

To find the topmost popover ancestor, given a Node newPopoverOrTopLayerElement, an HTML element or null source, and a boolean isPopover, perform the following steps. They return an HTML element or null.

The topmost popover ancestor algorithm will return the topmost ancestor popover for the provided popover or top layer element. Popovers can be related to each other in several ways, creating a tree of popovers. There are two paths through which one popover (call it the "child" popover) can have a topmost ancestor popover (call it the "parent" popover):

  1. The popovers are nested within each other in the node tree. In this case, the descendant popover is the "child" and its topmost ancestor popover is the "parent".

  2. An element is the 'source' of the popover (e.g., a button with command in the Show Popover state). In this case, the popover is the "child", and the popover subtree the trigger element is in is the "parent". The trigger element has to be in a popover and reference an open popover.

In each of the relationships formed above, the parent popover has to be strictly earlier in the showing auto popover list or showing hint popover list than the child popover, or it does not form a valid ancestral relationship. This eliminates non-showing popovers and self-pointers (e.g., a popover containing an invoking element that points back to the containing popover), and it allows for the construction of a well-formed tree from the (possibly cyclic) graph of connections. Only Auto and Hint popovers are considered.

If the provided element is a top layer element such as a dialog which is not showing as a popover, then topmost popover ancestor will only look in the node tree to find the first popover.

  1. If isPopover is true:

    1. Assert: newPopoverOrTopLayerElement is an HTML element.

    2. Assert: newPopoverOrTopLayerElement's popover state is not No Popover State or the Manual.

    3. Assert: newPopoverOrTopLayerElement's popover visibility state is not in the popover showing state.

  2. Otherwise:

    1. Assert: source is null.

  3. Let document be newPopoverOrTopLayerElement's node document.

  4. Let combinedPopovers be document's showing auto popover list extended with document's showing hint popover list.

  5. Let popoverAncestorIndex be the index of the last item in combinedPopovers of which newPopoverOrTopLayerElement is a flat tree descendant, otherwise -1.

  6. Let sourceAncestorIndex be -1.

  7. If source is not null, then set sourceAncestorIndex to the index of the last item in combinedPopovers of which source is a flat tree descendant, otherwise -1.

  8. Let ancestorIndex be the maximum of popoverAncestorIndex and sourceAncestorIndex.

  9. If ancestorIndex is -1, then return null.

  10. Return combinedPopovers[ancestorIndex].

To find the nearest inclusive open popover given a Node node, perform the following steps. They return an HTML element or null.

  1. Let currentNode be node.

  2. While currentNode is not null:

    1. If currentNode's opened in popover mode is "auto" or "hint", and currentNode's popover visibility state is showing, then return currentNode.

    2. Set currentNode to currentNode's parent in the flat tree.

  3. Return null.

To find the topmost auto or hint popover given a Document document, perform the following steps. They return an HTML element or null.

  1. If document's showing hint popover list is not empty, then return document's showing hint popover list's last element.

  2. If document's showing auto popover list is not empty, then return document's showing auto popover list's last element.

  3. Return null.

To perform the popover focusing steps for an HTML element subject:

  1. If the allow focus steps given subject's node document return false, then return.

  2. If subject is a dialog element, then run the dialog focusing steps given subject and return.

  3. If subject has the autofocus attribute, then let control be subject.

  4. Otherwise, let control be the autofocus delegate for subject given "other".

  5. If control is null, then return.

  6. Run the focusing steps given control.

  7. Let topDocument be control's node navigable's top-level traversable's active document.

  8. If control's node document's origin is not the same as the origin of topDocument, then return.

  9. Empty topDocument's autofocus candidates.

  10. Set topDocument's autofocus processed flag to true.

To check popover validity for an HTML element element given a boolean expectedToBeShowing and a Document or null expectedDocument, perform the following steps. They throw an exception or return a boolean.

  1. If element's popover state is No Popover, then throw a "NotSupportedError" DOMException.

  2. If any of the following are true:

    then return false.

  3. If any of the following are true:

    then throw an "InvalidStateError" DOMException.

  4. Return true.

To get the showing auto popover list for a Document document:

  1. Let popovers be « ».

  2. For each Element element of document's top layer:

    1. If all of the following are true:

      then append element to popovers.

  3. Return popovers.

To get the showing hint popover list for a Document document:

  1. Let popovers be « ».

  2. For each Element element of document's top layer:

    1. If all of the following are true:

      then append element to popovers.

  3. Return popovers.

6.12.1 The popover target attributes

TODO(domfarolino): Should we expand these attributes to menuitem elements? And should we expand their targeting behavior to include targeting menulist elements, which are popovers by default but don't use the explicit popover attribute? See the various TODOs below.

Buttons may have the following content attributes:

TODO(domfarolino): If we decide to expand the popovertarget attribute targeting behavior to include targeting menulist elements, then we'll have to loosen this paragraph.

If specified, the popovertarget attribute value must be the ID of an element with a popover attribute in the same tree as the button with the popovertarget attribute.

The popovertargetaction attribute is an enumerated attribute with the following keywords and states:

Keyword State Brief description
toggle Toggle Shows or hides the targeted popover element.
show Show Shows the targeted popover element.
hide Hide Hides the targeted popover element.

The attribute's missing value default and invalid value default are both the Toggle state.

Whenever possible ensure the popover element is placed immediately after its triggering element in the DOM. Doing so will help ensure that the popover is exposed in a logical programmatic reading order for users of assistive technology, such as screen readers.

The following shows how the popovertarget attribute in combination with the popovertargetaction attribute can be used to show and close a popover:

<button popovertarget="foo" popovertargetaction="show">
  Show a popover
</button>

<article popover="auto" id="foo">
  This is a popover article!
  <button popovertarget="foo" popovertargetaction="hide">Close</button>
</article>

If a popovertargetaction attribute is not specified, the default action will be to toggle the associated popover. The following shows how only specifying the popovertarget attribute on its invoking button can toggle a manual popover between its opened and closed states. A manual popover will not respond to light dismiss or close requests:

<input type="button" popovertarget="foo" value="Toggle the popover">

<div popover=manual id="foo">
  This is a popover!
</div>
DOM interface:

HTMLButtonElement/popoverTargetElement

Support in all current engines.

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLInputElement/popoverTargetElement

Support in all current engines.

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
interface mixin PopoverTargetAttributes {
  [CEReactions, Reflect="popovertarget"] attribute Element? popoverTargetElement;
  [CEReactions] attribute DOMString popoverTargetAction;
};

HTMLButtonElement/popoverTargetAction

Support in all current engines.

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLInputElement/popoverTargetAction

Support in all current engines.

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

The popoverTargetAction IDL attribute must reflect the popovertargetaction attribute, limited to only known values.

To run the popover target attribute activation behavior given a Node node and a Node eventTarget:

  1. Let popover be node's popover target element.

  2. If popover is null, then return.

  3. If eventTarget is a shadow-including inclusive descendant of popover and popover is a shadow-including descendant of node, then return.

  4. If node's popovertargetaction attribute is in the show state and popover's popover visibility state is showing:

    1. Set popover's popover trigger to node.

    2. Set popover's popover shown via interest to false.

    3. Return.

  5. If node's popovertargetaction attribute is in the hide state and popover's popover visibility state is hidden, then return.

  6. If popover's popover visibility state is showing, then run the hide popover algorithm given popover, true, true, false, and node.

  7. Otherwise:

    1. Let validity be the result of running check popover validity given popover, false, and null. If this throws an exception, catch it, and let validity be false.

    2. If validity is true, then run show popover given popover, false, and node.

To get the popover target element given a Node node, perform the following steps. They return an HTML element or null.

  1. If node is not a button, then return null.

  2. If node is disabled, then return null.

  3. If node has a form owner and node is a submit button, then return null.

  4. Let popoverElement be the result of running node's get the popovertarget-associated element.

  5. If popoverElement is null, then return null.

  6. TODO(domfarolino): See the above TODO: if we decide to expand the popovertarget's targeting ability to target menulist elements, then we'll need to loosen this condition below, to include menulist elements which are popovers by default, even without the explicit popover attribute.

    If popoverElement's popover attribute is in the No Popover state, then return null.

  7. Return popoverElement.

6.12.2 Popover light dismiss

"Light dismiss" means that clicking outside of a popover whose popover state is Auto or Hint will close the popover. This is in addition to how such popovers respond to close requests.

To light dismiss open popovers, given a PointerEvent event:

  1. Assert: event's isTrusted attribute is true.

  2. Let target be event's target.

  3. Let document be target's node document.

  4. If the result of running topmost auto or hint popover given document is null, then return.

  5. If event's type is "pointerdown": set document's popover pointerdown target to the result of running topmost clicked popover given target.

  6. If event's type is "pointerup":

    1. Let ancestor be the result of running topmost clicked popover given target.

    2. Let sameTarget be true if ancestor is document's popover pointerdown target.

    3. Set document's popover pointerdown target to null.

    4. If sameTarget is false, then return.

    5. Run hide popovers until given document, ancestor, false, and true.

To find the topmost clicked popover, given a Node node:

  1. Let clickedPopover be the result of running nearest inclusive open popover given node.

  2. Let targetPopover be the result of running nearest inclusive target popover given node.

  3. If the result of getting the popover stack position given clickedPopover is greater than the result of getting the popover stack position given targetPopover, then return clickedPopover.

  4. Return targetPopover.

To get the popover stack position, given an HTML element popover:

  1. Let hintList be popover's node document's showing hint popover list.

  2. Let autoList be popover's node document's showing auto popover list.

  3. If popover is in hintList, then return the index of popover in hintList + the size of autoList + 1.

  4. If popover is in autoList, then return the index of popover in autoList + 1.

  5. Return 0.

To find the nearest inclusive target popover given a Node node:

  1. Let currentNode be node.

  2. While currentNode is not null:

    1. Let targetPopover be currentNode's target popover.

    2. If targetPopover is not null and targetPopover's popover state is Auto or the Hint, and targetPopover's popover visibility state is showing, then return targetPopover.

    3. Set currentNode to currentNode's ancestor in the flat tree.

To get the target popover given a Node node, perform the following steps. They return an HTML element or null.

  1. If node is not a button element, then return node's popover target element.

  2. If node is disabled, then return null.

  3. Let target be the result of running node's get the commandfor-associated element.

  4. If target is null, then return node's popover target element.

  5. If node has a form owner:

    1. If element is a submit button, then return null.

    2. If element's type attribute is in the Reset Button state, then return null.

    3. If element's type attribute is in the Auto state, then return null.

  6. Let command be node's command attribute.

  7. If command is not in the Toggle Popover, Hide Popover, or Show Popover states, then return null.

  8. If target's popover attribute is in the No Popover state, then return null.

  9. Return target.

6.13 The command and commandfor attributes

Buttons and menuitem elements may have the following content attributes:

If specified, the commandfor attribute value must be the ID of an element in the same tree as the button or menuitem with this attribute.

The command attribute is an enumerated attribute with the following keywords and states:

Keyword State Brief description
toggle-popover Toggle Popover Shows or hides the targeted popover element.
show-popover Show Popover Shows the targeted popover element.
hide-popover Hide Popover Hides the targeted popover element.
close Close Closes the targeted dialog element.
request-close Request Close Requests to close the targeted dialog element.
show-modal Show Modal Opens the targeted dialog element as modal.
A custom command keyword Custom Only dispatches the command event on the targeted element.

The attribute's missing value default and invalid value default are both the Unknown state.

A custom command keyword is a string that starts with "--".

An HTML element can have specific is valid command steps and command steps defined for the element's local name.

TODO(domfarolino DOMFAROLINO): Probably add shared activation behavior algorithm here?

Both button elements and menuitem elements are the only command invoker elements. As such, much of their activation behavior is shared. The parts they share in common are defined in the shared command invoker activation steps below, which take an element element and an event event:

  1. Let target be the result of running element's get the commandfor-associated element.

  2. If target is not null:

    1. Let command be element's command attribute.

    2. If the result of determining if a command is valid for a target given command and target is false, then return.

    3. Let continue be the result of firing an event named command at target, using CommandEvent, with its command attribute initialized to command, its source attribute initialized to element, and its cancelable attribute initialized to true.

      DOM standard issue #1328 tracks how to better standardize associated event data in a way which makes sense on Events. Currently an event attribute initialized to a value cannot also have a getter, and so an internal slot (or map of additional fields) is required to properly specify this.

    4. If continue is false, then return.

    5. If target is not connected, then return.

    6. If command is in the Custom state, then return.

    7. If command is in the Hide Popover state:

      1. Let validity be the result of running check popover validity given target, true, and null. If this throws an exception, catch it, and let validity be false.

      2. If validity is true, then run the hide popover algorithm given target, true, true, false, and element.

    8. Otherwise, if command is in the Toggle Popover state:

      1. Let validity be the result of running check popover validity given target, false, and null. If this throws an exception, catch it, and let validity be false.

      2. If validity is true, then run the show popover algorithm given target, false, and element.

      3. Otherwise:

        1. Let validity be the result of running check popover validity given target, true, and null. If this throws an exception, catch it, and let validity be false.

        2. If validity is true, then run the hide popover algorithm given target, true, true, false, and element.

    9. Otherwise, if command is in the Show Popover state:

      1. Let validity be the result of running check popover validity given target, false, and null. If this throws an exception, catch it, and let validity be false.

      2. If validity is true, then run the show popover algorithm given target, false, and element.

      3. Otherwise, if target's popover visibility state is showing:

        1. Set target's popover trigger to element.

        2. Set target's popover shown via interest to false.

    10. Otherwise, if this standard defines command steps for target's local name, then run the corresponding command steps given target, element, and command.

  3. Otherwise, run the popover target attribute activation behavior given element and event's target.

DOM interface:
interface mixin CommandInvokerElement {
  [CEReactions, ReflectSetter] attribute DOMString command;
  [CEReactions, Reflect="commandfor"] attribute Element? commandForElement;
};

The command getter steps are:

  1. Let command be this's command attribute.

  2. If command is in the Custom state, then return command's value.

  3. If command is in the Unknown state, then return the empty string.

  4. Return the keyword corresponding to the value of command.


The following shows how buttons can use commandfor to show and hide an element with the popover attribute when activated:

<button type=button
        commandfor="the-popover"
        command="show-popover">
 Show menu
</button>
<div popover
     id="the-popover">
 <button commandfor="the-popover"
         command="hide-popover">
  Hide menu
 </button>
</div>
    

The following shows how buttons can use commandfor with a custom command keyword on an element, demonstrating how one could use custom commands for unspecified behavior:

<button type=button
        commandfor="the-image"
        command="--rotate-landscape">
 Rotate Left
</button>
<button type=button
        commandfor="the-image"
        command="--rotate-portrait">
 Rotate Right
</button>
<img id="the-image"
     src="photo.jpg">
<script>
  const image = document.getElementById("the-image");
  image.addEventListener("command", (event) => {
   if ( event.command == "--rotate-landscape" ) {
    event.target.style.rotate = "-90deg"
   } else if ( event.command == "--rotate-portrait" ) {
    event.target.style.rotate = "0deg"
   }
  });
</script>