Popup Element Spec Proposal (Abandoned)
Editors:
- Mason Freed (Google)
- Melanie Richards (Microsoft)
Note: This is an outdated proposal!
Please see the updated version here.
HTML Incubation Text: Popup
Target venue: HTML Living Standard
Categories:
Flow content.
Sectioning root.
Contexts in which this element can be used:
Where flow content is expected.
Content model:
Flow content.
Content attributes:
- Global attributes
anchor
— Creates an id-reference relationship with another element, which is used for both anchor positioning and popup stack managementdelegatesfocus
— Whether to move focus to the popup’s first focusable element when the popup is showninitiallyopen
— Whether the popup is shown upon document loadAccessibility considerations:
Pending specification in ARIA in HTML and HTML-AAM.
Add IDL to frontmatter (#356)
A popup
element represents transient application UI that “pops up” in the top layer of a web document, enabling the user to perform some task in a timely and immediate fashion. popup
is similar to the dialog
element, but is distinguished by its transient nature (“light dismiss” behaviors) and mutual exclusivity: only one popup
element may be rendered at a time, with the exception of nested popup
s.
Examples of popups include: button menus, listboxes used for item selection e.g. comboboxes, “teaching” UI, and other progressive-disclosure widgets or content pickers.
The open
IDL attribute, on getting, must return the last value to which it was set. On setting, it must be set to the new value. When the element is created, it must be set to false
.
Showing a popup
element
A popup
element and its contents must not be rendered unless:
- The
initiallyopen
attribute is specified - The
show()
method is invoked - Or the
popup
element has been invoked through user interaction with an element whosepopup
attribute references thepopup
element’s ID
This requirement may be implemented indirectly through the style layer. For example, user agents that support the suggested default rendering implement this requirement using the CSS rules described in the Rendering section.
The popup stack
This specification introduces a new stacking layer in the document top layer, called the popup stack. Each document has one popup stack.
The popup stack is an ordered set of elements, rendered in the order they appear in the set. The last element in the set is rendered last, and thus appears on top.
Showing or hiding a popup
element adds or removes the element from the popup stack, respectively.
The initiallyopen
attribute
The initiallyopen
attribute is a boolean attribute. When specified, it indicates that the popup element will be shown upon document load, such that the user can interact with it.
Example:
<popup initiallyopen></popup>
When a popup
element becomes browsing-context connected, the user agent must run the following steps, given a popup element candidate subject:
- If the
initiallyopen
content attribute is specified on the candidate subject, run the showing apopup
element steps. - Otherwise, set the candidate subject’s open state to
false
.
As a result of following this run step: in the event that initiallyopen is specified on multiple popups, the last of these popups (with the initiallyopen attribute) in the DOM order will be the popup that is rendered upon document load.
The show()
method
The show()
method renders the popup
element, such that the user can interact with it.
Example:
<popup id="newFeatureUI">
<p>
<strong>New!</strong>
I’m some sort of educational UI…
</p>
</popup>
<script>
if (upsellNewFeature) {
document.getElementById('newFeatureUI').show()
}
</script>
The show() method steps are to run the showing a popup
element steps with this.
The popup
attribute
The popup
attribute indicates that a related popup
element will be shown or hidden as the user interacts with the element where the popup
attribute is specified. If the attribute is specified, the attribute’s value must be the ID of a popup
element in the same node document.
Example: Invoking the button
element in this example will show/hide the popup
element, depending on whether or not the popup
element is currently shown:
<button id="menuButton" popup="menuPopup">Menu</button>
<popup id="menuPopup" role="menu" anchor="menuButton">
<!-- Markup for menuitems goes here -->
</popup>
The popup
attribute is supported on a subset of interactive elements:
button
input
in thebutton
stateinput
in theemail
,number
,search
,tel
,text
, orurl
states
Showing/hiding a popup
element via the popup
attribute
When an element with the popup
attribute specified receives a user interaction that shows the related popup
element, this element shall be known as the popup
element’s invoker.
Multiple elements may have a popup attribute that refers to the same popup element. A given popup element only has 0 or 1 invokers at a given time. For example, if the popup element was shown programmatically, the invoker is null. Otherwise, the element that the user actually interacted with to show the popup is its sole invoker.
If the invoker is a button
element or an input
element in the button
state, and the invoker is activated; OR the invoker is an input in the email
, number
, search
, tel
, text
, or url
states and focus is set to the invoker, the user agent must run the following steps:
- Let subject be the first element in tree order with the ID referenced by the
popup
attribute specified on the invoker. If there is no such element, or the subject is not apopup
element, then return. - Get the subject’s open state.
- If subject’s open state is
true
, run hiding apopup
element steps, with subject and invoker. - Otherwise, run showing a
popup
element steps with subject and invoker.
Showing a popup
element steps
The showing a popup
element steps, given a popup element candidate subject and an optional element invoker, and an optional element anchor element, are:
- Run the hiding currently-shown
popup
elements steps, with the candidate subject, invoker if it was given, and anchor element if it was given. - Add the candidate subject to candidate subject’s node document’s popup stack.
- Set the candidate subject’s open state to
true
. - If the
popup
element was shown as a result of a user interaction with aninvoker
, set the candidate subject’s invoker to invoker. - Let focusableArea be the result of getting the focusable area steps given candidate subject.
- Run the focusing steps given focusableArea.
Without the presence of the autofocus or delegatefocus attribute, focus remains on the active element. This behavior is to enable scenarios where the popup is used in a composite control. For example, a combobox where the user expects their focus to stay in the text input instead of moving automatically to the listbox popup as and when it appears.
Setting initial focus with the autofocus
attribute
The autofocus content attribute allows the author to indicate that an element is to be focused as soon as the page is loaded or as soon as the popup
within which it finds itself is shown.
When specified on the popup
element, it indicates that when the popup
element is shown, focus moves to the popup
element.
Example:
<popup autofocus>
<p>The popup itself will receive focus.</p>
<button>A focusable element</button>
</popup>
When specified on a descendent of the popup
element, it indicates that when the popup
element is shown, focus will move to the descendent of the popup
element where autofocus
is specified.
Example:
<popup>
<p>Text goes here</p>
<button>Button one</button>
<button autofocus>Button two</button>
</popup>
Setting initial focus with the delegatesfocus
attribute
The delegatesfocus
content attribute is a boolean attribute. When specified, it indicates that when the popup
element is shown, focus will move to the first focusable descendent of the popup
element.
Example:
<popup delegatesfocus>
<p>I am not a focusable element.</p>
<p>Nor am I.</p>
<button>I will be focused whenever the popup becomes focused.</button>
</popup>
As currently written in the text to be inserted into the “get the focusable area steps”: if both the delegatesfocus and autofocus content attributes are set on the popup element, the delegatesfocus behavior will take precedence (will be used).
Anchoring a popup
to another element
Many popups have a visual-logical relationship with another element that may not be a part of the popup
element’s ancestry chain. For example, a button
may control a popup
element, and the popup
needs to be positioned with respect to this button
. Or the popup
element may simply be used to draw attention to or describe another element. The anchor
attribute indicates this relationship. When specified, the attribute’s value must be the ID of an element in the same node document as the popup
element.
Example:
<button id="myButton">Anchor element</button>
<popup open anchor="myButton">
<p>
<strong>New!</strong>
I’m some sort of educational UI…
</p>
</popup>
The target of the anchor
attribute participates in determining whether a candidate popup
element is “nested” in a currently-shown popup
; refer to hiding currently-shown popup
elements steps.
Whenever there is a spec to point to for CSS anchored positioning, call out here that the anchor attribute is used to help resolve CSS anchor()
functions.
Hiding a popup
element
The hide()
method
The hide()
method hides a popup
element. The hide()
method steps are to run the hiding a popup
element steps with this.
Light dismissal
“Light dismiss” describes the behavior of a component which dismisses itself automatically when a user performs an action that implies that they are finished interacting with the component. The actions that trigger light dismiss are:
- The user presses the escape key.
- A focus change occurs (because of either user interaction or script), where the focus target is outside of the contents of the component. This includes the case where the user invokes a non-focusable element, which causes focus to jump to the nearest focusable ancestor of that element.
- An OS-level focus change occurs such that the window containing the component no longer has focus. For example, the user switches to a different browser tab or switches to a different application.
When a popup
element is shown and a light dismiss interaction occurs:
- If a keypress event for the
ESCAPE
key was fired, run hiding apopup
element steps, with the candidate subject set to the top-mostpopup
element in the popup stack. - If a focus change occurs, the user agent must set the start node to the element which received the focus event and run Hiding currently-shown
popup
elements steps. - Otherwise, the user agent must set the start node to null and run Hiding currently-shown
popup
elements steps.
Hiding currently-shown popup
elements steps
The hiding currently-shown popup
elements steps, given an optional popup element candidate subject, an optional element invoker, and an optional element anchor element, and an optional element start node, are as follows.
For each popup element subject in the node document’s popup stack:
- If candidate subject is null, run the hiding a
popup
element steps, with subject as candidate subject. - Otherwise, starting with the candidate subject, walk the flat tree to determine whether the subject is an ancestor to the candidate subject. If this condition is met, then return.
- Otherwise, if the invoker is not null, starting with the invoker, walk the flat tree to determine whether the subject is an ancestor to the invoker. If this condition is met, then return.
- Otherwise, if the anchor element is not null, starting with the anchor element, walk the flat tree to determine whether the subject is an ancestor to the anchor element. If this condition is met, then return.
- If start node is not null:
- If the start node is the subject, then return.
- Otherwise, starting with the start node, walk the flat tree to determine whether the subject is an ancestor to the start node. If this condition is met, then return.
- Otherwise, for this subject, run the hiding a
popup
element steps, with subject as candidate subject, and optional element invoker.
Hiding a popup
element steps
The hiding a popup
element steps, given a popup
element candidate subject and an optional element invoker, are as follows:
- Remove the candidate subject from the node document’s popup stack.
- Set the candidate subject’s open state to
false
. - Set the candidate subject’s invoker to null.
- Queue an element task on the user interaction task source given the candidate subject element to fire an event named
hide
at candidate subject.
HTML Incubation Text: User Interaction > Focus > Processing Model
The following text to be inserted into the get the focusable area steps.
If focus target is a popup
element
- If the
delegatesfocus
attribute is specified on focus target, return the first focusable descendent element of focus target, in tree order, that is not inert. - If there is no such descendent, but
delegatesfocus
is specified, return the focus target. - Otherwise, if the
autofocus
attribute is specified on focus target, return the focus target. - Otherwise, if the
autofocus
attribute is specified on a descendent element of focus target, return the first such descendent element of focus target, in tree order, that is not inert. - Otherwise, return.