Introducing the HTML5 “Menu” and “Menuitem” Elements
Today I’m going to introduce you to two HTML5 elements: <menu>
and <menuitem>
, part of the Interactive Elements specification. The web has evolved into something more than just linked documents; pages behave increasingly these days like apps. As such, it’s an appropriate time to form standard web interactivity features.
These two elements are amongst the least talked-about among developers, probably owing to their lack of support in major browsers. Firefox is the sole browser to have implemented this element at the time of writing.
Menu vs. Nav Element
When we’re talking about menu
it’s important not to be confused with <nav>
. The specification does a good job in defining the difference between these two distinct elements.
The <nav>
is the HTML Navigation Element. It is the element which represents the web page navigation block. It generally contains a set of links which allow users to navigate or jump through sections on the page or to another page of the website.
The <menu>
, on the other hand, represents a set of menu commands. The idea is similar to desktop or mobile applications. Desktop applications commonly use toolbar menus and context menus to perform varying tasks. Take the Blur menu in Photoshop, for example. This performs a task which makes the selected layer blurry.
This is the underlying difference between these two elements; <nav>
should contain links to help users navigate through web pages, whereas the <menu>
element should help users carry out certain tasks.
Using the Menu Element
In a nutshell, the <menu>
element is designed for creating contextual, toolbar, and popup menus. However, the latter two of these have not yet been implemented in any browser, including in Firefox. At the moment, it’s difficult to guess how (if?) browsers will implement them and how they will look. There’s also a good chance that the toolbar and popup menu specification will slightly change in the next iteration.
For now, we will focus our attention on the Contextual Menu feature.
Contextual Menu
A contextual menu (or context menu) appears when we right-click on an application. The options revealed are specific to where the user has clicked, hence context.
JavaScript Option
It is possible to add context menus on web pages through JavaScript or a jQuery plugin. The problem with this method is that it often requires hefty markup, and, critically, the script will remove the browser native context menu, which may disrupt common user expectation if not done properly.
Native Solution
<menu>
along with the <menuitem>
element will incorporate the new menu items as part of the native contextual menu. In the example below, we will add to our <body>
a new context menu item named "Hello World".
1 |
<body contextmenu="new-context-menu"> |
2 |
<menu id="new-context-menu" type="context"> |
3 |
<menuitem>Hello World</menuitem> |
4 |
</menu>
|
5 |
</body>
|
The essential parts of the above snippet are the attributes — id
, type
and contextmenu
— which specify the menu type as a context
menu as well as the scope where the new menu should be displayed.
In our case, the new menu will appear anywhere on the document when performing right-click, as we’ve assigned it using the contextmenu
attribute to the body
.
Alternatively, you can restrict the scope within a certain section on the page by assigning thecontextmenu
attribute to the elements — <div>
, <main>
, <section>
, and etc. — instead in the body
.
1 |
<body>
|
2 |
<div contextmenu="new-context-menu"> |
3 |
<!-- content -->
|
4 |
</div>
|
5 |
<menu id="new-context-menu" type="context"> |
6 |
<menuitem>Hello World</menuitem> |
7 |
</menu>
|
8 |
</body>
|
When we view it in the browser (at the moment, only in Firefox) you should see that the menuitem
we declared is added at the very top of the list.
Adding Sub-menu and Icon
Sub-menus comprise a group of items with co-related or similar actions. The Photoshop Image Rotation menu is a perfect example of this. The Image Rotation menu carries several sub-menu items to let users select which degree of rotation ( 900
and 1800
) they want, as well as the direction to apply it.
Using the <menu>
element, adding sub-menus is easy and intuitive. Go ahead and nest another<menu>
along with a label
to declare the menu name, like so:
1 |
<menu id="demo-image" type="context"> |
2 |
<menu label="Image Rotation"> |
3 |
<menuitem>Rotate 90</menuitem> |
4 |
<menuitem>Rotate 180</menuitem> |
5 |
<menuitem>Flip Horizontally</menuitem> |
6 |
<menuitem>Flip Vertically</menuitem> |
7 |
</menu>
|
8 |
</menu>
|
When we run this in a supporting browser, we will find a new menu with four sub-menus:
Icons
Furthermore, a new attribute called icon
has been introduced making it possible to add an icon along side the menu. It’s worth noting that this attribute is only applicable within the <menuitem>
element. Specify the icon path to the icon
, like so.
1 |
<menu id="demo-image" type="context"> |
2 |
<menu label="Image Rotation"> |
3 |
<menuitem icon="img/arrow-return-090.png">Rotate 90</menuitem> |
4 |
<menuitem icon="img/arrow-return-180.png">Rotate 180</menuitem> |
5 |
<menuitem icon="img/arrow-stop-180.png">Flip Horizontally</menuitem> |
6 |
<menuitem icon="img/arrow-stop-270.png">Flip Vertically</menuitem> |
7 |
</menu>
|
8 |
</menu>
|
And there it is the icon, as you can see below.
Adding a Function in the Menu
We’ve built something which looks like a context menu, but it doesn’t yet function as such. Users will expect something to happen when they click on it; clicking on Copy should copy the text or link, while clicking a New Folder menu item should create a new folder. We can do this using JavaScript.
Note: before proceeding I recommend you take a look Jeremy McPeak’s course on JavaScript Fundamentals; a great starting point for anyone learning JavaScript.
Take our “Image Rotation” example above, let’s add a function that will rotate the image we’ve clicked on. CSS3 Transform and Transition can perform the actual rotation in the browser for us; here is the style that will rotate the image 90 degrees:
1 |
.rotate-90 { |
2 |
transform: rotate(90deg); |
3 |
}
|
With the style rule specified, we need to write a function to apply this to the image:
1 |
function imageRotation(name) { |
2 |
document.getElementById('image').className = name; |
3 |
}
|
Add this function in the respective <menuitem>
through the onclick
attribute and pass the parameter with the class name, rotate-90
:
1 |
<menu id="demo-image" type="context"> |
2 |
<menu label="Image Rotation"> |
3 |
<menuitem onclick="imageRotation('rotate-90')" icon="img/arrow-return-090.png">Rotate 90</menuitem> |
4 |
<menuitem icon="img/arrow-return-180.png">Rotate 180</menuitem> |
5 |
<menuitem icon="img/arrow-stop-180.png">Flip Horizontally</menuitem> |
6 |
<menuitem icon="img/arrow-stop-270.png">Flip Vertically</menuitem> |
7 |
</menu>
|
8 |
</menu>
|
To finish off, create the style rules that will rotate the image 180 degrees and flip the image. And add each function within the respective item along with the parameter. View this example in action in the demo page.
Conclusion
The <menu>
element could be very useful both in web applications or regular websites. Sadly, the support is still really poor.
Hopefully, Safari, Chrome, Opera, and Internet Explorer will catch on soon and also implement the other menu types ( popup
and toolbar
). I’m really looking forward to how this element will evolve during the coming year.