I am trying to make a menu with sub-menu under an element by giving the main menu's il relative position and the ul inside it absolute position. Why does the sub-menu treats the to ul as it's container and not it's parent li?
the HTML:
<nav>
<ul>
<li>Menu Item 1</li>
<li>Menu Item 2
<ul>
<li>Submenu Item 1</li>
<li>Submenu Item 2</li>
<li>Submenu Item 3</li>
</ul>
</li>
<li>Menu Item 3</li>
<li>Menu Item 4</li>
<li>Menu Item 5</li>
</ul>
</nav>
the CSS:
nav a {
float: left;
padding: 10px;
border: solid 1px #C0C0C0;
margin-left: -1px;
}
nav li {
position: relative;
}
nav li ul {
position: absolute;
}
http://jsfiddle.net/6pgHa/
It may be because it is your anchor tags that are floated left and therefore defining the position, not the li elements.
Change the nav a selector to nav li and this fixes it. The li elements don't really have a position in your current code.
I've updated your fiddle to make the menu work the way I guess you want it to: http://jsfiddle.net/6pgHa/3/
nav {
width: 600px;
margin: 50px auto 0;
}
nav > ul li {
float: left;
position: relative;
}
nav > ul li a {
float: left;
padding: 10px;
border: solid 1px #C0C0C0;
display:inline-block;
}
nav > ul li ul {
position: absolute;
top:50px;
left:-9999px;
}
nav > ul li:hover ul {
left:0;
}
Related
I'm trying to create a nested dropdown menu that may potentially be very long and overflow off the page.
What I'd like to do is, when the menu is too long it will display a scroll bar. I'm doing this with overflow: auto. However, when I do this, it traps any submenus within the same 'scroll space' as defined by the first scroll bar.
I've also tried various iterations of overflow: none with the :not(:hover) selector, but nothing I've tried seems to work.
What I'd like it to do is show the scrollbar on each level, only if necessary (i.e. that submenu would scroll off the page). Each submenu should 'pop' out of the previous scroll bar, if any, as if it was not there.
I'd like to do this in all CSS, but I'm open to a JS solution as well.
I have a code pen showing the issue here:
https://codepen.io/mcmurphy510/pen/ZyGLKd
I'm not sure if I'm understanding your question correctly, but try isolating your desired element by using ID or CLASS. See the third level menu.
#primary_nav_wrap {
margin-top: 15px
}
#primary_nav_wrap ul {
list-style: none;
position: relative;
float: left;
margin: 0;
padding: 0;
}
#primary_nav_wrap ul a {
display: block;
color: #333;
text-decoration: none;
font-weight: 700;
font-size: 12px;
line-height: 32px;
padding: 0 15px;
font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif
}
#primary_nav_wrap ul li {
position: relative;
float: left;
margin: 0;
padding: 0;
}
#primary_nav_wrap ul li.current-menu-item {
background: #ddd
}
#primary_nav_wrap ul li:hover {
background: #f6f6f6
}
#primary_nav_wrap ul ul {
display: none;
position: absolute;
top: 100%;
left: 0;
background: #fff;
padding: 0;
}
#primary_nav_wrap ul ul li {
float: none;
width: 200px
}
#primary_nav_wrap ul ul a {
line-height: 120%;
padding: 10px 15px
}
#primary_nav_wrap ul ul ul {
top: 0;
left: 100%
}
#primary_nav_wrap ul li:hover > ul {
display: block;
height: 200px;
}
#primary_nav_wrap ul li ul li:not(:hover) {
}
/* ul li ul li ul li {
overflow: auto;
} */
#subdeep {
overflow: auto;
height: 50px !important;
}
<h1>Simple Pure CSS Drop Down Menu</h1>
<nav id="primary_nav_wrap">
<ul>
<li>Menu 1
<ul>
<li>Sub Menu 1</li>
<li>Sub Menu 2</li>
<li>Sub Menu 3</li>
<li>Sub Menu 4
<ul>
<li>Deep Menu 1
<ul id="subdeep">
<li>Sub Deep 1</li>
<li>Sub Deep 2</li>
<li>Sub Deep 3</li>
<li>Sub Deep 4</li>
</ul>
</li>
<li>Deep Menu 2</li>
</ul>
</li>
<li>Sub Menu 5</li>
</ul>
</li>
</ul>
</nav>
Probably you could use the proposed solution as the elements are positioned relative to each other and therefore the menu can set up some branches, you would "just" require to ensure that the parent element(s) remain visible
Mouse over on item "Link 3" will shows its sub-menu on the right side of it and then mouse over on "Link 31" for further sub menu.
.menu {
position: relative;
}
ul {
width: 200px;
margin: 0;
color: black;
list-style:none;
padding:0;
max-height:100px;
overflow-x: hidden;
overflow-y: auto;
}
li {
padding:0.5em;
}
li:hover{
background-color:blue;
color:white;
}
li .menu {
position: absolute;
z-index: 10;
background-color:lightgrey;
opacity: 0;
transition: opacity 0.5s;
}
li:hover > .menu,
.menu:hover {
opacity: 1;
}
li.parent {
cursor: pointer;
}
.level2 {
top: 0px;
left: 200px;
}
<div class="menu">
<ul>
<li>Link1</li>
<li class="parent">Link3...
<div class="menu level2">
<ul>
<li class="parent">Link31...
<div class="menu level2">
<ul>
<li>Link 311</li>
<li>Link 312</li>
<li>Link 313</li>
<li>Link 314</li>
</ul>
</div>
</li>
<li>Link 32</li>
<li>Link 33</li>
<li>Link 34</li>
</ul>
</div>
</li>
<li>Link2</li>
<li>Link1</li>
<li>Link2</li>
</ul>
</div>
I've got a nav bar configured to hide drop down elements (using display:none) until hovered over when it will show as a drop down (using display:block at a:hover). It all works great except the "divs" below it are pushed down when drop down displays. How can I get the "divs" to remain in place regardless of the display of the drop down items?
Thanks!
I hope it helps you
<h1>Simple Pure CSS Drop Down Menu</h1>
<ul class="nav">
<li>Menu1
<ul>
<li>Sub menu1</li>
<li>Sub menu2</li>
<li>Sub menu3</li>
<li>Sub menu4
<ul>
<li>Deep menu1</li>
<li>Deep menu2
<ul>
<li>Sub deep menu1</li>
<li>Sub deep menu2</li>
<li>Sub deep menu3</li>
</ul>
</li>
<li>Deep menu3</li>
</ul>
</li>
<li>Sub menu5</li>
</ul>
</li>
<li>Menu2
<ul>
<li>Sub menu1</li>
<li>Sub menu2</li>
<li>Sub menu3</li>
</ul>
</li>
<li>Menu3
<ul>
<li>Sub menu1</li>
<li>Sub menu2
<ul>
<li>Category1</li>
<li>Category2</li>
<li>Category3</li>
<li>Category4</li>
<li>Category5</li>
</ul>
</li>
<li>Sub menu3</li>
<li>Sub menu4</li>
<li>Sub menu5</li>
</ul>
</li>
</ul>
.nav {
margin: 15px 0 0;
}
.nav li {
display: inline-block;
width: 150px;
position: relative;
text-align: center;
}
.nav li:hover {
background: #f6f6f6;
}
.nav li a {
display: block;
padding: 10px 15px;
}
.nav ul {
display: none;
position: absolute;
}
.nav ul li {
display: block;
}
.nav li:hover ul {
display: block;
}
.nav li:hover ul li ul {
display: none;
}
.nav li ul li:hover ul {
display: block;
left: 100%;
top: 0;
}
.nav li ul li:hover ul li ul {
display: none;
}
.nav li ul li ul li:hover ul {
display: block;
}
fiddle
The <div> elements which contain the dropdown parts have to have position: absolute. That way they don't occupy any space in the surrounding containers. Tune their position n relation to their parent elements with the top and left (or right) settings.
The parent elements of those DIVs need to have position: relative to enable the absolute positioning of their children elements.
By the way, position: fixed wouldn't work that well, since this positions an element absolutely to the window, which in most cases you don't want (exception: if you have a fixed navbar).
I am trying to create a vertical navigation in my HTML document, but I cannot seem to get the main menu to line up evenly. Here is my HTML for the vertical navigation:
<div id="navbar">
<ul>
<li>Menu 1</li>
<li>Menu 2
<ul>
<li>Drop 1</li>
<li>Drop 2</li>
<li>Drop 3</li>
</ul></li>
<li>Menu 3</li>
<li>Menu 4
<ul>
<li>Drop 1</li>
<li>Drop 2</li>
</ul></li>
<li>Menu 5</li>
</ul>
</div>
And my CSS:
#navbar {
margin-left: -40px;
}
#navbar li{
list-style: none;
position: relative;
width: 209px;
padding: 6px;
line-height: 20pt;
cursor: pointer;
}
#navbar ul ul{
margin-left: 100px;
margin-top: -28px;
visibility:hidden;
height: 100px;
}
#navbar ul li:hover ul{
visibility:visible;
}
This is my first post ever, so I apologize if I didn't post in the correct format. This code is also from a much larger HTML/CSS file, so I just copy/pasted the only part I'm having an issue with. If I need to post a screenshot of what I'm talking about I can do that.
Thank you in advance!!
demo - http://jsfiddle.net/uab2hr50/2/
if you are looking to align the sub menu below the main menu
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#navbar ul {
border: 1px solid red;
display: inline-block;
padding: 6px;
}
#navbar li {
list-style: none;
position: relative;
width: 209px;
line-height: 20pt;
cursor: pointer;
}
#navbar ul ul {
display: none;
padding: 0;
border: 0;
}
#navbar ul li:hover ul {
display: block;
}
<div id="navbar">
<ul>
<li>Menu 1
</li>
<li>Menu 2
<ul>
<li>Drop 1
</li>
<li>Drop 2
</li>
<li>Drop 3
</li>
</ul>
</li>
<li>Menu 3
</li>
<li>Menu 4
<ul>
<li>Drop 1
</li>
<li>Drop 2
</li>
</ul>
</li>
<li>Menu 5
</li>
</ul>
</div>
There are a few problems here preventing the display you expect:
First: the fiddle
CSS CHANGES
#navbar li{
list-style: none;
position: relative;
/*width: 209px;*/
padding: 6px;
line-height: 20pt;
cursor: pointer;
display: block;
}
#navbar li:after {
content: '';
display: table;
clear: both;
}
#navbar ul a {
display: inline-block;
}
#navbar ul ul{
margin-top: 0;
visibility:hidden;
height: 100px;
padding: 0;
display: inline-block;
vertical-align: top;
margin-bottom: -9000px;
}
#navbar ul ul li:first-child {
padding-top: 0;
}
We removed quite a bit of your padding and margin rules here, and stopped setting a width on the li that you went ahead and broke out of anyway in the original code.
Then, we told both the a and ul elements to display as inline-block, told them they were to vertically align at the top and removed the padding-top off the first child of your sub-nav.
Then, we way over-compensate for the height of your lists by setting a margin-bottom of -9000px to pull your subsequent list items up to where they belong.
No absolute positioning needed, which would probably require some JavaScript to position everything reliably for you given different conditions.
Hope that helps.
I have problem with the select the last-child element!
I created page something like this for navbar:
<nav>
<ul>
<li>list numeber 1</li>
<li>list numeber 2
<ul>
<li>sub list item</li>
<li>sub list item</li>
<li>sub list item</li>
</ul>
</li>
<li>list numeber 3</li>
<li>Sign Out</li>
</ul>
</nav>
with css something like this:
nav {
background: yellow;
}
ul {
list-style: none;
}
li {
padding: 10px 15px;
display: inline-block;
position: relative;
}
ul li:last-child {
float: right;
background: #ddd;
}
ul li ul {
display: none;
position: absolute;
background: #eee;
top: 39px;
left: 0;
}
ul li:hover ul {
display: block;
}
ul li ul li {
display: block;
}
i want to add BG for last-child (Sing out) in for Ul , but when see the sub-items, last-child of that get background like the parent. but i dont want to get color. how can i fix that...?
i dont want to use any class or id or JavaScript!
i there any way...?
TnX
Change ul li:last-child to nav > ul > li:last-child.
The > character is the direct-descendent selector.
changes mentioned in comment line
<nav>
<ul>
<li>list numeber 1</li>
<li>list numeber 2
<ul id="menu">// changes-here id is mentioned.
<li>sub list item</li>
<li>sub list item</li>
<li>sub list item</li>
</ul>
</li>
<li>list numeber 3</li>
<li>Sign Out</li>
</ul>
</nav>
Changes mentioned in comment line
nav {
background: yellow;
}
ul {
list-style: none;
}
li {
padding: 10px 15px;
display: inline-block;
position: relative;
}
#menu li:last-child {// changes-here i refer the id of that menu
float: right;
background:green;
}
ul li ul {
display: none;
position: absolute;
background: #eee;
top: 39px;
left: 0;
}
ul li:hover ul {
display: block;
}
ul li ul li {
display: block;
}
For Demo:JSFIDDLE
First, your padding on the li elements will have unpredictable results on different browsers. I suggest coding in Firefox or Chrome. instead, put the padding on the a tag.
li a {
padding: 10px 15px;
}
li {
/*padding: 10px 15px; */
display: inline-block;
position: relative;
}
Second, you can use a decendant selector to specify the depth of the CSS, and override less specific selectors.
ul li ul, ul li:last-child {
background: #eee;
}
ul li ul {
display: none;
/*background: #eee;*/
position: absolute;
top: 39px;
left: 0;
}
I have a list that I'd like the main elements to align vertically and the sub elements of each to drop down underneath the main element. I want to keep the position: absolute on the subNav class because the width of this nav will vary from each so I can't set a width. This works in Firefox, but in IE 7 the absolute causes the subnav to display inline (so shifted to the right and up from where I would like). How can I fix this?
Example:
<style>
#nav ul, #nav li ul {
list-style-type: none;
margin: 0;
padding: 0;
}
#nav li {
float: left;
width: 120px;
border-right: 1px solid #000;
padding: 10px;
}
#nav li ul li {
float: none;
width: auto;
height: auto;
border-right: none;
text-align: left;
padding: 0;
}
#nav .subNav {
background: #eee;
position: absolute;
padding: 10px;
}
</style>
</head>
<body>
<div id="nav">
<ul>
<li>Main One
<ul class="subNav">
<li>Sub One A</li>
<li>Sub One B</li>
</ul>
</li>
<li>Main Two
<ul class="subNav">
<li>Sub Two A</li>
<li>Sub Two B</li>
</ul>
</li>
</ul>
</div>
</body>
Don't forget to put in your top and left values.
nav .subNav{
top:10px;
left:20px;
}
nav.containerDiv {
position:relative;
}
HTML
<ul class="nav">
<li>
<div class="containerDiv">
<ul class="subNav">...
</div>
</li>
</ul>
This will result in the subNav being relative to the container div, instead of the whole document.