ARIA practices on menu and menubar. Namely, our proposal includes adding <menubar>
, <menulist>
, and <menuitem>
elements.
Having native menu features will make it easier for web developers to add menulists, menubars and better configure the menu items to choose from. Furthermore, introducing these new features will expand on the baseline behaviors popover and anchor positioning provide. New native menu elements will also have the correct implicit ARIA roles, states and properties as well as the expected keyboard navigation behaviors - ensuring consistent experiences for users on the platform they are engaging with.
Use cases:
<menuitem>
elementsSection titled New%20%3Cmenuitem%3E%20elements<menuitem>
<menubar>
and <menulist>
disabled
attribute, and the :disabled
CSS pseudo-class<menuitem menu=submenu>
<menuitem>
is checkable, and its state changes<menuitem>
s in a <fieldset>
with a new checkable
attribute; see Grouping menuitems together.Question: Should <menuitem>
s be represented by a single element, or multiple elements?
As stated, our proposal involves introducing a single <menuitem>
element to represent menu buttons, some of which can be checkable. Instead of representing both non-checkable & checkable state-bearing menu items with the single <menuitem>
element, we could also consider:
type
attribute: <menuitem>
, <menuitem type=checkbox>
, <menuitem type=radio>
.type
is checkbox
or radio
, it is automatically checkablecheckable
IDL attribute on <menuitem>
name
attribute to group exclusive menu items together (this only applies for “radio” menu items):<menuitem checkable name=foo>
<menuitem checkable name=foo>
checkable
IDL attribute on the grouping element (<fieldset>
, <menulist>
)single
(for radios) or multiple
(for checkbox)Question: Should we allow radio and checkbox menu items as direct children of a <menubar>
?
Currently, we don’t see a need for this. All menuitems inside a menubar should perform some action like opening a sub <menulist>
, however we will reconsider this restriction if good use cases arise.
For example, a text editor might need to provide a <menulist>
to provide basic font style adjustments. A group of checkable <menuitem>
elements to mark content as “Bold”, “Italic” or “Underlined”, could be provided. The checked state representing whether the text is currently “Bold” (checked) or not.
<menuitem>
s togetherSection titled Grouping%20%3Cmenuitem%3Es%20togetherOur proposal involves grouping <menuitem>
elements together with the new <menubar>
and <menulist>
elements, and does not modify the existing <menu>
element processing model. See https://github.com/openui/open-ui/issues/1194 for more discussion about this.
<menubar>
<menuitem>
s that can then open submenus of commands.<menuitem>
<menulist>
<menuitem>
Question: Is <fieldset>
necessary to group <menuitem>
together?
Yes. While, we can use the “name”
attribute to logically group exclusive checkable <menuitem>
s together, to support captioned groups of <menulist>
items, we should use the existing <fieldset>
element (and its optional labeling <legend>
element) that give this functionality to forms. If multiple <menuitem>
s are added without a <fieldset>
, they are grouped together under their parent <menulist>
or <menubar>
, but are logically separate and are not checkable.
Note, <fieldset>
is a more general grouping element than <optgroup>
, which we briefly considered, but decided against since it is used for grouping options.
Our proposal includes adding a checkable
attribute on <fieldset>
, to group <menuitem>
s as either radios or checkboxes, instead of introducing new <menuitemcheckbox>
and <menuitemradio>
elements. We envision the following markup:
<menulist>
<fieldset checkable=single>
<legend>Sort by</legend>
<menuitem>Recently added</menuitem>
<menuitem>Date created</menuitem>
<menuitem>Creator</menuitem>
</fieldset>
<fieldset checkable=multiple>
<menuitem>1 bedroom</menuitem>
<menuitem>2 bedrooms</menuitem>
<menuitem>3 bedrooms</menuitem>
</fieldset>
</menulist>
Question: How should we expose the checked menu items to script?
It can be queried together as :checked element.
Question: Should we restrict <menubar>
and <menulist>
to only contain <menuitem>
s?
Similarly to customizable select, we expect everything to be wrapped inside <menuitem>
according to the content model. This includes non-interactive elements like logo, images, and text.
We should support <fieldset>
and <legend>
to help group the menu items together.
We should support specific use cases of interactive elements outside the <menuitem>
. For example, if the user wants to add an <input type=search>
element, it should not be wrapped inside a <menuitem>
and should instead be a sibling of <menuitem>
s.
Just like a select element, the menu element has a list of choices to pick from. And with customizable select now available, users might be confused on which one to use.
The <select>
element is a form-associated element and contains <option>
elements. Each of these <option>
elements must have a server-readable value. As a user chooses an option, specific events are triggered (change, input) and a new value is set.
On the other hand, the proposed <menulist>
element should be used to display a list of commands/actions. Each <menuitem>
should be thought of as a command that is activable. That action could be to open a new nested menulist element or to trigger a specific command. It must adhere to ARIA guidelines for menu and menubar.
<menuitem>
and not re-using the <command>
element?Section titled Why%20are%20we%20adding%20%3Cmenuitem%3E%20and%20not%20re-using%20the%20%3Ccommand%3E%20element%3FSee <command>
element’s deprecated specification here. In the last year, the command and commandfor attributes were introduced so buttons can perform actions on other elements declaratively. We thought re-using this obsolete element with the same name would be confusing to developers.
Additionally - command is a single element, where as this proposal is introducing various elements with additional grouping semantics and keyboard behaviors beyond what a single ‘command’ element would represent - or reasonably be capable of creating parity with the various ARIA roles these new proposed elements would be natively introducing to HTML.
<menubar>
and <menulist>
and not re-using the <menu>
element?Section titled Why%20are%20we%20adding%20%3Cmenubar%3E%20and%20%3Cmenulist%3E%20and%20not%20re-using%20the%20%3Cmenu%3E%20element%3FThe <menu>
element already exists, but it is very barebones. It represents a “toolbar” but is exposed no differently than an unordered list containing list items, each list item then representing a command (represented by a button element) that the user can perform or activate. There is a lot of nuance between the various menu patterns (menubar, navigation menu, toolbar) that this one element cannot differentiate. It has no special keyboard behavior nor unique ARIA roles mapping beyond the implicit roles of the elements it represents. Due to these legacy restrictions, we recommend not modifying it and instead depend on the new elements <menubar>
and <menulist>
.
You can read more about what the menu element is and isn’t, here.
<menulist>
Section titled Popover%20semantics%20for%20%3Cmenulist%3EGiven a <menuitem>
inside a <menubar>
, it can invoke a <menulist>
by invoking a target.
This can be accomplished by either:
<menuitem menu=id>
<menuitem menulist=id>
<menuitem popovertarget=id>
<menuitem command="show-menu" commandfor=id>
Questions
<menulist>
s are popovers by default, what happens if we add a popover attribute on top of it?<menulist>
?Section titled Why%20are%20we%20using%20popover%20instead%20of%20openable%20for%20%3Cmenulist%3E%3FAn ”openable” is an element rendered in-page with display:none until it is opened. This could be useful for mobile apps, where the menubar is shown vertically in-page.
An element with role=menu is pretty much exclusively a popover or contained within a popover. If someone wanted an in-page menu then a menubar, or a fieldset of controls might be the more appropriate solution. Someone could show/hide a menubar - much like how google docs allows one to show/hide the menubar with the toggle on the right side of the toolbar (hide the menus (ctrl+shift+f) button).
Openable is currently not standard. If there are valid cases of needing the <menulist>
element to be in-page and the feature is mature enough, we can revisit this.
We can use the same keyboard behavior as described in the table of the ARIA Authoring Practices Guide, which is demonstrative of the keyboard expectations for how menus and menubars work at the operating system level.
Questions
<menuitem>
in a <menulist>
and are moving to the next <menuitem>
in the <menubar>
.When user clicks on a menuitem:
The algorithm when the user activates a <menuitem>
in a <fieldset checkable=multiple>
:
The algorithm when the user activates a <menuitem>
in a <fieldset checkable=single>
:
Questions
<menulist>
cause it to close?<menuitem>
? This is not supported for popovers yet.No. the menu elements proposal is intended to be semantically different from customizable <select>
, which is in part achieved by the difference in form-association support. Supporting form-assocation also increases complexity (it raises questions like: what do we do if some of the controls appear outside of the menu element tree? how does form-association integrate with menu nesting?) with no obvious benefit; until a strong use case materializes, our default will be to not form-associate elements in this proposal.
However, we do recognize there are use cases where users might want to have inputs inside the menulists or menubars. For example, searchable menus using an input element. In such cases, the control is allowed in the menulist or menubar, but is not associated with a form.
We propose these elements should not support the CSS appearance property and just have a “base” appearance by default like the <dialog>
element.
Questions
<menubar>
should list <menuitem>
s horizontally, but support using CSS writing-mode.writing-mode: vertical-lr
on the <menubar>
writing-mode: horizontal-tb
on the <menuitem>
inside the <menubar>
<menulist>
can support more than top to bottom layout:display: grid
and use rows/columns.<menuitem>
, should the check mark be on the left or the right?direction
property.<menuitem>
, should there be a default slot for the icon? If so, should it be on the left or the right?direction
property.Previously, “context menus” were specified to allow developers to define custom context menus declaratively. This was being prototyped by Mozilla. Blink also had an implementation behind a flag.
<menu id="menu1" type="context">
<a href=#>Cancel</a>
</menu>
<button contextmenu="menu1">Right-click me</button>
Per comment and PR, this feature was removed from the HTML specification because there was a lack of active interest by at least two implementers.
From Chromium, the reasoning for removing support was:
Chromium bug: https://issues.chromium.org/issues/40589971
Mozilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=617528
Mozilla bug to remove support: https://bugzilla.mozilla.org/show_bug.cgi?id=1372276
Webkit bug about the touch bar API: https://bugs.webkit.org/show_bug.cgi?id=179020
The specification were removed per:
https://github.com/whatwg/html/pull/2742
https://github.com/whatwg/html/pull/2342
https://github.com/whatwg/html/pull/244
We discourage users from using these new elements to build a custom context menu. There are good reasons to keep the user agent defined context menu. For example, it allows users to copy/paste consistently across sites and to have browser extension options added. We do not plan to provide a declarative way to build a context menu.
However, this proposal is not about removing the existing web capabilities. Authors can use Javascript to add an event listener on “contextmenu” and call preventDefault to not show the default context menu. They can support custom context menus (similar to Google Doc) by showing a <menulist>
at the cursor location.
We understand it would be helpful to have this feature be natively supported. If we want to open the conversation about supporting this, here are some open questions to resolve:
<menuitem>
to the existing UA context menu?A “navigation menu” represents a means to allow users to access different pages/screen or sub-pages/screens of a website or web application - commonly used in many blogs, SPAs, news websites, really anywhere. The most common way to create a navigation menu is by using a <nav>
element, which implicitly exposes the ARIA landmark navigation
role. Lists, hyperlinks and buttons (to show/hide sub-navigation items) are the commonly expected child elements of many standard navigations, which generally do not need an author to declare specific ARIA roles to be accessible. Since all items in standard navigations are commonly hyperlinks and buttons, users can rely on standard Tab key navigation to reach each interactive element of the navigation.
Sometimes, to reduce the amount of keyboard tabbing to bypass large navigation menus, a Disclosure Navigation Menu pattern or Menubar Navigation pattern may be used. Each have their own pros and cons.
We are evaluating the possibility to include Navigation Menubar pattern in our proposal. We need to carefully evaluate if this is a valuable addition, as there are long standing UX concerns with using menubars in this way, and if such a pattern is introduced, we want to make sure it addresses the concerns of all users.
Questions
<nav>
element if we were to support a “disclosure” or “menubar” navigation pattern?<menubar>
, should we have a new <navmenubar>
element?<menuitem>
s?<menuitem>
should only wrap non-interactive elements.<menuitem>
s?Questions about VoiceOver on navigation menubar
A menubar provides a hierarchical structure of menus for accessing application functions while a toolbar provides quick access to commonly used commands through icons and buttons. As such, a toolbar can contain a variety of controls beyond just menuitems. For example, buttons and comboboxes to invoke menulists.
There are ARIA guidelines for the toolbar pattern, which is different from the menubar and the navigation menu patterns. This proposal will not address this yet.
There is a history of attempting to do this in Webkit, for example for a Touch Bar. The idea for this is to collect all your “commands” and put them into the macOS menu bar (or expose them some other way). This proposal will not address this yet.
<menubar>
<menuitem menu=format>Format</menuitem>
<menuitem menu=tools>Tools</menuitem>
<menuitem menu=extensions>Extensions</menuitem>
<menuitem menu=help>Help</menuitem>
</menubar>
<menulist id=format>
<menuitem menu="format-text">Text</menuitem>
<menuitem menu="format-paragraph-styles">Paragraph styles</menuitem>
<menuitem menu="format-align-indent">Align & indent</menuitem>
...
<menulist id="format-text" checkable=multiple>
<menuitem id="bold">Bold</menuitem>
<menuitem>Italic</menuitem>
<menuitem>Underline</menuitem>
...
</menulist>
</menulist>
<script>
bold.addEventListener("click", () => {
let text = document.getElementById("text");
text.style.fontWeight = 'bold';
});
</script>
Menus have been heavily discussed, please see below to learn about the existing specification and efforts.