1

Ive got a 3 leve dropdown menu and the 3rd level sub-menu displays next to the 2nd level menu item like it should, except for a gap. The 2nd level is set to a width of 100px so I've absolutely positioned the 3rd level to top:0, left:100px so it displays to the right of the 2nd level, but there's a gap. If I change left:100px to left:97px there is no gap. Why is this?

The HTML:

<nav>
<ul>
    <li><a href="#">Menu 1</a></li>
    <li><a href="#">Menu 2</a>
        <ul>
            <li><a href="#">Sub-Menu 1</a></li>
            <li><a href="#">Sub-Menu 2</a></li>
            <li><a href="#">Sub-Menu 3</a></li>
        </ul>
    </li>
    <li><a href="#">Menu 3</a></li>
    <li><a href="#">Menu 4</a>
        <ul>
            <li><a href="#">Sub-Menu 1</a></li>
            <li><a href="#">Sub-Menu 2</a></li>
            <li><a href="#">Sub-Menu 3</a>
                <ul>
                    <li><a href="#">Sub-Menu 4</a></li>
                    <li><a href="#">Sub-Menu 5</a></li>
                    <li><a href="#">Sub-Menu 6</a></li>
                </ul>
            </li>
        </ul>
    </li>
    <li><a href="#">Menu 5</a></li>
</ul>
</nav>

The CSS:

/* Initialise for 3 tiers */
nav ul, ul li ul, ul li ul li ul {
    margin:0;
    padding:0;
}

nav ul li, ul li ul li, ul li ul li ul li {
    list-style-type:none;
    float:left; 
}

/* Link Appearance for 3 tiers */
nav ul li a, ul li ul li a, ul li ul li ul li a {
    text-decoration:none;
    color:#fff;
    background:#666;
    padding:5px 10px;
    float:left; 
}

nav ul li a:hover, ul li ul li a:hover, ul li ul li ul li a:hover {
    background:#C00;
}

/* 2nd Tier */
nav ul li {
    position:relative;  
}

nav ul li > ul {
    display:none;
    position:absolute;
    top:30px;
    left:0;
    width:100px;    
}

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

/* 3rd Tier */ 
nav ul li ul li {
    position:relative;  
}

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

nav ul li ul li ul {
    display:none;
    position:absolute;
    top:0;
    left:100px;
}

JSFiddle

1
  • are you using chrome? Commented Feb 26, 2014 at 9:03

4 Answers 4

2

using percentage instead of pixel for this issue: try left:100% and check result

nav ul li ul li ul {
    display:none;
    position:absolute;
    top:0;
    left:100%;
}

Fiddle

also you don't need to write ul li ul li ul li a or like so.simply you can write:

ul ul ul a{
your CSS code
}
Sign up to request clarification or add additional context in comments.

2 Comments

As simple as that eh? :) Thanks!
Yeah! that's it ;) @JasonCollier
1

The issue is the gap between the menus. They need to be adjacent or even overlap for this hover trick to work.

So instead of specifying

left: 100px;

do something like

left: 100%; 
/* or even */
left: 99%; 

This will cause the 3rd layer to be adjacent to the second layer menu, or even overlap the second slightly (for 99%), allowing you to move the mouse without any interruptions that close the menu. And you won't have to worry about the width of the menus either.

Updated fiddle: http://jsfiddle.net/tqEfW/5/

If you want to keep the gap for the look of it, you can give the 3rd layer ul a padding:

nav ul li ul li ul {
    ....
    left: 100%;
    padding-left: 4px;
}

Ad demonstrated here: http://jsfiddle.net/tqEfW/9/

That said, from a UX point of view, menus with 3 layers are very hard to use and should be avoided when possible.

1 Comment

Thanks for the great info! I agree 3 layer menus should be avoided - just needed to know how in case :)
0

If you create CSS selectors like ul.first-level > li or ul.second-level > li it will only select the li that are inmediately after the ul with class first-level (or with class second-level, respectively).

In this way, without interating a lot of ul li ul li ul that can be really hard to read you can control the appearance of any complex nested list.

2 Comments

Thanks for the tip! I must admit it was doing my head in counting the ul's and li's :)
Good suggestion, although this should generally be in a comment, since it doesn't answer the question.
-1

Its looks like you know how to solve it but your question is why this is happening.

Now in your code you put the width 100px to ul. but the li didn't have nay width. now both width is not same thing. width in ul is the width of this list area. And width in li means width of each individual list item. In your case your

  ul li a
  {
   padding: 5px 10px;
  }

now the padding of a do not full the full area. and you put the background color at ul li a so the much area its covering(not sure 'cover' is the appropriate word to mention it) its showing dark in back and around 3px left so its showing white.

If you put

  ul li a
  {
   padding: 5px 10.1px;
  }

You will see the li have no gap[#123] between levels of menu.

Instead of setting the background to ul li a if you set it to ul you can see there is no gap[#123]

#123 The actual white area is not gap. The ul is 100px but text including the padding of 10px in left and right not filling the total 100px. Its filling only 97px so when you are putting the width as 97px its showing no white area. But when it is 100px this showing the background on 97px as black and the rest 3px white which looks like a gap.

3 Comments

Thanks for the explanation. So using padding to control the size of the menu item is probably not the best way if I want things to be pixel perfect. Is it better to set a width for the <li> as opposed to using padding?
You are welcome. If i am not wrong you knew that if you put the width 97px then there is no gap, means you have a solution. At the end of your question you asked "Why is this?" so instead of giving you a solution for your problem i describe the problem. So if i am not wrong this should be selected as answer so in future people can get understand why this kind of problem arise. In stackoverflow we ask and answer question not just solving our problem, also make a reference for future.
The question was not "please solve my code" The answer which is accepted do not describe the issue "WHY THE PROBLEM IS HAPPENING"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.