problems with nested lists and hover effects - html

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.

Related

Gap filler between svg images in menu items

I have a menu that is made up of ul and li the list items nest SVGs as the items that will show up in the menu. inside the first ul, li nested another ul,li that shows up on hover as a submenu, everything works fine but I want to create a gap filler around my SVGs in the item menu so that when I hover a little bit away from the image, the sub menu would still appear.
I searched that and find some ways involved using the pseudo class ::after, but did not manage to make it work
This is my code
<div id="menu">
<ul>
<li> <img src="this is just for code"/>
<ul>
<li> link</li>
<li> link2/li>
</ul>
</li>
<li> <img src="this is just for code"/>
<ul>
<li> link</li>
<li> link</li>
</ul>
</li>
the css is
#menu ul li{
width:auto;
height:2.5em;
list-style:none;
float:left;
margin: 0em 20px 0em 20px ;
padding: 0px ;
cursor:pointer;
justify-content:space-between;
#menu ul ul li{
float:none;
width:100%;
height:auto;
padding: 1em 0;
text-align:center;
#menu ul li:hover > ul{
display:block; }
#menu ul li img{
width:inhrtit;
height:inherit;
margin: 0 0 60px 0;
position:relative;
bottom:0.6em;
}
#menu ul li:hover > ul::after{
width:auto;
height:2.5em;
padding:0px 100px;
margin: 90px;
position:absolute;
right:70px; left:90px;
pointer-events: none;
-webkit-transform: translateX(-110%);
transform: translateX(-110%);
}
#menu ul li:hover > ul::after {
pointer-events: auto;
}
Sorry my code is lousy. as the first question I hope this is not an enough dump one.
Since you're looking to increase the hover area of <li> elements, you can add padding to them.
For example, below is an example of using padding to increase the clickable area. Increasing hover area is similar.
https://jsfiddle.net/gazg1yuy/

Navigation bar with drop down not working

I'm doin' a navigation bar for a website. I created it etc. but when I go to one of the sub menu's it disappears..
here's my HTML:
<ul id="menu">
<li>Welcome</li>
<li>Review
<ul>
<li>Customer Reviews</li>
<li>Leave a Review</li>
</ul>
</li>
<li>Gallery</li>
<li>Discounts
<ul>
<li>Refer us!</li>
<li>Claim discount</li>
</ul>
</li>
<li>Send me an email!
</li>
</ul>
</nav>
and my CSS:
/* nav */
nav{
text-align:center;
}
nav a:visited{
color:black;
}
nav a{
text-decoration:none;
color:black;
}
#menu {
margin:0 auto;
display: inline-block;
list-style-type:none;
padding:0;
}
#menu li {
float: left;
position: relative;
list-style-type: none;
background:white;
border:1px solid black;
margin-left:10px;
margin-top:5px;
border-radius:4px;
}
#menu li a {
font-family:helvetica;
display:block;
padding:10px 10px;
text-decoration:none;
}
#menu li a:hover {
color:orange;
}
#menu li ul {
background: none repeat scroll 0 0 #ffffff;
margin-top:6px;
margin-right:1px;
padding: 2px;
}
/*#menu, #menu ul {
margin:0 auto;
padding: 0;
}*/
#menu li {
float: left;
position: relative;
list-style-type: none;
}
#menu > li:hover > ul {
display: block;
}
#menu > li > ul {
display: none;
position: absolute;
}
#menu li a {
white-space: nowrap;
}
and a little JSFiddle for ya: http://jsfiddle.net/nv741s01/
If you hover your mouse over a menu option [that has a sub-menu] long enough and then do it, it works, but people won't be willing to wait three seconds every time they want to visit a sub menu, so how do I resolve it so that it works as soon as you go to it?
any help would be much appreciated, thanks in advance :)
It was because there was a little gap between the sub menu and the menu, here is the fixed JSFiddle:
http://jsfiddle.net/nv741s01/3/
And here is what I changed:
#menu li ul {
background: none repeat scroll 0 0 #ffffff;
margin-top: 1px;
margin-right:1px;
padding: 2px;
}
I changed the margin-top to 1px.
The margin of an element doesn't capture hover events. Use padding instead. Make these changes:
#menu li {
float: left;
position: relative;
list-style-type: none;
background:white;
padding-left:10px;
padding-top:5px;
margin:0;
}
/* add this rule */
#menu li a {
border:1px solid black;
border-radius:4px;
}
#menu li ul {
background: none repeat scroll 0 0 #ffffff;
margin-top:0px;
margin-right:1px;
padding: 2px;
}
Fiddle: http://jsfiddle.net/nv741s01/2/
You are using margin to position the submenu away from the main item. Since margin isn't part of the actual element it doesn't trigger any hover behaviours. Instead, use padding on the child ul element, since padding is actually considered part of the child's box. This will make the hover behaviours trigger consistently when moving the mouse from parent to child.
You also describe that there's a 3 second delay somewhere - that's impossible from this code, and I cannot reproduce it obviously.
Your dropdowns are disappearing because as you move your mouse cursor down, there's a gap between the parent menu item and the child menu item.
When the mouse leaves the parent li space, it no longer applies to the hover state, and so the CSS rule is ignored, leaving the child menu hidden.
If it helps, I tend to use a combination of margins and padding, to 'bump together' the parent and child menus, to help navigation.

