Blog (my web musings)

Find out what's interesting me, get tips, advice, and code gems that don't fit elsewhere.

Search Blog

One of the most annoying things on touch devices is the way that CSS hover activated menus stay open until another link is clicked. Well, this example fixes that: Responsive CSS3 Multi-Level, Drop-Down Menu (with SwiftClick)


Earlier releases of the Drop-Down menu have been replaced with better support for tap-activated sub-menus on touchscreen - reverted to using the arrow labels and checkbox hack [like the Fly-Out version does] - they're there for mobile view so why not use them on desktop!?! - instead of the pseudo " \/ " and " > " elements.

This responsive menu uses JavaScript to beat the 300ms delay on touch devices, close dropped-down sub-menus on touchscreen with a tap anywhere in the surrounding area, and close all the menus / sub-menus in one go in mobile view.

View it in a large screen touch device (iPad or other large tablet) and you can just click the surrounding area to close any open menus. Great stuff! "How did you do it?", I hear you ask. Well, to be honest, it was something I stumbled on while researching perceived performance on mobile (and ways to improve it).

Removing the 300ms delay

The first point in the article mentions a JavaScript function called FastClick by FT Labs, which removes that 300ms delay from web buttons / links. This sounded brilliant, so I downloaded it and started playing around. Unfortunately, I noticed some strange behaviour on my CSS menus, where FastClick caused sub-menus to momentarily vanish after activation, and then reappear, or worse still, it caused the wrong drop-down to open! Huh? It was all very perplexing. Now, I'm not saying that there's anything wrong with FastClick - far from it - my problems probably have more to do with the way I implemented it. But still, these issues prompted me to seek out a fix, which is how I came across an alternative to FastClick called SwiftClick. In their Faster Tapping with SwiftClick article, the author mentions the same problems that I'd noticed too;

For the most part this [FastClick] worked really well, but we eventually began to find that the until sometimes exhibited strange behaviour, such as events not firing when links were clicked and then firing later on, at the same time as other click events when different elements were clicked.

Well, at a 5th of the script size, (5kb instead of 25kb non-minified), I thought I'd give SwiftClick a whirl. I downloaded the minified code, dropped it into the bottom of my page (this demo), and then initialised it, as directed, on the document body;

var swiftclick = SwiftClick.attach(document.body);

By default, the SwiftClick script only targets common clickable elements (a, div, span, button), which is what makes it smaller than FastClick, but I want it to work on my menu's arrow labels too. With SwiftClick you can add more elements;

swiftclick.addNodeNamesToTrack (["label"]);

If you try the demo on a touch device, and compare it to the earlier version without SwiftClick you will see that the sub-menus activate in ultra-quick time, AND the drop-downs in desktop view close again without obscuring content! Oh, happy day, and big kisses to the SwiftClick team!

Don't have a large screen touch device? You can test it on a small screen touch device too. Just copy the source code into a web page of your own, but remove this line;

<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />

then upload it to your own web host / server and view there. The absence of that meta tag makes the desktop drop-down view visible on smaller screens.

Coincidentally, I tried SwiftClick on my Responsive Multi-Level, Fly-Out Menu and it works splendidly on that too!