Making CSS Drop Down Menus Work on the iPhone
Wednesday, March 23, 2011 10:00 PM
Today I spent a while struggling to get a CSS drop down menu to work on the iPhone. The short of it is that you need to either explicitly set display: none; on the secondary list and change it to block or any visible setting on :hover or, I stumbled on this later, you need to specify a width on the drop down unordered list (and not it’s list item children). If you’re curious for more, keep reading.
I recently had a client ask if I could get the drop down menus on his website to work on the iPhone. We hadn’t done anything special for mobile devices on this project, but basic navigational functionality is of course very important. I was surprised at the request because sites I’ve done before have used drop downs that worked. What was different here? If you’ve used a drop down menu on the iPhone before you know what to expect. On the first tap of the top level navigational item the second level list appears (and the link you clicked on seems to show it’s activated state >—not tested). You can then select a secondary item or tap again on the main link to follow it. However, on this particular site, when the top item was tapped the drop down would display, but before anything could be done the link would be followed and you would be taken to that page. Good luck trying to stop the browser load or selecting a sub-link first!
After a long and fruitless search on the web I started asking some friends of mine for help and looking at sites they had developed. I noticed all the sites with correctly functioning iPhone friendly drop down menus use JavaScript.
Meh.
I’ve used SuckerFish before and it is a great script, but I’m more happy with a pure CSS solution (and I’m not supporting dead versions of IE). So I did a little sleuthing and discovered that all of these JS enabled websites toggle the display CSS rule of the sub-menu between none and block. My CSS code was toggling the left rule from -999em to auto alone. So I did some testing of different combinations and discovered that the display rule is the only one that matters. No JavaScript is required as long as you explicitly set display: none; as the initial rule for the sub-menu. And then on :hover you just change display to any visible option you want.
Try it out for yourself. Below are two CSS only drop down menus. Both will work in a desktop browser, but only the second will work correctly on an iPhone. Here are the two declarations that are added for the working drop down:
#ios ul { display: none; } #ios li:hover ul { display: block; }
Update: As I’ve been testing this out, I just realize that setting a width on the drop down secondary list will also make it work. It doesn’t need to be on hover of course then, just on the initial declaration.
- This will reload the page on first tap
- Now you see me...
- And I'm gone!
- Home page
- This will reveal on first tap and load on second tap
- Now you see me...
- Hey, I'm still here!
- Home page
Comments
Paul said
Thanks! - this worked a treat.
I was puzzled why some of my menus worked fine on iphone and other didnt.
Later discovered that I was using left:-999px; for some of the menus, and diplay:none;
The ones with display:none worked fine on iphone/ipad
On 02/26 at 02:50 PM
Natasha said
I also found that just wrapping the top level menu item in worked to enable the drop down on the iphone.
On 02/27 at 06:28 PM