Telerik blogs
The importance of user experience should never be underestimated. Software not withstanding, user experience is important in everything that we interact with, both physical and digital. There is an entire website dedicated just to user interaction fails with hilarious results. I captured one at the movie theater in my own small southern town. A door leading to a 20 foot drop that ends in pavement is obviously a relic from a remodel with no place in the natural order of things anymore. However, sometimes we have to sacrifice less important features in order to get support for more critical ones. In this case, they may have chosen to raise the ceiling instead of having a second story space. The door is the painful reminder. The web is all about sacrificing "perfect" in order to get "working". If there was ever a place in web development where we see this played out, it's with the Context Menu.

A Bit Of History

The Context Menu, like so many other things we know and love, was created by Xerox and first appeared in Smalltalk on the Xerox Alto, which interestingly enough had a portrait monitor. However, the menu was fixed to the screen and the user had to move the mouse across the screen to click and activate it. 640px-Xerox_Alto Jobs and his band of rebels at NEXTSTEP took the idea a step further and allowed the menu to be brought up with a right mouse click which allowed the menu to be summoned right where the mouse was located. Microsoft added their own bit of ingenuity when the allowed flyout and sub-menus in Word. Windows 7 changed the menu again, yet subtly, by activating the menu on release of the mouse button requiring two clicks to select a menu item. This was news to me as I have always clicked twice, but it is possible still on OS X to activate the menu with a right click and then select an item all in the same "click".

Browser Context Menus

As native applications, browsers have always had context menus. The options in the menus have varied over time, but generally include Copy/Paste/Refresh and more recently the all hallowed "Inspect Element". While the contents of the context menu will change depending on what part of the browser you right-click on, clicking on the contents within the browser viewport always renders the same menu. browser-cotext-menus The trouble with Context Menus in browsers is that the browser has quickly morphed from a way to post Live Journal entries into a runtime for applications. That means that we expect the applications that are running inside of the browser to behave like desktop ones do, and desktop apps have context menus. Essentially, we want a application with context menus within an application with context menus.

Native Browser Context Menu Options

The best solution would be a way to extend the built-in context menu so that we can add custom menu items to the existing list of system menu options. In that case we have a few options.

HTML contextmenu Attribute

Believe it or not, there is a spec for extending native context menus with the <menu> element that have a type of context and then referencing the id of that element with the contextmenu attribute wherever you want that context menu to appear.
<menu id="customMenu">
  <menuitem label="Share On Live Journal" onclick="blog()"></menuitem>
  <menuitem label="Check AOL Email" onclick="blog()"></menuitem>
  <menuitem label="Publish To GeoCities" onclick="blog()"></menuitem>
</menu>

<div contextmenu="customMenu">
  <h1>Native Context Menu?</h1>
</div>
Didn't work for you? That would be because native context menus are only supported in FireFox. Here - I included a GIF of it for you so you won't feel completely left out. firefox-context-menu Notice that the commands are simply appended to the top of the list. I find this a tad noisy, although the spec notes that maybe those default system commands would be collapsed by default, which I think is a much more desirable experience. It doesn't look like any other browser vendors plan on implementing this anytime soon. Why is that? I'm not entirely sure, but Addy Osmani noted that the FireFox implementation actually differs from the spec. However, when I looked at the WHATWG spec, everything looks legit to me.  Perhaps there is a different standard with the W3C.
The nice thing about standards is that you have so many to choose from — Andrew S. Tanenbaum
David Walsh points out that this custom context menu in FireFox will work even if JavaScript is disabled. This is a problem since those menu items are rather dependent on JavaScript in order to work. I don't see that as a reason not to implement them though. To add a twist to this story, Chrome actually does support custom context menus, just not on standard browser pages.

Chrome Context Menus

Chrome has an API for creating custom context menu items, but only in the confines of Chrome Apps and Extensions. Not only that, but it's completely different from what the WHATWG specifies and relies, instead, on a manifest JSON configuration file to specify the context menu structure. Chrome's Context Menus are quite a bit more robust, allowing for different types of menu items, such as radio buttons, checkboxes and menu separators. Interestingly enough, they also did not decide to collapse the standard menu items by default as suggested by the spec. packaged-app-context-menu

IE Custom Context Menus

Technically speaking, you can add in custom menu items in IE, but it requires hacking the Windows Registry and then of course those menu items show up on every page. Probably not the solution you were looking for.

So What Do We Do?

While there is no way to extend the native menu across browsers, vendors do universally provide access to the event that summons the context menu, providing developers a way to intercept and stop the native action so they can supplement it with their own.

Custom Context Menus

There is no shortage of jQuery context menu plugins, including one from Rodney Rehm that was then forked by Addy to act as a pollyfill, using the native implementation where available, and falling back to the jQuery based alternative. Kendo UI Core added a Context Menu in it's latest release. To create one, simply use an unordered list to construct the menu, initialize the plugin, and specify the target area where the plugin will be activated on right click.
<ul id="menu">
  <li>Share On Live Journal</li>
  <li><img id="aol" src="http://icons.iconarchive.com/icons/ncrow/mega-pack-2/256/AOL-icon.png">Email with AOL</li>
  <li>Publish To GeoCities</li>
</ul>

<div id="target">
  <h1>Right-Click Me For Some Options</h1>
</div>
(function() {
  $('#menu').kendoContextMenu({
    target: '#target',
    select: function(e) {
      alert('pfffft');
    }
  });
}());
By default Kendo UI Context Menus have a vertical orientation, but this is JavaScript, so why not have a horizontal one? Of course, Context Menus can have nested menus just like the native ones. That's accomplished simply by nesting lists. Adding separators is done by including a class of k-separator on an li. Since it's all JavaScript, we can even control how the thing is summoned. We can have it shown on a regular click, right click, or any other event.

Advantages And Disadvantages

Custom context menus are really neat and provide that missing "desktop-like" experience for users who are accustomed to working with that interaction. The downside is that highjacking the native context menu means you lose basic actions like copy/paste and you have to implement them all over again in JavaScript if you want them back. Also remember that context menus are a desktop interaction. They do not exist on mobile devices natively. Raymond Camden talks about how you could implement the "touchhold" event on mobile to summon the popup list. That's actually a pretty neat idea and Kendo UI does this for you automatically. Because we're always thinking mobile first baby.

Get Contextual

If you're in the market for a context menu, you can wait for browser vendors to implement it, which might blow your project timeline out of the water. OR, you could grab Kendo UI Core and get one that works across browser and on mobile devices today. Say it with me now, "Thank you, JavaScript".

Burke Holland is the Director of Developer Relations at Telerik
About the Author

Burke Holland

Burke Holland is a web developer living in Nashville, TN and was the Director of Developer Relations at Progress. He enjoys working with and meeting developers who are building mobile apps with jQuery / HTML5 and loves to hack on social API's. Burke worked for Progress as a Developer Advocate focusing on Kendo UI.

Comments

Comments are disabled in preview mode.