absolute position stay with parent of parent instead of parent

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.

CSS dropdown menu - 3rd level issue

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.

All but last child element of css menu is moved one pixel left

I'm tearing my hair out here.
I have horizontal dropdown menu on a site I am building. The menu is made up of an unordered list, with the dropdown part made up of hidden child elements that pop up when you roll over the parents.
In Firefox everything appears to be fine, but, in Chrome and Safari, while the last child element in each menu is acting as expected, all other child elements are shunted left by one pixel. So, in the example below, Child A3, Child B4, and Child C2 are aligned perfectly with their respective parents, while the rest are not.
Can someone please shed some light on what is going wrong here?
Code and screenshots below...
How it should look...
How it actually looks...
I have included the entire nav block of the CSS just in case I have missed something outside of the actual parent/child part.
HTML
<nav>
<div id="menu" class="menustrip">
<ul>
<li class="page_item">
Parent A
<ul class='children'>
<li class="page_item">Child A1</li>
<li class="page_item">Child A2</li>
<li class="page_item">Child A3</li>
</ul>
</li>
<li class="page_item">Parent B
<ul class='children'>
<li class="page_item">Child B1</li>
<li class="page_item">Child B2</li>
<li class="page_item">Child B3</li>
<li class="page_item">Child B4</li>
</ul>
</li>
<li class="page_item">Parent C
<ul class='children'>
<li class="page_item">Child C1</li>
<li class="page_item">Child C2</li>
</ul>
</li>
</ul>
</div>
</nav>
CSS
#menu, #main-nav{
width: 950px;
margin: 0 30px 0 0;
padding-right: 30px;
border-bottom-style: solid;
border-bottom-width: 8px;
border-bottom-color: #78B2E2;
text-align: right;
}
ul#main-nav{
list-style: none;
padding-top: 10px;
margin-right:30px;
}
.page_item, .navlink{
display: inline-block;
background-color: #243488;
height: 34px;
width: 110px;
margin-left: 1px;
text-align: center;
}
.page_item a, .navlink a{
padding-top: 4px;
display: block;
height: 34px;
width: 110px;
}
.page_item:hover, .navlink:hover{
background-color: #78B2E2;
}
.page_item:active, .navlink:active{
background-color: #78B2E2;
}
/* Hide Sub Menus by default */
#menu ul li ul.children {
display:none;
z-index:100;
}
/* Display Sub Menus on rollover of parent */
#menu ul li:hover ul.children {
display:block;
position:absolute;
top:205px;
margin: 0 0 0 -11px; /*pull child menus in line with parent */
width: 132px;
list-style: none;
}
/* Style sub menu items not to float like parent items */
#menu ul li ul.children li {
float:none;
width:110px;
height: 34px;
background-color:#243488;
border-top: 3px solid #ffffff;
font-size: 11px;
}
#menu ul li ul.children li:hover {
background-color:#78B2E3;
color:#243488;
}
/* Sub Menu link color */
#menu ul li ul.children li a:hover {
color:#243488;
}
#menu ul li ul.children li a {
color:#ffffff;
}
Not sure what causes it exactly, but it has to do with the fact that the list items in <ul class="children"> are inline-blocks and the ul itself is centered.
So you have two solutions: either align the ul to the left instead of centering it
.children {text-align:left;}
or, make its list items blocks instead of inline blocks.
.children > li {display:block;}
Either of those adjustments will get rid of the display anomaly. In both cases, you will also have to increase the left margin, but I'm sure that won't be a problem.
Changing .children .page_item to display:block rather than display:inline-block seemed to fix it in my Chrome. This also required a bit more margin-left to re-align things.
.children .page_item {
display:block;
margin-left:10px;
}