CSS Recursive Menu display sub menu on hover - css

I have created a recursive menu in angular using ngtemplates.
I want to make menu which displays the sub menu on hover. However, I am having trouble when I exit hover of the main menu, the sub menu disappears.
Here is a sample code structure I was generating.
a+ul {
display: none;
}
a:hover+ul {
display: block
}
<ul>
<li>
<a>a</a>
<ul>
<li>
<a>b</a>
<ul>
<li><a>c</a></li>
</ul>
</li>
</ul>
</li>
</ul>

The problem here is that once you start hovering over the c Text you no longer hover over the a. So a:hover + ul isn't valid anymore and the ul disappears. To solve this you can put the ul inside a wrapper and adapt the selectors and html like this:
.menu-wrapper>ul {
display: none;
}
.menu-wrapper:hover>ul {
display: block
}
<ul>
<li>
<div class="menu-wrapper">
<a>a</a>
<ul>
<li>
<div class="menu-wrapper">
<a>a</a>
<ul>
<li><a>c</a></li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>

Try the below piece of code for the expected output:
a+ul {
display: none;
}
a:hover+ul {
display: block
}
#menu a {
display: block;
text-decoration: none;
}
#menu:hover ul,
#menu:hover ul li:hover ul,
#menu:hover ul li:hover ul li:hover ul {
display: block;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="menu">
<ul>
<li>
a
<ul>
<li>
b
<ul>
<li>c</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>

<!DOCTYPE html>
<html>
<head>
<style>
nav li {
cursor: pointer;
position: relative;
width: 8vw;
}
nav > ul > li {
position: relative;
display: block;
}
nav > ul > li ul {
position: absolute;
display: none;
}
nav > ul li:hover > ul {
position: absolute;
display: block;
}
nav > ul > li > ul li:hover > ul {
position: absolute;
display: block;
}
</style>
</head>
<body>
<nav>
<ul >
<li>
<a>a</a>
<ul>
<li><a>b</a>
<ul>
<li><a>c</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</body>
</html>

Related

Sub-menu displays content on hover over of main menu element

I'm trying to learn to build a drop-down menu for a navigation bar. I want a main element that says Music, then 2 sub menus called Songs, and Albums, then I'd like a list of links(songs, albums) to appear on hover. When I hover over my main element however, all sub content of my elements are also displaying, and I'd like to stop this from happening, until the sub-menu(Albums, or Songs) is hovered over.
I've tried flipping some things around in CSS, tried every combo I can come up with. I'm assuming I'm missing something.
HTML
nav ul ul li li {
display: none;
background-color: yellow;
}
nav ul ul:hover li li {
display: block;
}
nav ul ul li {
display: none;
background-color: red;
}
nav ul {
position: relative;
background-color: pink;
}
nav ul :hover li {
display: block;
}
<div class="wrapper">
<nav>
<ul>
<li>Music
<ul>
<li>Songs
<ul>
<li> Blue slide park</li>
<li>Albums
<ul>
<li>KIDS</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
****EDIT*****
I fixed my HTML, please just focus on CSS.
You use child combinator > to select the immediate children of the element.
nav > ul ul{
display: none;
}
nav > ul li:hover > ul{
display: block;
}
<header>
<H2>My Web Page</H2>
</header>
<body>
<div class="wrapper">
<nav>
<ul>
<li>Music
<ul>
<li>Songs
<ul>
<li>Blue side parks</li>
<li>Albums</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</body>
</html>
?
nav ul ul li li {
display: none;
background-color: yellow;
}
nav ul ul:hover li li {
display: block;
}
nav ul ul li {
display: none;
background-color: red;
}
nav ul {
position: relative;
background-color: pink;
}
nav ul :hover li {
display: block;
}
nav ul li ul li ul{
display:none;
}
nav ul li ul li:hover ul{
display:block;
}
nav ul li ul li ul li .x2{
display:none;
}
.x1:hover .x2{
display:block;
}
<header>
<H2>My Web Page</H2>
</header>
<body>
<div class="wrapper">
<nav>
<ul>
<li>Music
<ul>
<li>Songs
<ul>
<li><a
href="#"> Blue slide park</li>
<li class="x1">Albums
<ul class="x2">
<li><a
href="#">KIDS</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</body>

