Solutions for CSS based responsive multi-level drop down menus without JS dependencies?

13,176

Solution 1

For the multilevel drop down menu with out java script I create a sample here.

HTML:

<ul>
    <li>
        Menu 1
        <ul>
            <li>Menu 1.1</li>
            <li>
                Menu 1.2
                <ul>
                    <li>Menu 1.2.1</li>
                    <li>
                        Menu 1.2.2
                        <ul>
                            <li>Menu 1.2.2.1</li>
                            <li>Menu 1.2.2.2</li>
                        </ul>
                    </li>
                    <li>Menu 1.2.3</li>
                    <li>Menu 1.2.4</li>
                </ul>
            </li>
            <li>Menu 1.3</li>
        </ul>
    </li>
    <li>Menu 1</li>
    <li>Menu 1</li>
    <li>Menu 1</li>
    <li>Menu 1</li>
</ul>​

CSS:

ul{
}
ul li{
    display:inline-block;
    position:relative;
}
ul li> ul{
    display:none;
    position:absolute;
    left:95%;
    top:15px;
}
ul li> ul li{
    display:block;
}
ul li:hover> ul{
    display:block;
}
​

Solution 2

I'm going to say right up front that this solution/pattern is not a drop down solution. But, it is a very cool way to rethink navigation for responsive designs. I don't know the full extent of your navigation needs, either, so this might not be complex enough for you.

Take a look at the Contents Magazine site: http://contentsmagazine.com/

Note the main navigation under the logo. When viewed in a smaller viewport (resize your browser), you will see the 'explore' link. That link, when tapped, gets you to the navigation.

Here's the thing: It's just a simple anchor link.

The pattern is this: In terms of page source order, your navigation is actually towards the bottom of the page. (And, in terms of semantics, this makes a lot of sense to boot.) There is a simple anchor link at the top of the page that jumps to the navigation (which is also an accessibility best practice).

So, thinking mobile-first, the page loads with the navigation at the bottom of the page, but the user can click the anchor link to get to it. As it's an anchor link, the jump is instantaneous, and it actually almost feels like a drop down.

Then, as the viewport gets larger, using just CSS, the navigation is moved (presentationally, anyway) to the top of the page, and positioned under the logo. That is achieved with simple absolute positioning.

Solution 3

You only have one option for a pure-CSS dropdown menu that works with iOS devices: use anchor tags and toggle display: none/block (short article on iOS Safari hover behavior).

HTML:

<ul>
    <li><a href="#">Menu Item 1</a>
         <ul>
             <li>SubLink1.1</li>
             <li>SubLink1.2</li>
             <li>SubLink1.3</li>
             <li>SubLink1.4</li>
         </ul>
    </li>
    <li><a href="#">Menu Item 2</a>
         <ul>
             <li>SubLink2.1</li>
             <li>SubLink2.2</li>
             <li><a href="#">SubMenu3 &gt;&gt;</a>
                 <ul>
                     <li><a href="#">Nested Link 2.3.1 &gt;&gt;</a>
                     <ul>
                         <li>Nested Link 2.3.1.1</li>
                         <li>Nested Link 2.3.1.2</li>
                     </ul>
                     </li>
                     <li>Nested Link 2.3.2</li>
                 </ul>
             </li>
         </ul>
    </li>
    <li><a href="#">Menu Item 3</a>
         <ul>
             <li><a href="#">SubMenu3.1 &gt;&gt;</a>
                 <ul>
                     <li>Nested Link 3.1.1</li>
                     <li>Nested Link 3.1.2</li>
                     <li>Nested Link 3.1.3</li>
                     <li>Nested Link 3.1.4</li>
                     <li>Nested Link 3.1.5</li>
                     <li>Nested Link 3.1.6</li>
                 </ul>
             </li>
             <li>SubMenu3.2</li>
         </ul>
    </li>
</ul>

CSS:

li>ul { display: none; }
li:hover>ul{
    display: block;
}

I have tested this on an iPhone 4 iOS6 and it works fine. Also tested on a Kindle Fire. I don't have access to an android phone for testing, so you want to check those devices.

JS Fiddle: http://jsfiddle.net/aGYnU/2/

Making it responsive:

