Edition for Web Developers — Last Updated 20 January 2025
popover
attributeSupport in all current engines.
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. |
(the empty string) | ||
manual
| manual | Does not close other popovers; does not light dismiss or respond to close requests. |
hint | hint | Closes other hint popovers when opened, but not other auto popovers; has light dismiss and responds to close requests. |
The attribute's missing value default is the no popover state, and its invalid value default is the manual state.
Support in all current engines.
The popover
IDL
attribute must reflect the popover attribute,
limited to only known values.
Every HTML element has a popover visibility state, initially , with these potential values:
hidden
showing
Every Document
has a popover pointerdown target, which is an HTML element or null, initially null.
Every HTML element has a popover invoker, which is an HTML element or null, initially set to null.
Every HTML element has a popover showing or hiding, which is a boolean, initially set to false.
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 a string or null, initially null.
The following attribute change steps, given element, localName, oldValue, value, and namespace, are used for all HTML elements:
If namespace is not null, then return.
If localName is not popover
, then
return.
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, and false.
element.showPopover()
Support in all current engines.
popover
attribute is in the auto state, 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()
Support in all current engines.
display: none
to it.element.togglePopover()
Support in all current engines.
The showPopover(options)
method steps are:
Let invoker be options["source
"] if it exists; otherwise, null.
Run show popover given this, true, and invoker.
To show popover, given an HTML element element, a boolean throwExceptions, and an HTML element or null invoker:
If the result of running check popover validity given element, false, throwExceptions, and null is false, then return.
Let document be element's node document.
Assert: element's popover invoker is null.
Let nestedShow be element's popover showing or hiding.
Let fireEvents be the boolean negation of nestedShow.
Set element's popover showing or hiding to true.
Let cleanupShowingFlag be the following steps:
If nestedShow is false, then set element's popover showing or hiding to false.
If the result of firing an event named beforetoggle
, using ToggleEvent
, with the cancelable
attribute initialized to true, the oldState
attribute initialized to "closed
", and the newState
attribute initialized to "open
" at element is false, then
run cleanupShowingFlag and return.
If the result of running check popover validity given element, false, throwExceptions, and document is false, then run cleanupShowingFlag and return.
Check popover validity is called again because firing the beforetoggle
event could have disconnected this element or
changed its popover
attribute.
Let shouldRestoreFocus be false.
Let originalType be the current state of element's popover
attribute.
Let stackToAppendTo be null.
Let autoAncestor be the result of running the topmost popover ancestor algorithm given element, document's showing auto popover list, invoker, and true.
Let hintAncestor be the result of running the topmost popover ancestor algorithm given element, document's showing hint popover list, invoker, and true.
If originalType is the auto state, then:
Run close entire popover list given document's showing hint popover list, shouldRestoreFocus, and fireEvents.
Let ancestor be the result of running the topmost popover ancestor algorithm given element, document's showing auto popover list, invoker, and true.
If ancestor is null, then set ancestor to document.
Run hide all popovers until given ancestor, shouldRestoreFocus, and fireEvents.
Set stackToAppendTo to "auto
".
If originalType is the hint state, then:
If hintAncestor is not null, then:
Run hide all popovers until given hintAncestor, shouldRestoreFocus, and fireEvents.
Set stackToAppendTo to "hint
".
Otherwise:
Run close entire popover list given document's showing hint popover list, shouldRestoreFocus, and fireEvents.
If autoAncestor is not null, then:
Run hide all popovers until given autoAncestor, shouldRestoreFocus, and fireEvents.
Set stackToAppendTo to "auto
".
Otherwise, set stackToAppendTo to "hint
".
If originalType is auto or hint, then:
Assert: stackToAppendTo is not null.
If originalType is not equal to the value of element's popover
attribute, then:
If throwExceptions is true, then throw a
"InvalidStateError
" DOMException
.
Return.
If the result of running check popover validity given element, false, throwExceptions, and document is false, then run cleanupShowingFlag and return.
Check popover validity is called again because running hide all popovers until above could have fired the
beforetoggle
event, and an event handler could have
disconnected this element or changed its popover
attribute.
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.
If stackToAppendTo is "auto
":
Assert: document's showing auto popover list does not contain element.
Set element's opened in popover mode to "auto
".
Otherwise:
Assert: stackToAppendTo is "hint
".
Assert: document's showing hint popover list does not contain element.
Set element's opened in popover mode to "hint
".
Set element's popover close watcher to the result of establishing a close watcher given element's relevant global object, with:
cancelAction being to return true.
closeAction being to hide a popover given element, true, true, and false.
getEnabledState being to return true.
Set element's previously focused element to null.
Let originallyFocusedElement be document's focused area of the document's DOM anchor.
Add an element to the top layer given element.
Set element's popover visibility state to showing.
Set element's popover invoker to invoker.
Set element's implicit anchor element to invoker.
Run the popover focusing steps given element.
If shouldRestoreFocus is true and element's popover
attribute is not in the no popover state, then set element's
previously focused element to originallyFocusedElement.
Queue a popover toggle event task given element, "closed
", and "open
".
Run cleanupShowingFlag.
To queue a popover toggle event task given an element element, a string oldState, and a string newState:
If element's popover toggle task tracker is not null, then:
Set oldState to element's popover toggle task tracker's old state.
Remove element's popover toggle task tracker's task from its task queue.
Set element's popover toggle task tracker to null.
Queue an element task given the DOM manipulation task source and element to run the following steps:
Fire an event named toggle
at element, using ToggleEvent
, with
the oldState
attribute initialized to
oldState and the newState
attribute
initialized to newState.
Set element's popover toggle task tracker to null.
Set element's popover toggle task tracker to a struct with task set to the just-queued task and old state set to oldState.
The hidePopover()
method steps are:
Run the hide popover algorithm given this, true, true, and true.
To hide a popover given an HTML element element, a boolean focusPreviousElement, a boolean fireEvents, and a boolean throwExceptions:
If the result of running check popover validity given element, true, throwExceptions, and null is false, then return.
Let document be element's node document.
Let nestedHide be element's popover showing or hiding.
Set element's popover showing or hiding to true.
If nestedHide is true, then set fireEvents to false.
Let cleanupSteps be the following steps:
If nestedHide is false, then set element's popover showing or hiding to false.
If element's popover close watcher is not null, then:
Destroy element's popover close watcher.
Set element's popover close watcher to null.
If element's popover
attribute is in the auto state or the hint state, then:
Run hide all popovers until given element, focusPreviousElement, and fireEvents.
If the result of running check popover validity given element, true, and throwExceptions is false, then run cleanupSteps and return.
Check popover validity is called again because running hide all popovers until could have disconnected
element or changed its popover
attribute.
Let autoPopoverListContainsElement be true if document's showing auto popover list's last item is element, otherwise false.
Set element's popover invoker to null.
If fireEvents is true:
Fire an event named beforetoggle
, using ToggleEvent
, with the oldState
attribute initialized to "open
" and the newState
attribute initialized to "closed
" at element.
If autoPopoverListContainsElement is true and document's showing auto popover list's last item is not element, then run hide all popovers until given element, focusPreviousElement, and false.
If the result of running check popover validity given element, true, throwExceptions, and null is false, then run cleanupSteps and return.
Check popover validity is called again because firing the beforetoggle
event could have disconnected
element or changed its popover
attribute.
Request an element to be removed from the top layer given element.
Set element's implicit anchor element to null.
Otherwise, remove an element from the top layer immediately given element.
Set element's opened in popover mode to null.
Set element's popover visibility state to .
If fireEvents is true, then queue a popover toggle event task
given element, "open
", and "closed
".
Let previouslyFocusedElement be element's previously focused element.
If previouslyFocusedElement is not null, then:
Set element's previously focused element to null.
If focusPreviousElement is true and document's focused area of the document's DOM anchor is a shadow-including inclusive descendant of element, then run the focusing steps for previouslyFocusedElement; the viewport should not be scrolled by doing this step.
Run cleanupSteps.
The togglePopover(options)
method steps are:
Let force be null.
If options is a boolean, set force to options.
Otherwise, if options["force
"] exists,
set force to options["force
"].
Let invoker be options["source
"] if it exists; otherwise, null.
If this's popover visibility state is showing, and force is null or false, then run the hide popover algorithm given this, true, true, and true.
Otherwise, if force is null or true, then run show popover given this, true, and invoker.
Otherwise:
Let expectedToBeShowing be true if this's popover visibility state is showing; otherwise false.
Run check popover validity given expectedToBeShowing, true, and null.
Return true if this's popover visibility state is showing; otherwise false.
To hide all popovers until, given an HTML element or Document
endpoint, a boolean
focusPreviousElement, and a boolean fireEvents:
If endpoint is an HTML element and endpoint is not in the popover showing state, then return.
Let document be endpoint's node document.
Assert: endpoint is a Document
or
endpoint's popover visibility state is showing.
Assert: endpoint is a Document
or
endpoint's popover
attribute is in the auto state or endpoint's popover
attribute is in the hint state.
If endpoint is a Document
:
Run close entire popover list given document's showing hint popover list, focusPreviousElement, and fireEvents.
Run close entire popover list given document's showing auto popover list, focusPreviousElement, and fireEvents.
Return.
If document's showing hint popover list contains endpoint:
Run hide popover stack until given endpoint, document's showing hint popover list, focusPreviousElement, and fireEvents.
Return.
Run close entire popover list given document's showing hint popover list, focusPreviousElement, and fireEvents.
If document's showing auto popover list does not contain endpoint, then return.
Run hide popover stack until given endpoint, document's showing auto popover list, focusPreviousElement, and fireEvents.
To hide popover stack until, given an HTML element element, a list popoverList, a boolean focusPreviousElement, and a boolean fireEvents:
Let repeatingHide be false.
Perform the following steps at least once:
Let lastToHide be null.
For each popover in popoverList:
If popover is endpoint, then break.
Set lastToHide to popover.
If lastToHide is null, then return.
While lastToHide's popover visibility state is showing:
Assert: popoverList is not empty.
Run the hide popover algorithm given the last item in popoverList, focusPreviousElement, fireEvents, and false.
Assert: repeatingHide is false or popoverList's last item is endpoint.
Set repeatingHide to true if popoverList contains endpoint and popoverList's last item is not endpoint, otherwise false.
If repeatingHide is true, then set fireEvents to false.
and keep performing them while repeatingHide is true.
The hide all popovers 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, a list popoverList, an HTML element or null invoker, and a boolean
isPopover, perform the following steps. They return an HTML element or null.
The topmost popover ancestor algorithm will return the topmost (latest in the showing auto popover list) 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):
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".
An invoking element (e.g., a button
) has a popovertarget
attribute pointing to a popover. In this case,
the popover is the "child", and the popover subtree the invoking element is in is the
"parent". The invoker 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 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 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.
If isPopover is true:
Assert: newPopoverOrTopLayerElement is an HTML element.
Assert: newPopoverOrTopLayerElement's popover
attribute is not in the no popover state or the manual state.
Assert: newPopoverOrTopLayerElement's popover visibility state is not in the popover showing state.
Otherwise:
Assert: invoker is null.
Let popoverPositions be an empty ordered map.
Let index be 0.
Let document be newPopoverOrTopLayerElement's node document.
For each popover of popoverList:
Set popoverPositions[popover] to index.
Increment index by 1.
If isPopover is true, then set popoverPositions[newPopoverOrTopLayerElement] to index.
Increment index by 1.
Let topmostPopoverAncestor be null.
Let checkAncestor be an algorithm which performs the following steps given candidate:
If candidate is null, then return.
Let okNesting be false.
Let candidateAncestor be null.
While okNesting is false:
Set candidateAncestor to the result of running nearest inclusive open popover given candidate.
If candidateAncestor is null or popoverPositions does not contain candidateAncestor, then return.
Assert: candidateAncestor's popover
attribute is not in the manual or none state.
Set okNesting to true if newPopover's popover
attribute is in the hint state or candidateAncestor's popover
attribute is in the auto state.
If okNesting is false, then set candidate to candidateAncestor's parent in the flat tree.
Let candidatePosition be popoverPositions[candidateAncestor].
If topmostPopoverAncestor is null or popoverPositions[topmostPopoverAncestor] is less than candidatePosition, then set topmostPopoverAncestor to candidateAncestor.
Run checkAncestor given newPopoverOrTopLayerElement's parent node within the flat tree.
Run checkAncestor given invoker.
Return topmostPopoverAncestor.
To find the nearest inclusive open popover given a Node
node, perform the following steps. They return an HTML
element or null.
Let currentNode be node.
While currentNode is not null:
If currentNode's popover
attribute is in
the auto state and currentNode's
popover visibility state is showing,
then return currentNode.
Set currentNode to currentNode's parent in the flat tree.
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.
If document's showing hint popover list is not empty, then return document's showing hint popover list's last element.
If document's showing auto popover list is not empty, then return document's showing auto popover list's last element.
Return null.
To perform the popover focusing steps for an HTML element subject:
If subject is a dialog
element, then run the dialog focusing
steps given subject and return.
If subject has the autofocus
attribute, then let control be subject.
Otherwise, let control be the autofocus delegate for
subject given "other
".
If control is null, then return.
Run the focusing steps given control.
Let topDocument be the active document of control's node document's browsing context's top-level browsing context.
If control's node document's origin is not the same as the origin of topDocument, then return.
Empty topDocument's autofocus candidates.
Set topDocument's autofocus processed flag to true.
To check popover validity for an HTML element
element given a boolean expectedToBeShowing, a boolean
throwExceptions, and a Document
or null expectedDocument
perform the following steps. They throw an exception or return a boolean.
If element's popover
attribute is in the no popover state, then:
If throwExceptions is true, then throw a
"NotSupportedError
" DOMException
.
Return false.
If any of the following are true:
expectedToBeShowing is true and element's popover visibility state is not showing; or
expectedToBeShowing is false and element's popover visibility state is not ,
then return false.
If any of the following are true:
element is not connected;
element's node document is not fully active;
expectedDocument is not null and element's node document is not expectedDocument;
element is a dialog
element and its is modal
is set to true; or
element's fullscreen flag is set,
then:
If throwExceptions is true, then throw a
"InvalidStateError
" DOMException
.
Return false.
Return true.
To get the showing auto popover list for a
Document
document:
Let popovers be « ».
For each Element
element in
document's top layer:
If all of the following are true:
element is an HTML element;
element's opened in popover mode is "auto
"; and
element's popover visibility state is showing,
then append element to popovers.
Return popovers.
To get the showing hint popover list for a Document
document:
Let popovers be « ».
For each Element
element in
document's top layer:
If all of the following are true:
element is an HTML element;
element's opened in popover mode is "hint
"; and
element's popover visibility state is showing,
then append element to popovers.
Return popovers.
To close entire popover list given a list popoverList, a boolean focusPreviouselement, and a boolean fireEvents:
While popoverList is not empty:
Run the hide popover algorithm given popoverList's last item, focusPreviousElement, fireEvents, and false.
Buttons may have the following content attributes:
popovertarget
popovertargetaction
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 >
HTMLButtonElement/popoverTargetElement
Support in all current engines.
HTMLInputElement/popoverTargetElement
Support in all current engines.
The popoverTargetElement
IDL attribute must
reflect the popovertarget
attribute.
HTMLButtonElement/popoverTargetAction
Support in all current engines.
HTMLInputElement/popoverTargetAction
Support in all current engines.
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:
Let popover be node's popover target element.
If popover is null, then return.
If eventTarget is a shadow-including inclusive descendant of popover and popover is a shadow-including descendant of node, then return.
If node's popovertargetaction
attribute is in the show state and
popover's popover visibility state is showing, then return.
If node's popovertargetaction
attribute is in the hide state and
popover's popover visibility state is , then return.
If popover's popover visibility state is showing, then run the hide popover algorithm given popover, true, true, and false.
Otherwise, if popover's popover visibility state is and the result of running check popover validity given popover, false, false, and null 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.
If node is not a button, then return null.
If node is disabled, then return null.
If node has a form owner and node is a submit button, then return null.
Let popoverElement be the result of running node's get the popovertarget
-associated
element.
If popoverElement is null, then return null.
If popoverElement's popover
attribute is in
the no popover state, then return null.
Return popoverElement.
"Light dismiss" means that clicking outside of a popover whose popover
attribute is in the auto state 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:
Let target be event's target.
Let document be target's node document.
Let topmostPopover be the result of running topmost auto popover given document.
If topmostPopover is null, then return.
If event's type
is "pointerdown
", then: set document's popover
pointerdown target to the result of running topmost clicked popover given
target.
If event's type
is "pointerup
", then:
Let ancestor be the result of running topmost clicked popover given target.
Let sameTarget be true if ancestor is document's popover pointerdown target.
Set document's popover pointerdown target to null.
If ancestor is null, then set ancestor to document.
If sameTarget is true, then run hide all popovers until given ancestor, false, and true.
To find the topmost clicked popover, given a Node
node:
Let clickedPopover be the result of running nearest inclusive open popover given node.
Let invokerPopover be the result of running nearest inclusive target popover for invoker given node.
If the result of getting the popover stack position given clickedPopover is greater than the result of getting the popover stack position given invokerPopover, then return clickedPopover.
Return invokerPopover.
To get the popover stack position, given an HTML element popover:
Let hintList be popover's node document's showing hint popover list.
Let autoList be popover's node document's showing auto popover list.
If popover is in hintList, then return the index of popover in hintList + the size of autoList + 1.
If popover is in autoList, then return the index of popover in autoList + 1.
Return 0.
To find the nearest inclusive target popover for invoker given a Node
node:
Let currentNode be node.
While currentNode is not null:
Let targetPopover be currentNode's popover target element.
If targetPopover is not null and targetPopover's popover
attribute is in the auto state and targetPopover's popover
visibility state is showing, then return
targetPopover.
Set currentNode to currentNode's ancestor in the flat tree.