nested navigation menu positioning - css

I am learning CSS and trying to get a nested navigation menu working. I am able to float the main items and stack all the child elements under it, but the position relative for the child menus are not working. I intend to move the child menu items to the right relative to its parent. Please let me know where I am going wrong.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<style>
*{
margin:0;
padding:0;
}
h1{
text-align: center;
text-decoration: underline;
margin-bottom: 10px;
}
li{
list-style: none;
}
ul li a{
text-decoration: none;
display: block;
width:100px;
height: 25px;
border: 1px solid green;
text-align: center;
}
.main > li{
float:left;
position: relative;
}
.main > li > li {
position: absolute;
top:0px;
left:10px;
}
</style>
</head>
<body>
<h1>Hello Plunker!</h1>
<ul class="main">
<li>Menu 1
<ul class="sub1">
<li>Menu 1.1
<ul class="sub2">
<li>Menu 1.1.1</li>
<li>Menu 1.1.2</li>
<li>Menu 1.1.3</li>
<li>Menu 1.1.4</li>
</ul>
</li>
<li>Menu 1.2</li>
<li>Menu 1.3</li>
<li>Menu 1.4</li>
</ul>
</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
</ul>
</body>
</html>
Link to Plnkr - Plnkr Link

The primary issue is that your selector:
.main > li > li
Selects nothing.
This > means "immediate descendant". There only immediate descendant to .main > li is a ul, so the selector should read:
.main > li > ul
And, once you have that working, then you can hide the ul (under normal circumstances) and show it on hover:
.main > li > ul {
display: none;
position: absolute;
top:27px;
left:10px;
}
.main > li:hover ul {
display: block;
}
See this revised plunker
EDIT
Your question is not very clear. I just realized reviewing the code in the plunker that you also want a sub-sub menu.
I've revised the plunker, so it is correct. Basically, you also need to set the position / display of the sub-sub menu as well. Revised css below:
main > li > ul {
display: none;
position: absolute;
top:27px;
left:10px;
}
.main > li > ul > li > ul {
position: absolute;
top: 0;
left: 100%;
display: none;
}
.main > li:hover > ul,
.main > li:hover > ul > li:hover > ul {
display: block;
}
And, while we are at it, you do NOT need float: left. Float is something that has very specific, practical uses - and this isn't one of them. Change it simply to be display: inline-block, and you are set, without the other consequences of using float. (Note: with display inline-block, you may notice the nav items are spaced apart about 4px - this is due to whitespace and has a simple solution (hint: it's this answer)

Related

All nested menus show when hovering over menu instead of just the first

I have used this method to centrally align my menu: http://matthewjamestaylor.com/blog/beautiful-css-centered-menus-no-hacks-full-cross-browser-support
I am having problems though with my selectors. The selectors I am using to show the sub menu and style the links is applying to all nested tags.
I have read the + operator selects the next sibling but I've tried things like #menu-main-menu-container li:hover a + ul but it doesn't work. The hover selector is confusing me a bit.
I included the snippet below. Can someone show me how I should be just selecting the first occurrence to display when hovering over the li?
I also have a problem of the second nested submenu not aligning properly but I think that might be due to the way I have centred the menu and not sure if that is fixable or not.
Any help appreciated.
#menu-main-menu-container {
width: 100%;
position: relative;
font: 300 16px/16px Lato, Arial; }
#menu-main-menu-container ul {
position: relative;
text-align: center;
float: left;
left: 50%;
margin: 0;
padding: 0; }
#menu-main-menu-container ul ul {
position: absolute;
display: none;
margin-top: 15px; }
#menu-main-menu-container ul ul ul {
right: 0; }
#menu-main-menu-container ul li {
right: 50%;
background-color: #f4f4f4; }
#menu-main-menu-container li {
list-style: none;
position: relative;
float: left;
padding: 15px;
margin: 0;
text-transform: uppercase; }
#menu-main-menu-container li:hover ul {
display: block; }
#menu-main-menu-container a {
white-space: nowrap;
text-decoration: none;
color: blue; }
#menu-main-menu-container li:hover {
background-color: blue;
transition: 1s; }
#menu-main-menu-container li:hover a {
color: white; }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="top-nav-menu.css">
</head>
<body>
<div id="menu-main-menu-container">
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Sub Item 1
<ul>
<li>Hidden Sub Item 1</li>
<li>Hidden Sub Item 2</li>
<li>Hidden Sub Item 3</li>
</ul>
</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
</ul>
</li>
<li>Item 3</li>
</ul>
</div>
</body>
</html>
Maybe with:
#menu-main-menu-container li:hover > ul
Operator >
If you use > operator you ensure that ul must be direct child of li:hover.