Css submenu not remain visible after menu unhover no javascript

I want to use only css, no javascript. When I mouse hover the top-level menu I can display the submenu, but as soon as I unhover the top-level menu the submenu disapper. How could I solve this without using javascript? Have I missed something?
I tried to use .has-children:hover + .sub-menu {display: block;} to display the submenu when I mouse hover the top-level menu, but I have no idea what I can code to keep visible the submenu.
The HTML code is:
.header ul {
list-style: none;
padding: 20px 30px;
}
.header li {
float: left;
position: relative;
}
.header li a {
padding: 20px 30px;
}
.menu {
clear: none;
float: right;
max-height: none;
}
.menu li ul {
position: absolute;
}
.sub-menu {
display: none;
}
.open-menu-link {
display: none;
}
.has-children:hover + .sub-menu {
display: block;
}
<header class="header">
<ul class="menu">
<li>Work</li>
<li>
<a class="has-children" href="#about">Haschildren</a>
<ul class="sub-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
<li>Careers</li>
<li>
<a class="has-children" href="#careers">About</a>
<ul class="sub-menu">
<li>Child 3</li>
<li>Child 4</li>
</ul>
</li>
<li>end</li>
</ul>
</header>
Add the class has-children to the li and use the li's hover event to display the submenu.
.header ul {
list-style: none;
padding: 20px 30px;
}
.header li {
float: left;
position: relative;
}
.header li a {
padding: 20px 30px;
}
.menu {
clear: none;
float: right;
max-height: none;
}
.menu li ul {
position: absolute;
}
.sub-menu {
display: none;
}
.open-menu-link {
display: none;
}
.has-children:hover .sub-menu {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="mystyle.css">
</head>
<body>
<header class="header">
<ul class="menu">
<li>Work
</li>
<li class="has-children">Haschildren
<ul class="sub-menu">
<li>Child 1
</li>
<li>Child 2
</li>
<li>Child 3
</li>
</ul>
</li>
<li>Careers
</li>
<li class="has-children">About
<ul class="sub-menu">
<li>Child 3
</li>
<li>Child 4
</li>
</ul>
</li>
<li>end
</li>
</ul>
</header>
</body>
</html>
Move you has-children class onto the li and then make your selector:
.has-children:hover > .sub-menu
Updated snippet:
.header ul {
list-style: none;
padding: 20px 30px;
}
.header li {
float: left;
position: relative;
}
.header li a {
padding: 20px 30px;
}
.menu {
clear: none;
float: right;
max-height: none;
}
.menu li ul {
position: absolute;
}
.sub-menu {
display: none;
}
.open-menu-link {
display: none;
}
.has-children:hover > .sub-menu {
display: block;
}
<header class="header">
<ul class="menu">
<li>Work</li>
<li class="has-children">
Haschildren
<ul class="sub-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
<li>Careers</li>
<li class="has-children">
About
<ul class="sub-menu">
<li>Child 3</li>
<li>Child 4</li>
</ul>
</li>
<li>end</li>
</ul>
</header>

Can't get the hover in my menu bar to work

I can't get the hover in my menubar to work. The html and css is below. I can get the display: none to work by itself. I can get the hover to work by itself. They just won't work together. Not sure what I am doing wrong.
This is the html:
<nav>
<ul>
<li><img class="mainbar"src="images/logov6v2.png" width="175" height="150" padding="0" text-align="center" vertical-align="text-top">
<li id="menudrop" class="rightbar">Menu</li>
<ul data-toggle="">
<li>Account Settings</li>
<li>About Us</li>
<li>Contact</li>
</ul>
</li>
</ul>
</nav>
This is the css:
#menudrop.rightbar ul li a {
color: red;
display: block;
text-decoration: none;
}
nav ul li ul {
display: none ;
background: #5f6975;
position: relative;
top:100%;
}
nav ul li ul:hover li {
display: block;
}
Besides fixing some missing closing tags the main adjustment is to change this
nav ul li ul:hover li {
display: block;
}
into that
nav ul li:hover ul {
display: block;
}
As the nav ul li ul ist set to display:none; it's not possible to set a hover on it.
Adjusted in Fiddle
And without the image:
#menudrop.rightbar ul li a {
color: red;
display: block;
text-decoration: none;
}
nav ul li ul {
display: none;
background: #5f6975;
position: relative;
top:100%;
}
nav ul li:hover ul {
display: block;
}
<nav>
<ul>
<li id="menudrop" class="rightbar">Menu
<ul data-toggle="">
<li>Account Settings
</li>
<li>About Us
</li>
<li>Contact
</li>
</ul>
</li>
</ul>
</nav>

