View RSS Feed


iOS 'Sticky Hover' Fix - Unhovering dropdown CSS menus

Rating: 8 votes, 5.00 average.
One line of JavaScript to fix the 'sticky hover' problem on iOS; Where hover CSS isn't removed from an active element until another focusable element (button, link) is clicked. With this script, a tap of the surrounding area will remove hover CSS.

What's the problem?
In the opening paragraph, I state that a problem with hover activated CSS on iOS is that hover styles aren't removed until another element takes focus. A notable case for this is with CSS-only dropdown menus - the kind we see on desktop, which an iPad held in landscape orientation may also be big enough to accommodate.

Picture these steps;

- An iPad user activates the desktop CSS menu,
- Sub-menus dropdown over content below,
- The dropped/revealed menu does not hide again until something else is tapped...

... But how can a user make the decision to tap 'something else' with half the screen obscured?

JavaScript-enhanced menus may have already tackled this issue in a few ways;

- There may be a closing mechanism applied to the parent button - a tap on the same button that reveals the sub-menu, also hides it again.
- There may be a closing mechanism that is triggered with a tap elsewhere on the screen.
- There may be a user-intent delay - where the menu will 'unhover' when there has been no interaction with it for a certain amount of time.

* But what about our CSS-only hover menu? How can we quickly 'unhover' it without introducing JavaScript?

An interesting question. CSS animations may provide a CSS-only way to introduce a user-intent delay. I haven't tested the idea (yet), but thinking about it in the here and now, it seems plausible that the transition-delay: time; property may offer a way to automatically hide a dropdown, but I'm not sure how well it would translate between mouse and touch; Hiding the menu quickly enough when a mouse has moved away from it, AND offering enough of a delay on touch to give the user time to read, process, and choose a menu option. The mouse/desktop scenario is capable of identifying both the user's intent to open and close the menu (albeit with a delayed close) but the touch/mobile scenario only really identifies the user's intent to open the menu - the closing action is automatic, on a timed delay.

Hmmmm, so maybe CSS can't really offer an ideal solution. What about JavaScript? Let's revise the earlier question...

* But what about our CSS-only hover menu? How can we quickly 'unhover' it without introducing a lot of JavaScript?

A small and quick JavaScript fix
Here's something that I identified as a happy side-effect while exploring how to beat the 300ms delay on touch -- the CSS-only menu closes with a tap anywhere else on the screen -- but I wasn't thrilled about using a 25kb script, or even a 5kb script, just to hide open menus. So I isolated the pertinent part of the code to this;
(function(l){var i,s={touchend:function(){}};for(i in s)l.addEventListener(i,s)})(document); // sticky hover fix in iOS
The mere presence of this line somewhere in your script file (or on your web page, in <script> tags) will tame those content-obscuring dropdowns and send them cowering for cover with a tap anywhere on the screen.


Check out the demo below to compare the effect on a menu (before and after)

DEMO - iOS 'Sticky Hover' Fix - for iPad/ iPhone:

I hope you find it useful.

Disclaimer: Please test thoroughly in your own particular website setup because it may or may not introduce quirky behaviours in other script utilities.

Submit "iOS 'Sticky Hover' Fix - Unhovering dropdown CSS menus" to Submit "iOS 'Sticky Hover' Fix - Unhovering dropdown CSS menus" to StumbleUpon Submit "iOS 'Sticky Hover' Fix - Unhovering dropdown CSS menus" to Google Submit "iOS 'Sticky Hover' Fix - Unhovering dropdown CSS menus" to Digg