In the world of web design and development, dropdown navigations or menus are a very common feature in pretty much any kinds of website because they are intuitive and not that difficult to code. However, they can be quite troublesome for users of touch-screen devices who cannot perform a proper hover interaction to expand the child panels of a dropdown navigation.

A simple tap (click) can be used to produce a hover effect. However, it won’t work properly on hyperlinks with URL. On some mobile browsers, hover can be emulated by a long touch on the hyperlink but this can also produce unwanted results such as opening a context menu or highlighting the text.

Consider this typical Suckerfish-style HTML structure:

<ul id="mainmenu">
	<li><a href="about.html">About</a>
		<ul>
			<li><a href="about.html">Overview</a></li>
			<li><a href="news.html">News</a>
				<ul>
					<li><a href="news.html">Latest</a></li>
					<li><a href="archive.html">Archive</a></li>
				</ul>
			</li>
		</ul>	
	</li>
</ul>

Here’s how it looks like.

Users using the touchscreen devices would not be able to access the sub-menus by a simple tap because both About and News has a URL that will simply redirect the page.

The workaround here is when a touch-screen browser is detected, we disable the URL in the hyperlinks dynamically via Javascript either by changing the location to “#” or by preventing the default action. Conveniently enough, the code for detecting touch-screen browsers can be borrowed from the awesome Modernizr.js library, in just three lines.

function is_touch_device() {
  return !!('ontouchstart' in window);
}

What is left now is just to write the JS code that will go through the dropdown menu HTML and modify the <a> tag accordingly if it has a sub-menu. In jQuery, this can be written as follows:

$(document).ready(function() { 
	
	/* If mobile browser, prevent click on parent nav item from redirecting to URL */
	if(is_touch_device()) {	

		$('#mainmenu li > ul').each(function (index, elem) {
			/* Option 1: Use this to modify the href on the <a> to # */
			$(elem).prev('a').attr('href' ,'#');	
			
			/* OR Option 2: Use this to keep the href on the <a> intact but prevent the default action */
			$(elem).prev('a').click(function(event) {
  				event.preventDefault();
			});
		});
	}
	
});

If you have a dropdown menu with only one level of children, the code can be simplified further by modifying the jQuery selector and eliminating the “each” loop.

$(document).ready(function() { 
 
	/* If mobile browser, prevent click on parent nav item from redirecting to URL */
	if(is_touch_device()) {	
		/* Option 1: Use this to modify the href on the <a> to # */
		$('#mainmenu > li > a').attr('href' ,'#');		
		
		/* OR Option 2: Use this to keep the href on the <a> intact but prevent the default action */
		$('#mainmenu > li > a').click(function(event) {
			event.preventDefault();
		});
	}
	
});

The choice of using between Option 1 and Option 2 depends entirely on your application. If for instance you have additional JS events or interactions attached to the <a> tag of the dropdown menu, Option 2 might be useless because event.preventDefault(); might prevent those interactions from happening.

Click here to view the demo.

As always, I am happy to hear any other methods you might have out there to make hover interaction less miserable for touch screen users. Have a nice day!