trying to create a css column sub menu

So I'm trying to create a css menu, where the children are in a column format. But I cannot seem to get the child li's to float, displaying their ul's underneath them. I can't seem to get the parent ul to be the width of the child, it seems to want to remain the width of the parent (I hope this is making sense).
Here's the HTML:
<div class="header">
<ul class="nav menu">
<li class="item-101 current active">Home</li>
<li class="item-112 deeper parent">Accommodation
<ul class="nav-child unstyled small">
<li class="item-161 deeper parent">Property Type
<ul class="nav-child unstyled small">
<li class="item-149">Apartments</li>
<li class="item-150">Suites</li>
<li class="item-151">Penthouses</li>
</ul>
</li>
<li class="item-179 deeper parent">Information
<ul class="nav-child unstyled small">
<li class="item-152">Inclusions</li>
<li class="item-162">Gallery</li>
</ul>
</li>
</ul>
</li>
<li class="item-113">Contact</li>
</ul>
</div>
and the CSS:
.header ul{margin:0;padding:0;list-style:none}
.header ul li{position:relative;float:left;display:inline;margin:0;padding:0}
.header ul li > a{padding:25px 15px;font-size:20px;line-height:20px;color:#666;font-weight:800;text-transform:uppercase;display:block}
.header ul li.item-101 > a{padding-left:0}
.header ul li.active > a,
.header ul li > a:hover{color:#1a2440}
.header ul li > ul{position:absolute;left:-9999em;width:auto;min-width:100%;max-width:500px;background:rgb(255,255,255);background:rgba(255,255,255,0.95);border:solid 1px #eaeaea}
.header ul li > ul li{float:left;display:inline-block;background:#f0f}
.header ul li > ul li:last-child{border-bottom:none}
.header ul li > ul li > a{padding:13px 15px;margin:0;font-size:16px;line-height:16px;color:#006699;font-weight:800;text-transform:uppercase;background:none;display:block;white-space:nowrap}
.header ul li > ul li.active > a,
.header ul li > ul li > a:hover{color:#009fe3}
.header ul li > ul li > ul{position:relative;float:none;display:block;top:0;left:0;background:none;border:none}
.header ul li > ul li > ul li{float:none;display:block;top:0;left:0;border-top:solid 1px #d7d7d7;background:#f9f}
.header ul li.parent:hover > a{color:#1a2440}
.header ul li.parent:hover > ul{left:0}
I've created a jsfiddle of what I've currently got, but I want the children of the Accommodation drop down to behave like columns. Which it's currently not doing. Any help would be appreciated!
Here you go.
WORKING SOLUTION
The HTML:
<div class="header">
<ul class="nav menu">
<li class="item-101 current active">Home</li>
<li class="item-112 deeper parent">Accommodation
<ul class="nav-child unstyled small">
<li class="item-161 deeper parent">Property Type
<ul class="nav-child unstyled small">
<li class="item-149">Apartments</li>
<li class="item-150">Suites</li>
<li class="item-151">Penthouses</li>
</ul>
</li>
<li class="item-179 deeper parent">Information
<ul class="nav-child unstyled small">
<li class="item-152">Inclusions</li>
<li class="item-162">Gallery</li>
</ul>
</li>
</ul>
</li>
<li class="item-113">Contact</li>
</ul>
</div>
The CSS:
.header ul{margin:0;padding:0;list-style:none}
.header ul li{position:relative;float:left;display:inline;margin:0;padding:0}
.header ul li > a{padding:25px 15px;font-size:20px;line-height:20px;color:#666;font-weight:800;text-transform:uppercase;display:block}
.header ul li.item-101 > a{padding-left:0}
.header ul li.active > a,
.header ul li > a:hover{color:#1a2440}
.header ul li > ul{position:absolute;left:-9999em;width:auto;min-width:100%;max-width:500px;background:rgb(255,255,255);background:rgba(255,255,255,0.95);border:solid 1px #eaeaea}
.header ul li > ul li{float:left;display:inline-block;background:#f0f}
.header ul li > ul li:last-child{border-bottom:none}
.header ul li > ul li > a{padding:13px 15px;margin:0;font-size:16px;line-height:16px;color:#006699;font-weight:800;text-transform:uppercase;background:none;display:block;white-space:nowrap}
.header ul li > ul li.active > a,
.header ul li > ul li > a:hover{color:#009fe3}
.header ul li > ul li > ul{position:relative;float:none;display:block;top:0;left:0;background:none;border:none}
.header ul li > ul li > ul li{float:none;display:block;top:0;left:0;border-top:solid 1px #d7d7d7;background:#f9f}
.header ul li.parent:hover > a{color:#1a2440}
.header ul li.parent:hover > ul{left:0}
.header ul li > ul {
background: none repeat scroll 0 0 rgba(255, 255, 255, 0.95);
border: 1px solid #EAEAEA;
left: -9999em;
max-width: 1010px;
min-width: 356px;
position: absolute;
width: auto;
}
.header ul li > ul li {
background: none repeat scroll 0 0 #FF00FF;
display: inline-block;
float: left;
width: 178px;
}
.header ul li > ul li {
background: none repeat scroll 0 0 #FF00FF;
display: inline-block;
float: left;
width: 178px;
}
Hope this helps.
EDIT
To work with dynamic width, here is the WORKING SOLUTION
here I make a menu with a submenu with all columns that you want ;)
HTML
<ul id="wrap">
<li>
Menu Item
<div class="subwrap">
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
</div>
</li>
<li>
Menu Item
<div class="subwrap">
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
</div>
</li>
CSS
#wrap {
min-width: 200px;
background-color: yellow;
}
#wrap > li {
float: left;
display: block;
background-color: orange;
margin-left: 20px;
}
#wrap li:hover .subwrap {
display: block;
}
#wrap li .subwrap {
display: none;
height: 200px;
background-color: pink;
position: absolute;
}
#wrap li .subwrap ul {
float: left;
margin-left: 20px;
padding: 0;
}
#wrap li .subwrap ul:first-child {
margin-left: 0;
}
#wrap li .subwrap ul li {
display: block;
float: none;
}
Example: http://jsfiddle.net/Hendrymc/8D5T4/

CSS horizontal menu not clearing because I need postion absolute

EDIT: in theory i think i could accomplish this by having a dummy ul between the 2 level and then positioning the 'second (now 3rd) level. Crude proof of concept > http://jsfiddle.net/petergus/jk7vU/
I have a horizontal dropdown menu that I am trying to get to stretch its parent div height.
The problem I run into is the child ul. In order to get it to sit on a line below the main menu I have to use position: absolute but that takes it out of the flow.
Is it even possible to have a multilevel horizontal list without set container height?
EDIT: Here is an illustration screenshot of what i am trying to accomplish. EXCEPT the content (black text behind) should slide down.
Here is how the content slides down >
as far as i can tell this is simple a problem of position: relative vs absolute
Please see a sample setup at http://jsfiddle.net/petergus/nC32t/
HTML:
<div class="mnavwrapper">
<div id="mnav">
<ul class="menu clearfix">
<li class="first expanded">
<span title="" class="nolink">Click me here</span>
<ul class="submenu clearfix">
<li class="first leaf">consultancy</li>
<li class="leaf">daylight</li>
<li class="leaf">solutions</li>
<li class="leaf">design</li>
<li class="leaf">something</li>
<li class="last leaf">team</li>
</ul>
</li>
<li class="expanded"><span title="" class="nolink">portfolio</span>
<ul class="submenu clearfix">
<li class="first leaf">all projects</li>
<li class="leaf">commercial</li>
<li class="leaf">public</li>
<li class="leaf">private</li>
<li class="leaf">something</li>
</ul>
</li>
<li class="expanded"><span title="" class="nolink">another</span>
<ul class="submenu clearfix">
<li class="first leaf">techniques </li>
<li class="last leaf">influences</li>
</ul>
</li>
</ul>
</div>
</div>
<div id="contentbody">
<p>Hello text</p>
</div>
​CSS:
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}
ul.menu {
/*display: inline-block;*/
list-style: none;
clear: both;
width: 100%;
display: block;
position:relative;
}
ul.menu li {
/*float: left;*/
padding: 0px 10px;
display: inline;
}
ul.menu li {
float: left;
}
ul.submenu {
list-style: none;
position: absolute;
width: 100%;
}
ul.submenu li {
float: left;
}
.mnavwrapper {
/*clear: both;*/
}
#mnav {
background: lightblue;
/*float: left;*/
width: 100%;
}
#contentbody {
background: pink;
}
p {
padding: 0px;
margin: 0px;
}
​jQuery:
$('.active-trail').addClass('selected');
$('ul.menu .nolink').click(function() {
$(this).parent().toggleClass('selected').end().next('ul').slideToggle().parent().siblings('li').find('ul').slideUp(150).parent().removeClass('selected');
});​
I think this is what you want:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8"
http-equiv="Content-Type" />
<title>test doc</title>
<style type="text/css">
ul {
display: table;
padding: 0;
}
li {
display: inline-block;
white-space: nowrap;
width: 13em;
}
li li {
display: none;
width: auto;
}
li:hover li {
display: inline-block;
}
</style>
</head>
<body>
<p>dfhg</p>
<ul>
<li>Hover here for sub-menu
<ul>
<li>daylight</li>
<li>solutions</li>
<li>design</li>
<li>something</li>
<li>team</li>
</ul>
</li>
<li>Yet another sub-menu
<ul>
<li>daylight</li>
<li>solutions</li>
<li>design</li>
<li>something</li>
<li>team</li>
</ul>
</li>
</ul>
<p>Hello text</p>
</body>
</html>
cheers,
gary
something like this?: http://jsfiddle.net/chanckjh/DDeRT/
html:
<div class="nav">
<ul>
<li class="nav1">nav
<ul>
<li>sub</li>
<li>sub</li>
<li>sub</li>
<li>sub</li>
</ul>
</li>
<li class="nav2">nav2
<ul>
<li>sub</li>
<li>sub</li>
<li>sub</li>
<li>sub</li>
</ul>
</li>
</ul>
</div>​
css:
.nav > ul >li{
display: inline;
position: absolute;
}
.nav1{
left: 50px;
}
.nav2{
left: 100px;
}
.nav > ul >li > ul > li{
display: none;
}
.nav > ul >li:hover > ul > li{
display: inline;
}
​

Resources