Last Updated on
<menu> tag has a bit of a troubled history. In HTML3 it was essentially synonymous with
<ul>. It was deprecated in HTML4, but added back to the specification for HTML5. Due to feedback from browser makers, it changed a bit between the publishing of the W3C HTML5 spec and the continued work on the WHATWG HTML5.1 spec.
The purpose of the
Support is a bit lacking at this point, but there's definite progress in a few browsers. There are actually a few different pieces of menu-related support that we're interested in knowing about:
- Support for the basic
- Support for the popup
- Support for the
- Support for the
There was previously a
<button type="menu"> in the spec to allow opening context menus via buttons, but that has been removed as of February 2017. Unfortunately, that severely limits the usefulness of the
If you're curious to know more, the rest of the post will explain the spec and how the
<menu> tag can be used. If you're just interested in knowing current browser support for the above features, here's the support matrix:
|Firefox||Chrome||Safari||Edge||Android Chrome||iOS Safari|
|toolbar menu||Partial||Yes (Flag)||Partial||Partial||Yes (Flag)||Partial|
|popup menu||Yes||Yes (Flag)||No||No||Yes (Flag)||No|
|menuitem||Partial||Yes (Flag)||No||No||Yes (Flag)||No|
|contextmenu||Yes||Yes (Flag)||No||No||Partial (Flag)||No|
Note: Chrome support is limited to Chrome 48+ running with
Between Chrome 48 and 52, it was enabled behind the "Experimental Web Platforms" feature flag.
Making Sense of Menus
The most basic case of the
<menu> tag is using it as it was used back in the HTML3 days to provide a list of links. Its children should be
<li> list items with links or buttons inside. This is the default type of menu, and is supported by all browsers. In most cases, it looks identical to a
In HTML5, the
<menu> element has a
type attribute that determines which type of menu is being defined. The default value for
"toolbar", which preserves the list-like appearance from HTML3.
Note: Neither Chrome nor Firefox properly implement the default value for the
Chrome does not implement the
typeattribute at all unless the "Experimental Web Platform Features" flag is enabled.
Firefox returns an older (now incorrect) default value of
A basic example of sidebar link using
<menu> might look something like this:
<menu type="toolbar"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </menu>
Making Use of HTML5
Beyond being compatible with HTML3, the HTML5
<menu> tag is intended to add custom context actions to right-click/long-press popup menus in the browser. To define a popup menu, you need to set the
type attribute to
<menu> elements are intended to be combined with the global
contextmenu attribute. You can specify
contextmenu on any element in your page and set its value to the ID of a
<menu> in the same DOM hierarchy, and when the contextmenu event is triggered on that element it will show the specified
Note: Chrome on Android supports the
contextmenuattribute, but does not enable long-press on the elements. Therefore, you can only bring up the menu on a element that already has long-press support (like an
As an example, this is how you might associate a menu with a
<div contextmenu="myMenu">Right-click Me</div> <menu type="context" id="myMenu"> </menu>
Now this menu doesn't really accomplish much because it's empty. To add actions to our menu, we need to use the
<menuitem> tag. This element is optionally self-closing (like
<options>) and does not require a closing tag if it is followed by another
<menu>, or the end tag of its parent element.
Note: Firefox doesn't treat
<menuitem>as self-closing properly at the moment, so to be safe I'd recommend including a closing tag.
<menuitem> tag is modelled after the
<option> tag. The first and most important attribute is
label. This is the text that you want to appear in your popup menu. If no
label attribute is specified, the text content of the element will be used as the label.
The simplest menu item looks like this:
<menuitem label="Menu Item 1">
Some other basic attributes for
icon: Adds an icon to the menu when the
iconvalue is the URL of an image.
disabled: Visually disables and prevents clicking on the menu item.
title: Provides a hint describing the item action, which may be displayed as a tooltip.
Note: Chrome doesn't support the
iconattribute at the moment.
I don't think any browsers support the
Our example might now look something like this:
<div contextmenu="myMenu">Right-Click Me</div> <menu type="context" id="myMenu"> <menuitem label="Item 1" title="The first menu item"> <menuitem label="Item 2" title="The second menu item" disabled> </menu>
More complicated menu items
Often menus are used by applications to present a quick way to enable or disable options, or to toggle between a few different options. We can do that in HTML too by looking at some of the advanced attributes for the
For menu items that can be toggled on and off (like a checkbox), set the
type attribute to
"checkbox". You can specify if the item is checked by default using the
For items that behave like a radio button group, set the
type attribute to
"radio", and give all the items the same
radiogroup value. You can specify which item should be checked by default with the
You can also group menu items by adding separators with an
Our more complicated example looks like this:
<menu type="context" id="myMenu"> <menuitem type="checkbox" label="Enable CSS" checked> <menuitem type="checkbox" label="Enable JS"> <hr> <menuitem type="radio" radiogroup="img" label="PNG" checked> <menuitem type="radio" radiogroup="img" label="JPEG"> <menuitem type="radio" radiogroup="img" label="GIF"> </menu>
There's one more type of menu item, a
"command" type that references another element in the page by ID and triggers it with a click event when the menu item is activated.
<button id="submitbutton" type="submit">Submit</button> <menu type="context"> <menuitem type="command" command="submitbutton" label="Submit"> </menu>
You can create submenus by nesting
<menu> elements within each other. When creating a child menu, you must specify the
label attribute on the child
<menu>. This label will be displayed as a menu item that opens the child menu.
<div contextmenu="myMenu">Right-Click Me</div> <menu type="context" id="myMenu"> <menu label="Child Menu"> <menuitem label="Child Item 1"> <menuitem label="Child Item 2"> </menu> </menu>
Opening Menus With Buttons
Much to my dismay, this feature is missing in all browsers and – as of February 2017 – has been entirely dropped from the HTML5 spec.
The HTML5 spec proposed adding a new type of
<button> for opening menus when activated. If the button
type attribute is
"menu" and the
menu attribute is the ID of a popup
<menu> tag, clicking or tapping the button should open the menu.
This is where the real value of menus can be used, combining a
<menu type="toolbar"> containing
<button type="menu"> elements with
<menu type="context"> elements to build a standard-style menu bar using only standards-based HTML.
(Not working) example:
<button type="menu" menu="myMenu">Click Me</button> <menu type="context" id="myMenu"> <menuitem label="Item 1"> <menuitem label="Item 2"> </menu>
I worked on a JS polyfill for this missing feature, which you can find as
ay-menu-button on npm.
- : Updated to reflect that WHATWG have broken my heart by dropping
<button type="menu">from the spec.
- : Updated to reflect Chrome moving the feature behind more flags in Chrome 52.
- : Updated to reflect the loosened
<menuitem>text content rules.
- : Updated to reflect Chrome 48 support for
- : Updated to reflect that the spec has been changed from
- : Originally published.