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.
Related
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 ran into some problem when trying to position an absolute positioned div. its working as its should i guess, however i want it to stay with parent of parent instead of parent becouse i have a dropdown list and it will follow the parent down on the side when i want it to stay in top like first li with div is displayed. ive created a jsfiddle to show the problem. http://jsfiddle.net/trptR/
can this be done using css only or is Javascript a must?
HTML
<div id="navmenu">
<ul>
<li>example
<ul>
<li>sub example1</li>
<li>sub example2</li>
<li>sub example3</li>
<li>sub example4</li>
</ul>
</li>
<li>Test
<ul>
<li>Sub Test 1
<div>
<ul>
<li>Projekt</li>
</ul>
</div>
</li>
<li>Sub Test 2
<div>
<ul>
<li>Projekt</li>
</ul>
</div>
</li>
</ul>
</li>
</ul>
</div>
CSS
#navmenu{
display:inline-block;
background:red;
}
#navmenu ul{
list-style:none;
margin:0;
padding:0;
}
#navmenu ul li{
float:left;
position:relative;
display:block;
padding:0.5em;
}
#navmenu ul li ul{
position:absolute;
display:none;
border:solid 1px #333;
background:#fff;
}
#navmenu ul li:hover ul{
display:inline-block;
}
#navmenu ul li ul li{
float:none;
display:block;
position:relative;
}
#navmenu ul li ul li:hover{
background-color:#EBEBEB;
}
#navmenu ul li ul li div{
display:none;
width:10em;
height:14.6em;
background:blue;
position:absolute;
top:0;
left:6em;
border:solid 1px #000;
}
#navmenu ul li ul li:hover div{
display:block;
}
Could you remove position:relative from both your #navmenu ul li style set and from you #navmenu ul li ul li style set?
http://jsbin.com/ziqov/1/edit
Positioning is key
I'm not sure I understand the explanation of your problem, but I do think I understand when you say you have
parentElementTop > parentElementBelow > element
that you want element to be aligned to parentElementTop rather than the parentElementBelow.
To align element absolutely to parentElementTop all you need to do in CSS is to not set position to relative or absolute on the intermediate parentElementBelow and any subsequent absolutely positioned element will be aligned according to last non-statically positioned ancestor. In your case that would be the parentElementTop which is what you want.
think about using
#navmenu > ul > li{
float:left;
position:relative;
display:block;
padding:0.5em;
cursor:pointer;
}
because otherwise your selectors overwrite each other.
I got a css menu with 3 levels. You can see my actual code right here http://jsfiddle.net/7rMgu/
As you can see, my secondary level don't keep the light blue background when navigating in the 3rd level. I've looked over the website for similar thread but I just found similar problems with only 2 levels. Also, can someone explain when I should use the '>' in css as I'm a bit confused.
CSS
html{height:100%;background-color:#0d497d;}
body{width:100%;height:100%;margin:0px;padding:0px;color:#575757;font:0.75em "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif;}
div.menuAdmin ul{margin:0;padding:0;float:right;height:100%;}
div.menuAdmin ul li{display:block;float:left;height:23px;margin-bottom:0;}
div.menuAdmin ul li a{color:#fff;padding:0.1em 0.3em 0.2em 0.3em;text-decoration:none;font-size:12px;display:block;margin:0.85em 0em 0em 0em;width:130px;background-color: #0d497d;border:1px solid #78B9EF;border-radius:5px;}
div.menuAdmin ul li:hover a{color:#000;border-radius:5px;background-color:#78B9EF;}
div.menuAdmin ul li ul{display:none;}
div.menuAdmin ul li:hover > ul {display:block;height:20px;width:139px;position:absolute;margin:0;}
div.menuAdmin ul li:hover > ul li a {line-height: 20px;color:#fff;text-decoration: none;margin: 0;padding-bottom: 0.1em;background-color: #0d497d;border:1px solid #78B9EF;border-radius:5px;}
div.menuAdmin ul li:hover > ul li a:hover {color:#000;text-decoration:none;text-shadow:none;background-color: #78B9EF;}
div.menuAdmin ul ul li:hover > ul {display:block;position:absolute;left:100%;top:0;width:139px;}
div.menuAdmin ul > ul > ul li:hover > a {color:#444;background-color:#78B9EF;}
HTML
<div class='menuAdmin'>
<ul>
<li>
<a href=''>A</a>
<ul>
<li>
<a href=''>1</a>
<ul>
<li>
<a href=''>A1</a>
</li>
<li>
<a href=''>A2</a>
</li>
<li>
<a href=''>A3</a>
</li>
<li>
<a href=''>A4</a>
</li>
</ul>
</li>
<li>
<a href=''>2</a>
</li>
<li>
<a href=''>3</a>
</li>
<li>
<a href=''>4</a>
</li>
</ul>
</li>
<li>
<a href=''>B</a>
</li>
<li>
<a href=''>C</a>
</li>
<li>
<a href=''>D</a>
</li>
</ul>
</div>
Thanks
To keep the :hover effect you need to make the change on hover the li element not just the a tag, so you have this:
div.menuAdmin ul li:hover > ul li a:hover
Must be:
div.menuAdmin ul li:hover > ul li:hover > a
With the hover on the li element keeps the effect since the ul wich is the submenu is part of the li.
Check the Demo http://jsfiddle.net/7rMgu/1/.
Now your second question when use this >; when you only want to affect the direct children, it let you avoid the same style on nested elements. An example with the same selector I have fix, if you remove the last > check what happen:
http://jsfiddle.net/7rMgu/3/
It changes all a inside the li even if are inside some nested elements.
Here is an updated fiddle:
http://jsfiddle.net/ryanwheale/7rMgu/2/
Essentially, you always want the :hover selector to be on the LI. You had it on the A.
Also, the > selector in CSS means "direct children"... best explained by example:
<div class="my-div">
<p>This should be blue</p>
<div>
<p>This should be green</p>
</div>
</div>
and this css:
.my-div p { color: green }
.my-div > p { color: blue }
You have a few redundant rules, I've tried to boil it down for you:
.menuAdmin ul{ /* all lists */
margin:0;
padding:0;
list-style: none;
}
.menuAdmin li { /* all list items */
margin:0;
padding:0;
}
.menuAdmin > ul { /* first level list*/
float: right;
}
.menuAdmin > ul > li { /* first level list items*/
float: left;
}
.menuAdmin ul ul { /* second and third level list */
position: absolute; /* remove from flow */
display: none; /* hide by default */
}
.menuAdmin ul ul ul { /* third level list */
top: 0;
left: 100%;
}
.menuAdmin li:hover > ul { /* first level list inside of a hovered item */
display: block;
}
.menuAdmin a { /* all links */
color:#fff;
padding:0.1em 0.3em 0.2em 0.3em;
text-decoration:none;
font-size:12px;
display:block;
width:130px;
background-color: #0d497d;
border:1px solid #78B9EF;
border-radius:5px;
}
.menuAdmin li:hover > a { /* links inside hovered list item */
color:#000;
background-color:#78B9EF;
}
As already answered, > means "child" (a.k.a. direct descendant)
See demo at http://jsfiddle.net/7rMgu/5/
Original Question
I have a webpage with a css menu. The problem is that the menu is displaying properly except for menu items wit a submenu. I this case the menu items not displaying consistently and the the submenu is not showing at all.
I have uploaded the page at http://prova.webuda.com/account.html. Such a problem occurs with the menu item ACCOUNT.
Also, I have looked at it with firebug and I have seen that the relavant submenu unsorted list is grayed out, which makes me suppose that there must be some parsing issue. However, from my analysis it should be fine.
What am I doing wrong? Can somebody please help me?
Edit
Css
#mainMenu
{
font-size: 0.85em;
}
#mainMenu ul
{
margin: 0;
padding: 0;
text-transform: uppercase;
}
#mainMenu ul li, #mainMenu ul li:hover
{
height:50px;
float:left;
text-align:center;
font-weight:bold;
font-size:1.7em;
overflow:hidden;
margin-left:1.05em;
margin-right:1.05em;
}
#mainMenu ul li a, #mainMenu ul li span a
{
color:brown;
text-decoration:none;
color:#006;
}
.mainSubMenu
{display:none;}
#mainMenu ul li:hover #mainMenu ul li ul{display:block;}
#mainMenu ul li ul{position: absolute;left:-1px;top:98%;}
#mainMenu ul ul ul{position: absolute;left:98%;top:-2px;}
#mainMenu ul ul{
width:119.7px;
}
Html
<div class="mainMenu" id="mainMenu">
<ul>
<li class="menuItem" id="menuItem1"> Squadra </li>
<li class="menuItem" id="menuItem2"> Biglietti </li>
<li class="menuItem" id="menuItem3"> Abbonamenti </li>
<li class="menuItem" id="menuItem4"> Ritiro </li>
<li class="menuItem" id="menuItem5"> Fidelity Card </li>
<li class="menuItem" id="menuItem7"> <span> Account </span>
<ul class="mainSubMenu">
<li class="subMenuItem"><a class="pureCssMenui" href="profilo.html">Profilo</a></li>
<li class="subMenuItem"><a class="pureCssMenui" href="datiFatturazione.html">Dati Fatturazione</a></li>
<li class="subMenuItem"><a class="pureCssMenui" href="storicoTifoso.html">Storico Tifoso</a></li>
<li class="subMenuItem"><a class="pureCssMenui" href="esci.html">Esci</a></li>
</ul>
</li>
</ul>
</div>
Most significantly the part which is not working is #mainMenu ul li:hover #mainMenu ul li ul{display:block;}
There are a few issues with your CSS. First, the # selector only works for elements that have the id set to that. For example, #menuItem applies styling to any element with id="menuItem". However, your HTML has class="menuItem", so you must use the . selector instead.
Second, when the menu does appear, it appears too far down the page for the user to see, as per #mainMenu ul li ul{position: absolute;left:-1px;top:98%;} and #mainMenu ul ul ul{position: absolute;left:98%;top:-2px;}.
Here are the corrections:
.mainMenu
{
font-size: 0.85em;
}
.mainMenu
{
margin: 0;
padding: 0;
text-transform: uppercase;
}
.mainMenu ul li, .mainMenu ul li:hover
{
height:50px;
float:left;
text-align:center;
font-weight:bold;
overflow:hidden;
margin-left:1.05em;
margin-right:1.05em;
}
.mainMenu ul li a, .mainMenu ul li span a
{
color:brown;
text-decoration:none;
color:.006;
}
.mainSubMenu
{display:none;}
.mainMenu:hover .mainSubMenu {display:block}
.mainMenu ul li ul{position: absolute;left:1px;top:2%;}
.mainMenu ul ul ul{position: absolute;left:2%;top:2px;}
.mainMenu ul ul{
width:119.7px;
}
And a working fiddle: http://jsfiddle.net/Af7SE/
Also, here is another example of a menu like yours.
The first problem is because your last <a> is nested on a <span>, try using:
<li class="menuItem" id="menuItem7">
Account
<ul class="mainSubMenu">
....
</ul>
</li>
And your menu never show because has a problem with the overflow:hidden; and the static width on your submenu, try using the next code, it will show your submenu but you will need make more changes.
#mainMenu ul li:hover ul{display:block;}
instead of
#mainMenu ul li:hover #mainMenu ul li ul{display:block;}
remove all the overflow:hidden because it hide your submenu, I make some modifications for the example:
http://jsfiddle.net/NrA8A/
#mainMenu ul {
margin: 0;
padding: 0;
text-transform: uppercase;
list-style: none; /*remove the bullets*/
}
#mainMenu ul li, #mainMenu ul li:hover {
.....
/*Remove the overflow :hidden*/
}
I have a menu structure like this :
<ul class"menu">
<li>
<a>item1</a>
<ul>
<li><a>subitem1</a></li>
<li><a>subitem2</a></li>
<li><a>subitem3</a></li>
<li><a>subitem4</a></li>
<li>
<a>item2</a>
<ul class="sub-ul-2">
<li><a>subitem5</a></li>
<li><a>subitem6</a></li>
<li><a>subitem7</a></li>
<li><a>subitem8</a></li>
</ul>
</li>
</ul>
</li>
</ul>
My requirement is, when I hover on item1 then subitem1,subitem2,subitem3,subitem4 only need to display and subitem5 - 8 no need to display.
When I hover on item2, then only subitem5 - 8 need to display. How can I achieve this by using css?
I have tried:
ul.menu ul{
display: none;
}
ul.menu li:hover:first-child ul {
display:block;
}
HTML
<ul class="menu">
<li>
item1
<ul>
<li>subitem1</li>
<li>subitem2</li>
<li>subitem3</li>
<li>subitem4</li>
<li>
item2
<ul>
<li>subitem5</li>
<li>subitem6</li>
<li>subitem7</li>
<li>subitem8</li>
</ul>
</li>
</ul>
</li>
</ul>
CSS
.menu li > ul {
display:none;
}
.menu li:hover > ul {
display:block;
}
LIVE
Something like this? (Without changing your html)
CSS:
ul li ul {display:none;}
ul > li:hover ul{display:block;}
ul li ul > li > ul.sub-ul-2 {display:none;}
ul > li:hover ul > li:hover ul{display:block;}
DEMO 1
Update: (Without using any classes & cursos:pointer;)
ul li ul {display:none;}
ul > li:hover ul{display:block;}
ul > li > ul > li > ul > li{display:none;}
ul > li:hover ul > li:hover ul li{display:block;}
li{cursor:pointer;} /* For the hand (cursor) while hover over the li */
DEMO 2
Or the short css, after fixing the first ul from <ul class"menu"> to <ul class="menu"> (By adding the = to it)
.menu ul {display:none;}
.menu li:hover > ul{display:block;}
li{cursor:pointer;}
DEMO 3
fiddle: http://jsfiddle.net/Z22kH/
html:
<ul class="menu">
<li>
<a>item1</a>
<ul class="sub-ul-1">
<li><a>subitem1</a></li>
<li><a>subitem2</a></li>
<li><a>subitem3</a></li>
<li><a>subitem4</a></li>
<li>
<a>item2</a>
<ul class="sub-ul-2">
<li><a>subitem5</a></li>
<li><a>subitem6</a></li>
<li><a>subitem7</a></li>
<li><a>subitem8</a></li>
</ul>
</li>
</ul>
</li>
</ul>
css:
ul.menu li{
display: none;
}
ul.menu > li{
display: block;
}
ul.menu > li:hover > ul > li,
ul.menu ul > li:hover > ul > li{
display:block;
}
I've put together a working and minimalistic jsfiddle demo.
You hide all UL's inside .menu. Upon hovering any list-item, you reveal any direct descendant UL. I use display: block; and display: none; for the purpose of keeping it simple.
CSS:
/* Hide all UL's inside .menu */
.menu ul {
display: none;
}
/* Show any UL which is a direct child of a hovered list-item */
.menu li:hover > ul {
display: block;
}