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>Menu 1</li>
<li>Menu 2
<ul>
<li>Sub-Menu 1</li>
<li>Sub-Menu 2</li>
<li>Sub-Menu 3</li>
</ul>
</li>
<li>Menu 3</li>
<li>Menu 4
<ul>
<li>Sub-Menu 1</li>
<li>Sub-Menu 2</li>
<li>Sub-Menu 3
<ul>
<li>Sub-Menu 4</li>
<li>Sub-Menu 5</li>
<li>Sub-Menu 6</li>
</ul>
</li>
</ul>
</li>
<li>Menu 5</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
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
}
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.
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.
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.
Related
I've a code snippet of a vertical fly-out-menu and would like to avoid the top gap of the sub-menus.
I made some progress with float, position and top but got lost in some dirty code.
That's the desired result:
What's a good/best/common practice to solve the problem? Thanks in advance!
/* Define the body style */
body {
font-family:Arial;
font-size:12px;
}
/* We remove the margin, padding, and list style of UL and LI components */
#menuwrapper ul, #menuwrapper ul li{
margin:0;
padding:0;
list-style:none;
}
/* We apply background color and border bottom white and width to 150px */
#menuwrapper ul li{
background-color:#7f95db;
border-bottom:solid 1px white;
width:150px;
cursor:pointer;
}
/* We apply the background hover color when user hover the mouse over of the li component */
#menuwrapper ul li:hover{
background-color:#6679e9;
position:relative;
}
/* We apply the link style */
#menuwrapper ul li a{
padding:5px 15px;
color:#ffffff;
display:inline-block;
text-decoration:none;
}
/**** SECOND LEVEL MENU ****/
/* We make the position to absolute for flyout menu and hidden the ul until the user hover the parent li item */
#menuwrapper ul li ul{
position:absolute;
display:none;
}
/* When user has hovered the li item, we show the ul list by applying display:block, note: 150px is the individual menu width. */
#menuwrapper ul li:hover ul{
left:150px;
top:0px;
display:block;
}
/* we apply different background color to 2nd level menu items*/
#menuwrapper ul li ul li{
background-color:#cae25a;
}
/* We change the background color for the level 2 submenu when hovering the menu */
#menuwrapper ul li:hover ul li:hover{
background-color:#b1b536;
}
/* We style the color of level 2 links */
#menuwrapper ul li ul li a{
color:#454444;
display:inline-block;
width:120px;
}
/**** THIRD LEVEL MENU ****/
/* We need to hide the 3rd menu, when hovering the first level menu */
#menuwrapper ul li:hover ul li ul{
position:absolute;
display:none;
}
/* We show the third level menu only when they hover the second level menu parent */
#menuwrapper ul li:hover ul li:hover ul{
display:block;
left:150px;
top:0;
}
/* We change the background color for the level 3 submenu*/
#menuwrapper ul li:hover ul li:hover ul li{
background:#86d3fa;
}
/* We change the background color for the level 3 submenu when hovering the menu */
#menuwrapper ul li:hover ul li:hover ul li:hover{
background:#358ebc;
}
/* We change the level 3 link color */
#menuwrapper ul li:hover ul li:hover ul li a{
color:#ffffff;
}
/* Clear float */
.clear{
clear:both;
}
<div id="menuwrapper">
<ul>
<li>Home</li>
<li>Products
<ul>
<li>Product 1
<ul>
<li>Sub Product 1</li>
<li>Sub Product 2</li>
<li>Sub Product 3</li>
</ul>
</li>
<li>Product 2</li>
<li>Product 3</li>
</ul>
</li>
<li>About Us
<ul>
<li>Faqs</li>
<li>Contact Us</li>
<li>Where are we?</li>
</ul>
</li>
<li>Help
</ul>
</div>
How does this look:
https://jsfiddle.net/tobyl/um02Loxc/1/
Relevant code:
#menuwrapper ul {
position: relative;
}
And:
/* We apply the background hover color when user hover the mouse over of the li component */
#menuwrapper ul li:hover{
background-color:#6679e9;
}
say body margin is 0
body{
margin:0;
}
In the below it's a menu with dropdown submenus.
In Chrome the sub-menus are appearing below the menu, but in Firefox and IE they are always appearing below the first item.
If I change the 'float: none' to 'float: left' it works and they appear below the menu, but all the sub-menu items become inline and flow one after the other.
Is there an easy fix (rather than modifying the html as this is generated from an xml file on the server - but I can modify if need be) in css?
Thanks.
<html>
<head>
<style>
#cat_nav li > ul { display: none; }
#cat_nav ul{list-style-type: none;}
#cat_nav ul li {float: none; position: relative} /*change float to not none and it aligns but items are inline */
#cat_nav ul li:hover > ul {display: block;}
#cat_nav ul ul {min-width: 150px;background-color:#DFDFDF;padding:4px 0 4px 0;position:absolute;}
</style>
</head><body>
<nav id="cat_nav">
<ul class="products_btn">
<li style="display: inline">
PCBS1
<ul class="dropdown">
<li> Fuzz 1-1</li>
<li> Fuzz 1-2</li>
<li> Fuzz 1-3</li>
</ul>
</li>
<li style="display: inline">
PCBS2
<ul class="dropdown">
<li> Fuzz 2-1</li>
<li> Fuzz 2-2</li>
<li> Fuzz 2-3</li>
</ul>
</li>
</ul>
</body></html>
Change the float:none to the float:left on #cat_nav ul li and add this
#cat_nav ul li li {
float:none
}
to un-float the list items within the list items (and thus appear stacked instead of inline).
You need to edit your selecting and positioning. I have made some small edits to your code with a working example tested in firefox. See below.
DEMO http://jsfiddle.net/RDQW8/1/
#cat_nav li > ul {
display: none;
}
#cat_nav ul {
list-style-type: none;
}
#cat_nav ul > li {
position: relative
}
/*change float to not none and it aligns but items are inline */
#cat_nav ul li:hover > ul {
display: inline-block;
}
#cat_nav ul ul {
min-width: 150px;
background-color:#DFDFDF;
padding:4px 0 4px 0;
top:15px;
position:absolute;
}
I have a CSS dropdown which is basically this: http://jsfiddle.net/2RgmH/
<ul id="menu">
<li><span>Example 1</span>
<ul>
<li><span>Level 2-A-1</span></li>
<li><span>Level 2-A-2</span></li>
<li><span>Example 2</span>
<ul>
<li><span>Example 3</span>
<li><span>Level 3-A-2</span></li>
<li><span>Level 3-A-3</span></li>
</ul>
</li>
<li><span>Level 2-A-4</span></li>
</ul>
</li>
<li><span>Level 1-B</span></li>
<li><span>Level 1-C</span></li>
<li><span>Level 1-D</span></li>
<li><span>Level 1-E</span></li>
</ul>
#menu > li > ul li > ul{ /* Third Level & beyond */
display:none;
background:#068;
}
#menu > li > ul li:hover > ul{
display:block;
position:absolute;
left:100%;
border-left:solid 3px #fff;
top:0;
width:auto;
}
#menu > li > ul > li ul > li{
display:block;
padding:3px 10px;
border-top:solid 3px #fff;
white-space:nowrap;
}
#menu > li > ul > li ul > li:hover > span{
color:#fff;
}
I would like Level 3 to line up with Level 2. Changing the 3rd level dropdown to position:relative almost does this, but it increases the size of the Example 2 to the size of the 3rd level menu - not good.
Where am I going wrong?
Edit:
I should have linked to the actual example, apologies. The page I'm working on is here: http://gmnscouts.org.uk/index2.php/ - it's the second menu. If you go to Counties > Activities, you will see my problem. The li stretches to accomodate the ul. This is with it set to relative. Setting it to absolute pushes the menu to the top, which is also unwanted behaviour.
Add this CSS:
ul.children li ul.children {
position: absolute;
left: 100%;
top: 0;
}
ul.children > li { position: relative; }
Through absolute positioning the third-level menu will not take up any space because it will be in its own layer.
I am trying to create a second level dropdown. I successfully created first level dropdown but bit stuck in making it level 2. Please assist me to complete it..
and also please explain me what mistake I am doing that I cant get the second level dropdown even the css part is good (I think so)
EDIT: I know there are many tutorials on dropdown css. But I want to know why this is not working.
Here is the link to jsbin
HTML
<ul id="nav">
<li>Home</li>
<li>Details
<ul id="subNav">
<li>x details<li>
<li>y details</li>
</ul></li>
<li>About Us
<ul id="xSubNav">
<li>About company
<ul>
<li>full information</li>
<li>summary</li>
</ul></li>
<li>About Author</li>
</ul></li>
</ul>
CSS
*{font-family:consolas;}
li{line-height:20px;}
ul#nav>li{float:left;width:100px;list-style:none;
cursor:hand;cursor:pointer;}
ul#nav li li
{display:none;width:150px;}
ul#nav li ul
{padding:0;margin:0;}
ul#nav>li:hover>ul>li
{display:block;}
ul#nav>li:hover{color:grey;}
ul li li{color:black;}
ul li li:hover
{color:cornflowerblue;}
ul li li:hover li /* level 2 dropdown part */
{display:block;margin-left:150px;width:300px;}
Here is solution with your code
Just add the below css:
ul ul li { position:relative;}
ul ul li ul { position:absolute; display:none; left:0px; top:0px;}
ul ul li:hover ul { display:block;}
ul#nav li li li {display:block;}
Check this working fiddle
The problem is the specificity of CSS rules. Just add #nav to the last three rules, to not get overridden by the first ones.
ul#nav li li{color:black;}
ul#nav li li:hover
{color:cornflowerblue;}
ul#nav li li:hover li
{display:block;margin-left:150px;width:300px;}
And I think some other tuning is needed, but that's the idea.
I'm getting some ugly behavior from a menu that contains nested lists.
The parent menu has some broad categories. When the user hovers over one of these list items, a child menu appears below. This is fine.
However, the child items can also have sub menus (I'll refer to these as grandchildren). These also appear on hover, but the entire child menu disappears when the user no longer hovers on the grandchild.
This is best explained with a FIDDLE
Hovering on Parent displays the 3 children. This is good.
Hovering on Child 1 displays the grandchildren. This is also
good.
But now trying to click Child 2 or Child 3 once the grandchildren under child 1 are expanded becomes clumsy. This is
very bad.
How can a decent hover effect be achieved here without this goofy behavior? (A CSS solution would be preferable.)
HTML
<div id="centeredmenu">
<ul>
<li>
<p><span>Parent</span></p>
<ul>
<li>
Child 1
<ul>
<li>grandchild 1</li>
<li>grandchild 2</li>
<li>grandchild 3</li>
</ul>
</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
</ul>
CSS
#centeredmenu ul {
clear:left;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
left:50%;
text-align:center;
}
#centeredmenu ul li {
display:block;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
right:50%;
}
#centeredmenu ul li a {
display:block;
margin:0 0 0 0px;
padding:3px 10px;
background: rgb(240,240,240);
color:#333333;
text-decoration:none;
line-height:2.3em;
border-top: 4px solid transparent;
border-right: 1px solid transparent;
border-bottom: 3px solid transparent;
border-left: 1px solid #848484;
}
/*hides the sub menu*/
#centeredmenu ul li ul li{
display: none;
}
/*displays sub menu on hover*/
#centeredmenu ul li:hover ul li {
display: block;
clear: both;
margin-left: 15px;
}
/*hides sub-sub menu*/
#centeredmenu ul li ul li ul{
display: none;
}
/*displays sub-sub menu on hover*/
#centeredmenu ul li ul li:hover ul {
display: block;
clear: both;
margin-left: 15px;
}
The markup structure of nested lists looks fine.
Using absolute positions on the nested ULs and the z-index tweaks you mentioned should do it.
This CSS only demo looks relevant:
http://line25.com/wp-content/uploads/2012/css-menu/demo/index.html
The problem is that when you mouse out of child1 onto child2, child1 collapses and moves child2 out from under the mouse cursor. You need to absolutely position the grandchildren so they aren't contained within the children.