PureCSS and CSS menu dropdowns

I'm trying to use PureCSS, and get menudrop downs using CSS (rather than via either YUI or Jquery for portability reasons).
This is what I have so far:
http://jsfiddle.net/ket262p3/3/
<div class="pure-menu pure-menu-open pure-menu-horizontal">
<ul>
<li class="pure-dropdown">
Test1
<ul>
<li>Test2</li>
<li class="pure-menu-separator"></li>
<li>Test3</li>
</ul>
</li>
<li class="pure-dropdown">
Test1
<ul>
<li>Test2</li>
<li>Test3</li>
<li>Test4</li>
<li>Test5</li>
</ul>
</li>
</ul>
</div>
and:
#import url("http://yui.yahooapis.com/pure/0.5.0/pure-min.css");
.pure-menu-horizontal ul {
padding:0;
margin:0;
font-weight: bold;
width: 100%;
position: relative;
}
.pure-menu-horizontal ul li {
float:left;
position: relative;
display: block;
}
.pure-menu-horizontal ul li a {
display:block;
}
.pure-menu-horizontal ul ul {
display: block;
position: absolute;
top: 58px;
}
.pure-menu-horizontal ul li:hover > ul {
display: list-item;
left: auto;
}
I think the underlying problem may be some subtly in purecss that causes the second level menu not to display.
Ignore the extra classes - they represent earlier stages of getting this to work with YUI or JQuery.
You have to set the visibility of your subnavigation to visible.
.pure-menu-horizontal ul li:hover > ul {
display: list-item;
left: auto;
visibility: visible;
}
Example:
http://jsfiddle.net/ket262p3/6/
On further investigation it appears that a lot of the infrastructure for doing this is already built into PureCSS, but not documented very well. I replicate the solution below so that other people can find it.
The main solution is documented here: https://gist.github.com/maxbeatty/7829915
I have replicated in a jsfiddle: http://jsfiddle.net/0562cqd8/1/
The html is as follows
<!-- includes pure-min.css -->
<div class="pure-menu pure-menu-open pure-menu-horizontal">
Heading
<ul class="pure-menu-children">
<li class="pure-menu-can-have-children pure-menu-selected">
Cars
<ul>
<li>
Blue
</li>
<li>
Red
</li>
<li>
Green
</li>
</ul>
</li>
<li>
Trucks
</li>
</ul>
</div>
With CSS like this:
#import url("http://yui.yahooapis.com/pure/0.5.0/pure-min.css");
.pure-menu-can-have-children:hover {
background: #eee;
}
.pure-menu-can-have-children:hover ul {
top: 35px; /* height of menu li */
left: 0;
visibility: visible;
border: 1px solid #b7b7b7;
background: #fff;
}
Please try this css
.pure-menu ul
{
margin:0;
padding:0;
float:left;
width:100%;
}
.pure-menu ul > li
{
margin:0;
padding:0;
float:left;
list-style:none;
position:relative;}
.pure-menu ul > li >a
{
margin:0;
padding:0;
float:left;
padding:8px 4px;
text-decoration:none;
color:red;}
.pure-menu ul > li > ul
{
position:absolute;
top:100%;
left:0;
display:none;
width:200px;
}
.pure-menu ul > li > ul >li
{
width:100%;
}
.pure-menu ul > li > ul >li >a
{
padding:8px 20px;
background:red;
color:#fff;}
li.pure-dropdown:hover ul {
display:block;
}
change the color as per your requirement

how do i make absolute positioned div behid it's relative positioned parent

I have this navigation menu and i want to make a part of second level menu( like 50px from its top ) go behind navigation wrap : like this photo :
<div class="main-nav-wrap wrapper">
<nav class="inner-el container main-nav">
<ul>
<li>
Menu Item 1
<ul>
<li>Menu Item 1-1</li>
<li>Menu Item 1-2</li>
<li>Menu Item 1-2</li>
</ul>
</li>
</ul>
</nav>
</div>
<!-- .main-nav-wrap -->
and here is the css :
.main-nav-wrap{
position:relative;
z-index:4;
}
.main-nav > ul > li {
float:right;
position:relative;
z-index:2;
}
.main-nav > ul > li > ul {
visibility:hidden;
opacity:0;
position:absolute;
z-index:-1;
}
.main-nav > ul > li:hover > ul {
visibility:visible;
opacity:1;
}
i'm trying to hide a part of .main-nav > ul > li > ul behind .main-nav > ul > li > ul
please help , thanks
fiddle added : http://jsfiddle.net/p91pdwLd/2/
Remove the z-index from the parent element
Here is a demo of this:
Markup
<div class="parent">
<div class="child"></div>
</div>
CSS
div {
width: 100px;
height: 100px;
}
.parent {
position: relative;
background: aqua;
}
.child {
position: absolute;
background: maroon;
top: 50px;
left: 50px;
z-index: -1;
}

CSS dropdown menu not showing the full texts of submenu items

I am trying to create a drop down menu using CSS and HTML, it is working fine but the problem is the sub menu items does not show the full texts. For example: If I hover on the link-1 the sub menu items shows up but I can only see first few of the texts from the sub menu items.
I want to increase the width of ul of the submenu items and see the full texts.
Would you please kindly show me how to do it?
Here's my COde:
HTML:
<div id="menu">
<ul>
<li>Link 1
<ul>
<li>ABC INFORMATION SYSTEM</li>
<li>ABC INFORMATION SYSTEM</li>
<li>ABC INFORMATION SYSTEM</li>
</ul>
</li>
<li>Link 2
<ul>
<li>Link 2-1</li>
<li>Link 2-2</li>
<li>Link 2-3</li>
</ul>
</li>
<li>Link 3
<ul>
<li>Link 3-1</li>
<li>Link 3-2</li>
<li>Link 3-3</li>
</ul>
</li>
</ul>
</div>
CSS
#menu{
text-align:left;
top:90px;
margin-left:230px;
position:absolute;
z-index:100;
}
#menu ul{
padding:0;
margin:0;
}
#menu li{
position: relative;
float: left;
list-style: none;
margin: 0;
padding:0;
}
#menu li a{
width:135px;
height: 30px;
display: block;
text-decoration:none;
text-align: center;
line-height: 30px;
background-color: #A7C66B;
color: white;
}
#menu li a:hover{
background-color: red;
}
#menu ul ul{
position: absolute;
top: 30px;
visibility: hidden;
}
#menu ul li:hover ul{
visibility:visible;
}
to increase the size of the submenus add the following to your css:
#menu ul ul li a{
width:335px;
height: 30px;
display: block;
text-decoration:none;
text-align: center;
line-height: 30px;
background-color: #A7C66B;
color: white;
}
In #menu li a make the width higher or put no width at all.
If you put no width at all, then it adjusts itself to the width of the text.