Play with the styles a bit. Change the positioning. Use em or percentage% values for the dimensions. You may need to use em values for the font-sizes within the menu as well (or media queries to set font-size based on viewport size).

Functionality should continue to work.

Solution 4

I have tried to solve this issue as well. And I don't think a solution which covers all my needs is possible at all. But this will probably be good enough for most people: http://jsfiddle.net/selfthinker/T7dDm/

HTML:

<ul>
  <li class="dropdown" onclick=""><span>Menu</span>
    <ul>
      <li><a href="#">Menu item</a></li>
      <li><a href="#">Another menu item</a></li>
    </ul>
  </li>
</ul>

CSS:

li.dropdown > span {
    cursor: pointer;
    /* style the "Menu" to make it appear clickable (e.g. replace it with a house icon?) */
    font-size: 2em;
    font-weight: bold;
    color: #00c;
}
li.dropdown {
    position: relative;
}
li.dropdown:hover > ul,
li.dropdown:active > ul,
li.dropdown:focus > ul {
    display: block;
}
li.dropdown > ul {
    display: none;
    position: absolute;
    top: 1.5em;
    left: 0;
    /* and style away: */
    background-color: #ccc;
    font-size: 1.5em;
}

I have tested this on the New iPad in Safari and Opera Mini, on Android (2.2.2, HTC Desire) in the stock browser and Opera Mini and on a few desktop browsers. And it basically works everywhere. These are the remaining issues:

  1. It's not keyboard accessible, i.e. you cannot tab through the menu items. You could make the menu dropdown itself appear on tabbing, but there is no way I'm aware of (without JavaScript) which lets you access the items within. This is the biggest issue for me.
  2. In Safari on the iPad and all Opera Minis the menu won't close anymore as soon as you have tapped on it. You either need to reload or click on a link. (In the Android browser you can close the menu by just tapping anywhere else on the screen.) There might be a solution to that?
  3. In Opera Mini the whole page reloads after tapping on the menu trigger, but after that the menu is displayed normally.

Solution 5

Mobile browsers often show/hide any :hover content when tapped, if not a link. Use this code:

HTML:

<ul>
<li id="showhide">I am visible, and can be tapped/hovered.
     <ul id="menu">
          <li>Menu item 1</li>
          <li>Menu item 2</li>
     </ul>
</li>
</ul>

CSS: (no styling)

#showhide{
     position:relative;
}
#menu{
     position: absolute;
     left: -999px
}
#showhide :hover #menu{
     left: 0px;
}

See this is JSFiddle: http://jsfiddle.net/VVqBU/

Share:
13,176

Related videos on Youtube

bcosynot
Author by

bcosynot

Updated on June 07, 2022

Comments

  • bcosynot
    bcosynot almost 2 years

    I have been looking at the available responsive drop down menus/navigation bars but nothing seems to be working right. I primarily need a CSS based menu that does not rely on JavaScript hacks.

    Why not use JS? JS based solutions fail to work on proxy browsers like Opera Mini, a majority of our audience uses that, and Blackberry browsers don't show work that well with JS.

    A lot of people advocate the use of select menus for mobile navigation. An interesting solution, but this is again dependent on JS and is very tedious for nested multi level menus.

    So then, what navigation systems have you come across that might work for you?

    • Mousey
      Mousey over 8 years
      this answer has a pure CSS responsive menu and works well in all sizes stackoverflow.com/a/32470745/4258817 - demo link is in the answer for testing before you decide
  • cimmanon
    cimmanon over 11 years
    I can confirm that :hover styles will display via tap in Opera Mobile (emulator) and Android (emulator), but another user on another question claimed this is not the case for iPhone.
  • Anders Arpi
    Anders Arpi over 11 years
    This is a neat solution, but I question the longevity of it. It's not standardized behaviour and is apt to change with new browsers, phones etc.
  • Chi-chi
    Chi-chi over 11 years
    @chovy: True, the classes aren't necessary, the functionality works fine without them. I've edited my sample code to reflect this. However, they do help make the style sheets easier to read when you have nested menus and each menu has different properties. Without classes, this can get ugly: JS Fiddle
  • Mooseman
    Mooseman over 11 years
    Perhaps in the future there may be a CSS selector specifically for this purpose. At the moment, this works in Mobile Safari (iOS 6.0).