Brett Klamer

Pure CSS Flyout/Dropdown Menu With Touch Compatibility

2015-01-18
Gero Zahn has informed me this method does not work on IE11 with a Microsoft Surface. Since CSS isn't my thing, I don't really want to look into it or update the code. You may want to move on if you need a stable solution.
2015-08-11
Another update provided by Matt. To support the Surface, check out the info at https://www.codelibrary.me. It may just need an aria-haspopup="true" property on the parent links. Not confirmed to be working yet...

I couldn't find find any good examples of pure CSS menus, so I put this together combining a few things I learned along the way. It features one touch to select hovered elements, two touches to select a top-level link, a "diagonal problem" solution, and a delayed hover transition to prevent unwanted menu expansion. Since I don't know much about CSS or HTML I wont give detailed explanations (as I don't have them), but I did put comments in the code that highlight the important ideas.

The example code should work with the following:

IEFirefoxChromeSafari
Desktop IE 7+Desktop LatestDesktop LatestDesktop Latest
Mobile IE 10+Mobile LatestMobile LatestiOS 4+

Example

**You can click in this space to clear the selected menu in iOS.** Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus tincidunt velit eu ornare congue. Donec vitae dignissim nisl, ac ornare orci. Phasellus hendrerit porttitor quam, eget accumsan quam accumsan vel. Vivamus nec magna elit.

Example HTML and CSS Code

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <!--[if lt IE 9]><script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->

<style>
/*****************
** Main Stylings
******************/
nav {
    width:8.6em;
    border-right:1px solid #999;
    float:left;
    margin:0.25em 0.75em 2em 0;
    position:relative;}
nav ul {
    font-size:0.9em;
    float:left;
    padding:0;
    margin:0;
    list-style:none;
    display:inline-block;
    width:100%;}
nav a {
    display:block;
    color: #444;
    line-height: 2.2em;
    text-decoration:none;
    padding:0 0.5em;
    position:relative;}			

/*****************
** menu indicator
******************/
nav ul li a.parent {
    background:url(closed.gif) no-repeat right center;}
nav ul li:hover > a.parent {
    background:url(open.gif) no-repeat right center;}

/*******************
** background color
********************/
nav {
    background:#f0f0f0;}
nav ul li ul {
    background:#cccccc;}

/*******************
** hover properties
********************/
nav ul li:hover {
    width:9.555555em; 
    background: #f90;}
nav ul li ul li:hover {
    width:10.617283em;}
nav ul li ul li ul li:hover {
    width:11.796982em;}

/*transition actions inspired from http://www.greywyvern.com/?post=337 */
nav ul li > ul {
    position:absolute;
    left:100%;
    margin-top:-3.3em;
    visibility:hidden;
    opacity:1;
    -webkit-transition:visibility 0s linear 0.25s;
    -moz-transition:visibility 0s linear 0.25s;
    -ms-transition:visibility 0s linear 0.25s;
    -o-transition:visibility 0s linear 0.25s;
    transition:visibility 0s linear 0.25s;
}

nav ul li:hover > ul {
    visibility:visible;
    opacity:1;
    -webkit-transition-delay:0.25s;
    -moz-transition-delay:0.25s;
    -ms-transition-delay:0.25s;
    -o-transition-delay:0.25s;
    transition-delay:0.25s;
}

/**********************
** touch screen fixes
***********************/
/*gives our "z" tag the same stylings as the "a" tag. It covers the "a" tag so that one touch will highlight.*/
nav z {
    display:block;
    line-height: 2.2em;
    position:relative;
    width:100%;
    margin-top:-2.2em;
    height:2.2em;}
/*make the "z" tag disappear after hovering for 0.3s. One touch will highlight the item, two touches will select the "a" tag link. Some devices/browsers may need a longer delay time*/
nav > ul > li > z {
    -webkit-transition:width 0s linear .3s;
    -o-transition:width 0s linear .3s;
    -moz-transition:width 0s linear .3s;
    transition:width 0s linear .3s;}
nav ul ul > li > z {
    -webkit-transition:width 0s linear .3s;
    -o-transition:width 0s linear .3s;
    -moz-transition:width 0s linear .3s;
    transition:width 0s linear .3s;}
nav li:hover > z {
    width:0;}
</style>
</head>

<body>

<!--onclick="" is iOS clear selection hack. Add to all top level html tags-->
<nav onclick="">
    <h1>Flyout Menu</h1>
    <ul>
        <li><a class="parent" href="#1">Item 1</a><z></z>
            <ul>
                <li><a href="#2">Child 1</a></li>
                <li><a class="parent" href="#3">Child 2</a><z></z>
                    <ul>
                    <li><a href="#4">Child sub 1</a></li>
                    <li><a href="#5">Child sub 2</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li>
        <a href="#6">Item 2</a>
        </li>
    </ul>
</nav>

<!--onclick="" is iOS clear selection hack. Add to all top level html tags-->
<main onclick="">
<p>
**You can click in this space to clear the selected menu in iOS.** Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus tincidunt velit eu ornare congue. Donec vitae dignissim nisl, ac ornare orci. Phasellus hendrerit porttitor quam, eget accumsan quam accumsan vel. Vivamus nec magna elit. 
</p>
</main>

</body>
</html>

Last updated 2015-08-11 - Feel free to email me with any questions or comments.