UL Dropdown Menu Problems

I have two problems with my dropdown menu, one involving links, the other involving IE7 issues. Code follows after questions, and in both instances, I'm trying to avoid javascript (a key part of the project)
I am successfully highlighting the text of the link when I hover, including some pixels above, below and left & right. However, the only part of the highlight that is clickable (i.e. where I can access a hyperlink) is where the text is, and I want to be able to have the entire highlight, padding and text, to be clickable. I've done it before, but I'm confused with the current code on how to fix it. Can anybody help me out?
Using the same dropdown, everything is working fine, except in IE7. Some IE7 users complained that once they highlighted the menu item and the dropdown occurs, they only get down to about the 2nd item before the dropdown disappears, and it does it for every dropdown. I know it's an issue with IE7, but I need to get a work around for it. Any help at all?
My CSS code:
ul { list-style: none; }
p { margin: 8px 0; }
ul.dropdown { list-style-type:none;height:24px; top:2px; padding:0px 0px 0px 0px;;margin:0px 0px 0 1px;vertical-align:bottom; color:#000000; position: relative; }
ul.dropdown a:hover { color: #000; }
ul.dropdown a:active { color: #ffa500; }
ul.dropdown li { float: left; position:relative; vertical-align:middle; background-position:0 -40px; padding: 2px 4px 5px 2px; margin-right:6px;}
ul.dropdown li a { display: block; padding: 0px 0px; color: #222; text-decoration:none; vertical-align:middle; width:100%;}
ul.dropdown li:last-child a { border-right: none; }
ul.dropdown li.hover,
ul.dropdown li:hover { background: #F3D673; color: black; position: relative; }
ul.dropdown li.hover a { color: black; }
ul.dropdown ul { width: 152px; visibility: hidden; position: absolute; top: 100%; left: -40px; z-index:60;}
ul.dropdown ul li { font-weight: normal; background: #ECEAD8; color: #000; width:100%;/*border-bottom: 1px solid #ccc;*/ float: none; }
ul.dropdown ul li.nohover { color: black; background: #ECEAD8; position:relative; }
ul.dropdown ul li a { border-right: none; width: 100%; display: inline-block; min-height:1.4em;}
ul.dropdown ul ul { left:72.7%;top: 0px; width:158px; z-index:50; display:inline-block;}
ul.dropdown li:hover > ul { visibility: visible; display:block; }
#arrowRight { float:right; margin-top:-11px;}
a.moreItems {background: url(/images/menu/arrow_r.gif) no-repeat right;}
Here is the HTML Code:
<!DOCTYPE HTML>
<html>
<head>
<title></title>
<link rel=stylesheet type="text/css" href="menustylesheet.css">
</head>
<body>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="25" class="topmenu" bgcolor="##ECEAD8" nowrap>
<ul class="dropdown">
<li><b>Item 1</b> <img src="/images/menu/arrow_d.gif" border="0" height="7" width="7">
<ul>
<li><a class="moreItems" href="">Item 1-1</a>
<ul>
<li>Item 1-1-1</li>
</ul>
</li>
<li><a class="moreItems" href="">Item 1-2</a>
<ul>
<li>Item 1-2-1</li>
</ul>
</li>
<li>Item 1-3 <div style="vertical-align:middle;"><img src="/images/menu/arrow_r.gif" id="arrowRight" border="0"></div>
<ul>
<li>Item 1-3-1</li>
<li>Item 1-3-2</li>
</ul>
</li>
<li>Item 1-4</li>
<li>Item 1-5</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr><td bgcolor="##c0c0c0" style="height:1px;"></td></tr>
</table>
</body>
</html>
I apologize if this has been answered before, but I hope someone can pinpoint where in the code I need to change or modify to make it work.
I have an answer to your first problem. When doing this kind of menu. I stay as far away from padding as I can. I find it easier just to use margins, but for starters lets look at a page I built for you:
http://www.albatrossfonts.com/stack/ulbuttons.html
I'll explain this code below.
Here is my HTML:
<div id="wrapper">
<ul class="dropdown">
<li>Button 1</li>
<li>Button 1</li>
<li>Button 1</li>
</ul>
</div>
And the CSS:
.dropdown
{
width: 200px;
display:block;
margin: 200px auto 0 auto;
list-style-type: none;
padding: 0;
}
.dropdown li
{
width: 200px;
height: 44px;
display: block;
float: left;
margin: 1px 0 0 0;
list-style-type: none;
padding: 0;
}
.dropdown li a:link, .dropdown li a:visited
{
width: 200px;
height: 44px;
display: block;
float: left;
margin: 0;
color: #ffffff;
background-color: #666666;
text-decoration: none;
text-indent: 12px;
line-height: 44px;
}
.dropdown li a:hover
{
background-color: #333333;
}
Notice that I declared a:link, instead of just a. I also declared a:visited since I want the visited state to be the same as the original state.
In the .dropdown entry, I simply defined a width for the list (ul) and made it display properly.
In the .dropdown li entry, I set the width and height of each list item, removed bullets, and set the display and float to make them display as a box. No padding. Just a box.
In the .dropdown li a:link, .dropdown li a:visited entry, what we are essentially doing is "filling" our list item boxes with a link, and it just so happens that we can define a link as a box as well. So I set the dimensions of the link to the exact same size as our li's (this is what makes the entire box clickable). Then set the display and float, and a background color, as well as a text color, or simply "color."
In order to get your text in the center, you should not use vertical-align. Use line-height, and set it to the same height as your li element. This will center your text in the box vertically.
To control where your text appears horizontally, set a text-indent property, use text-align. In this example, I used text-indent.
Finally, we define our a:hover state. It's important to remember that the only things you truly need to define here are any properties that actually change. In this case, the background color.
If you wanted to ad a state for the mouse down event, you could do something like:
.dropdown li a:active
{
background-color: #000000;
text-indent: 20px;
}
/////////// Edit////////////
Here's how you would use a single css styles for multiple menus or child menus.
html for 2 separate ul's:
<ul class="dropdown">
<li>Button 1</li>
<li>Button 1</li>
<li>Button 1</li>
</ul>
<ul class="dropdown">
<li>Button 1</li>
<li>Button 1</li>
<li>Button 1</li>
</ul>
CSS: (stays the same, because you assign both of them to the class "dropdown."
.dropdown
{
width: 200px;
display:block;
margin: 200px auto 0 auto;
list-style-type: none;
padding: 0;
}
.dropdown li
{
width: 200px;
height: 44px;
display: block;
float: left;
margin: 1px 0 0 0;
list-style-type: none;
padding: 0;
}
.dropdown li a:link, .dropdown li a:visited
{
width: 200px;
height: 44px;
display: block;
float: left;
margin: 0;
color: #ffffff;
background-color: #666666;
text-decoration: none;
text-indent: 12px;
line-height: 44px;
}
.dropdown li a:hover
{
background-color: #333333;
}
If you want to apply your styles for a child ul, like this:
<ul class="dropdown">
<li>Button 1
<ul>
<li><a href="#">subButton 1</li>
<li><a href="#">subButton 2</li>
<li><a href="#">subButton 3</li>
</ul>
</li>
<li>Button 1</li>
<li>Button 1</li>
</ul>
You simply append your styles to include the child ul and child ui li, as follows; where .dropdown actually represents your first ul. So .dropdown(ul) --> li (list item in "dropdown" unordered list) --> ul (ul inside dropdown li) --> li (li inside dropdown ul li ul)
Sorry if that sounds confusing, but in other words, if you didn't assign a class to your parent ul at all, it would be ul li ul li to access a list item inside a child list.
.dropdown, dropdown li ul
{
width: 200px;
display:block;
margin: 200px auto 0 auto;
list-style-type: none;
padding: 0;
}
.dropdown li, .dropdown li ul li
{
width: 200px;
height: 44px;
display: block;
float: left;
margin: 1px 0 0 0;
list-style-type: none;
padding: 0;
}
.dropdown li a:link, .dropdown li a:visited, .dropdown li ul li a:link, .dropdown li ul li a:visited
{
width: 200px;
height: 44px;
display: block;
float: left;
margin: 0;
color: #ffffff;
background-color: #666666;
text-decoration: none;
text-indent: 12px;
line-height: 44px;
}
http://www.webcredible.co.uk/user-friendly-resources/css/internet-explorer.shtml
^This has helped me on many occasions to find work-arounds for IE.

Resources