LearnBuilding HTML5 Context Menus

   
Avatar

Matt West
writes on March 25, 2014

A lesser known feature of the HTML5 specification is context menus. These allow you to add custom items to the menu that appears when a user right-clicks on the page. Using JavaScript, you can then control the actions these items will perform when clicked.

In this blog post, you’re going to learn how to create your own context menus using the <menu> and <menuitem> elements.

Let’s get started.

Free trial on Treehouse: Do you want to learn more about HTML5 and front-end development? Click here to try a free trial on Treehouse.

Browser Support for HTML5 Context Menus

HTML5 context menus are currently only supported in Firefox (8+). This feature has been around for some time now, but no other browsers have implemented it. However, there is a polyfill available that will add support for context menus in other web browsers.

The menu and menuitem Elements

HTML5 context menus are constructed using two elements, <menu> and <menuitem>.

The <menu> element has a number of attributes that control how it will be displayed in the browser.

<menu type="context" id="menu">...</menu>

The type attribute is used to specify that we’re creating a context menu. This is important as the <menu> element can also be used for marking up other kinds of menus.

It’s important that you give your <menu> element an id, otherwise you won’t be able to use the menu on your page (more on this later).

The label attribute can be specified on nested <menu> elements to set the text that will be displayed in the main context menu.

Similarly the icon attribute can be used to specify the location of an icon image that will be displayed alongside the label text for nested menus.

Creating Menu Items

The <menuitem> element is used to create a new menu item. The label attribute should contain the text that you wish to display in the menu. You can also optionally specify an icon attribute with a path to an image to display alongside the label text.

<menuitem label="Tweet this Page" onclick="doSomething();" icon="/path/to/icon.png"></menuitem>

The action a menu item will perform is defined using JavaScript. You can use the onclick attribute to add this JavaScript directly to the <menuitem> element.


Note: I’m not a huge fan of using the onclick attribute to define event handlers, but I wasn’t able to get this working using an unobtrusive JavaScript approach.


Assigning Context Menus

Once you’ve created your context menu, you need to assign the menu to an element on the page. Your menu will only be visible in the context menu if the user right-clicks on this particular element.

You can assign a menu by specifying the contextmenu attribute on the desired element and setting its value to the id of your <menu> element.

<div contextmenu="menu-id">...</div>

If you want your menu to appear regardless of where the user clicks on the page, you could assign the menu to the <body> tag.

Nested Menus

Nested Context Menus

Nested Context Menus

You can nest <menu> elements within one another to create more complex menu structures. This can be particularly handy if you want to provide a large number of controls but don’t wish to clutter up the main context menu.

<menu type="context" id="menu">
    <menuitem label="Action" onclick="..." icon="icon.png"></menuitem>
    <!-- Nested Menu -->
    <menu label="Nested Menu Name" icon="/path/to/icon.png">
        <menuitem label="Action One" onclick="..."></menuitem>
        <menuitem label="Action Two" onclick="..."></menuitem>
        <menuitem label="Action Three" onclick="..."></menuitem>
    </menu>
</menu>

Nested <menu> elements should include a label attribute containing the text that will be displayed in the parent menu. You can also specify an icon attribute with a path to an image that will be displayed alongside the label.

Context Menu Demo

HTML5 Context Menus

HTML5 Context Menus

Putting this all together, here is a demo of an example context menu that provides options to share the current page. Here, we’re just going to use some simple JavaScript that will redirect the user to the appropriate sharing URL when the menu item is clicked.

<!-- Create the menu -->
<menu type="context" id="menu">
    <menuitem label="Tweet This Page" onclick="window.location='https://twitter.com/intent/tweet?text=' + document.title + ' ' + window.location.href;" icon="twitter.png"></menuitem>
    <menuitem label="Digg This Page" onclick="window.location='http://digg.com/submit?url='+window.location;" icon="digg.png"></menuitem>
    <menuitem label="Email This Page" onclick="window.location='mailto:?body='+window.location;"></menuitem>
</menu>

In this case, we’re just going to use a simple <div> element that will act as our click target for the menu.

<!-- The target element that the menu is assigned to -->
<div id="target" contextmenu="menu">Right-click here to see the menu.</div>

View The Demo Download The Code

Final Thoughts

Whilst I can think of a number of legitimate uses for HTML5 context menus (in-game controls being one — pause, restart, etc.), I also worry that the power to invade the browser UI like this could be exploited. Take some time to think whether the controls you plan to provide through the context menu could not be delivered better through a different interface. We run the risk of polluting the context menu and confusing users if we don’t use this feature responsibly.

What are your thoughts about HTML5 context menus? Do you wish other browsers would hurry up and implement this feature, or are you worried that it will just be exploited? Let us know in the comments below.

Useful Links

GET STARTED NOW

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you've been dreaming about.

Get Started

7 Responses to “Building HTML5 Context Menus”

  1. スーパーコピー時計専売店当店は海外安心と信頼のスーパーコピーブライトリング、代引き店です.正規品と同等品質のシャネル コピー代引き,品質が秀逸,値段が激安!ブライトリングコピー,代引きなどの商品や情報が満載!全商品写真は100%実物撮影です! お客様の満足度は業界No.1です!スーパーコピー時計,時計コピー ,ブランド時計コピー販売(n級品)店舗 ブランド腕時計(ロレックス,ブライトリング,タグホイヤー,オメガ,ガガミラノなど)の最新 情報やイベントを紹介する正規販売店と腕時計コピーの専門サイトです。当店はロレックスやパテックフィリップなどの新品スーパーコピー時計の販売と。
    エルバーキンコピーエルメスバーキン30コピーエルメス ボリード47,エルメス バッグ 名前,エルメス ネクタイ ピンク エルメス クラッチバッグ,エルメス バッグ コピー,エルメス バーキン コピー エルメス 財布 ダミエ オークション,エルメス ヨーロッパ,エルメス エールライン エルメス クラッチ激安通販、高い品質、送料無料。バーキン25コピー、バーキン30コピー、バーキン35コピー、バーキン40コピーなど世界中有名なブランドレプリカを格安で通販しております。N級品スーパーコピーブランドは ブランドスーパーコピー超N品エルメスバッグ,エルメス バーキン25 , バーキン30.バーキン35.バーキン40. エルメス(HERMES) ケリー http://www.wtobrand.com/he1.html

  2. Your comment form ate my HTML – it really should escape it instead. The HTML I posted was:

    menuitem label=”Tweet This Page” id=”menuItem1″

  3. You mentioned you weren’t able to write the JS code unobstrusively (horrible spelling, too lazy to fix 😉 but I had no issue simply adding an ID to the menu item and adding a click handler:

    ..

    document.addEventListener(“DOMContentLoaded”, function() {
    document.querySelector(“#menuItem1”).addEventListener(“click”, function() {
    console.log(“m1 click”);
    }, false);
    }, false);

    Am I missing something?

  4. From a usability point of view, who will actually know that you can right-click to access these menu items, you would need a space explaining this, which you could have populated with the required links in the first place.

    As you mention, use within html5 games could work nicely, a bit like how you would interact with Flash (sorry only example I could think of)

    Maybe also instead of links it could be used to place a short message, if right clicking on a copyrighted image, a kind reminder “not for personal use” etc?

    • Often times a web app will feel like a desktop environment, in which case a user might try to use a right-click context menu without knowing any implementation standards.

      As a user, it has been nice to find such a feature when I instinctively/accidentally right-click on the web.

Leave a Reply

You must be logged in to post a comment.

man working on his laptop

Are you ready to start learning?

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you've been dreaming about.

Start a Free Trial
woman working on her laptop