Consider the following nested list:
<div >
<ul class="main">
<li>Fist item<ul class="ab"><li>a1</li><li>a2</li><li>a3</li><li>a4</li></ul>
</li>
<li>Second item<ul class="ab"><li>b1</li><li>b2</li><li>b3</li><li>b4</li></ul></li>
<li>Third item<ul class="ab"><li>c1</li><li>c2</li><li>c3</li><li>c4</li></ul>
</li>
</ul>
</div>
I want the outer level displayed horizontally, and the inner level displayed just below the outer one. To this aim I've used relative and absolute position for outer and inner lists in the css style:
#container {width:300px}
main {width:200px;position:relative;}
body > div > ul > li {display:block;float:left;padding:5px;}
body > div > ul > li > a:hover + .ab {display:block;}
.ab {display:none;clear:both;position:absolute;left:0px}
It works fine unless you resize container width to 200px (as you can try on JSfiddle) (I have to achieve a solution working with different widths). In this case the inner level container overlaps the outer one. I wonder if it is possible to force the inner container to be displayed after the outer container through css or solve this issue in another way.
Edit: I need to make my question clearer because given answers so far show the same proposal I have already made. So i've made a little addition in the css styles declaring a box for the inner container (here the update JSfiddle snippet). The key issue is that my toy example simulates the left column in a more complicated web page. I do not know in advance the exact width of such a column (maybe 150px, maybe 200px or something similar) and I do not know in adcance the length of the titles for the outer list elements. I need a solution that works for whichever width the outer container could have.
This is a screenshot of what I obtain in the default case:
This is what I obtain narrowing the outer container to 200px (try yourself on JSfiddle):
and this is instead what I want to obtain:
I hope to have been my question clear now.
U need to make outer level positioned to relative and inner level as absolute, like this:
#container {width:300px}
.ab {
display:none;
clear:both;
position:absolute;
left:0px
}
body > div > ul > li {
display:block;
float:left;
padding:5px;
position:relative;
}
body > div > ul > li > a:hover + .ab {
display:block;
position:absolute;
left:0; /* So it aligns to the left edge of outer level */
top:100%; /* So inner level isn't overlaping outer */
}
main {width:200px;position:relative;}
Example here: https://jsfiddle.net/d9fsff69/2/
To ensure flexibility, make sure your widths are not fixed. And the rest is a matter of margin. I added some background coloring for visual aid:
Use this CSS:
#container {
width: 100%
}
main {
width: 200px;
position: relative;
}
body > div > ul > li {
display: block;
float: left;
padding: 5px;
background:#999;
}
body > div > ul > li > a:hover + .ab {
display: block;
background:#ddd;
margin-top: 5px;
}
.ab {
display: none;
clear: both;
position: absolute;
left: 0px
}
Here is the DEMO
I would just give you similar example:
body {
margin: 0px;
font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 13px;
text-align: center;
background: #E3CAA1;
}
ul {
width: 100%;
text-align: center;
display: inline-block;
margin: 0px;
list-style: none;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
background: #000;
color: #fff;
}
ul li {
font: 12px/18px sans-serif;
display: inline-block;
margin-right: -4px;
position: relative;
padding: 20px 20px;
cursor: pointer;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
ul li:hover {
color: #71b51e;
background: #161616;
}
ul li ul {
padding: 0;
position: absolute;
left: 0;
top: 57px;
width: 140px;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
display: none;
opacity: 0;
visibility: hidden;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
ul li ul li {
background: #161616;
display: block;
color: #fff;
text-align: left;
padding: 5px 15px;
height: 25px;
}
ul li ul li:hover {
background: #111;
color: #71b51e;
}
ul li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
<ul>
<li>OPTION
<ul>
<li>SUB-1</li>
<li>SUB-2</li>
<li>SUB-3</li>
<li>SUB-3</li>
</ul>
</li>
<li>OPTION</li>
<li>
OPTION
<ul>
<li>SUB-1</li>
<li>SUB-2</li>
<li>SUB-3</li>
<li>SUB-3</li>
</ul>
</li>
<li>OPTION</li>
</ul>
Related
my problem is that when I hover over the area where the hidden list is, it shows the hidden list. I only want it to show the hidden list when hovered over the 'Language' link on the dropdown menu. Why is it doing this, it's probably something blindingly obvious that I can't spot.
Cheers :)
EDIT: I've already tried using a fixed height for the #lang_bar. I also need the transitions to still work. I've already tried using the display:none and display:block; but that didn't work so I used visibility instead.
Any ideas?
HTML:
<div id="lang_bar">
<ul>
<li><strong>Language</strong>
<ul>
<li><strong>Maori</strong></li>
<li><strong>Tongan</strong></li>
<li><strong>Chinese</strong></li>
<li><strong>Japanese</strong></li>
<li><strong>Korean</strong></li>
</ul>
</ul>
</div>
#lang_bar {
font-family: 'Open Sans', sans-serif;
color: white;
padding-left: 152px;
text-transform: uppercase;
z-index: 40;
position: absolute;
padding-top: 2px;
top: 0;
}
#lang_bar ul ul li a {
padding-top: 3px;
padding-left:5px;
}
#lang_bar ul li ul li a:before {
content: '';
display:block;
right: 0px;
height: 2px;
bottom:117px;
width: 100px;
position: absolute;
background: rgba(255, 255, 255, 0.2);
}
#lang_bar ul li ul li a:after {
content: '';
display:block;
right: 1px;
height: 2px;
width: 100px;
position: absolute;
background: rgba(255, 255, 255, 0.6);
}
#lang_bar li, #lang_bar li ul {
text-decoration: none;
list-style-type: none;
}
#lang_bar ul {
list-style: none;
padding-left: 0px;
}
#lang_bar ul li {
float: left;
width: 100px;
text-align: left;
line-height: 21px;
}
#lang_bar ul li a {
display: block;
color: #FFF;
background: transparent;
text-decoration: none;
text-align: center;
}
#lang_bar ul li ul {
visibility: hidden;
font-size:12px;
opacity: 0;
}
#lang_bar ul li:hover ul {
opacity: 1;
visibility: visible; /* display the dropdown */
-webkit-transition: all .25s ease;
-moz-transition: all .25s ease;
-ms-transition: all .25s ease;
-o-transition: all .25s ease;
transition: all .25s ease;
}
#lang_bar ul li ul a:hover{
transition-duration: 0.6s;
background-color: rgba(255, 0, 0, 0.23);
}
I changed your css a little bit and here is the result
I used display:none and display: block in place of visibility, and everything is working as it should be.
http://jsfiddle.net/sy3qowxs/5/enter link description here
And here is your final CSS:
#lang_bar {
font-family: 'Open Sans', sans-serif;
color: #123111;
padding-left: 152px;
text-transform: uppercase;
z-index: 40;
position: absolute;
padding-top: 2px;
top: 0;
}
#lang_bar a:link{color:#333333;}
#lang_bar ul ul li a {
padding-top: 3px;
padding-left:5px;
}
#lang_bar ul li ul li a:before {
content: '';
display:block;
right: 0px;
height: 2px;
bottom:117px;
width: 100px;
position: absolute;
background: rgba(255, 255, 255, 0.2);
}
#lang_bar ul li ul li a:after {
content: '';
display:block;
right: 1px;
height: 2px;
width: 100px;
position: absolute;
background: rgba(255, 255, 255, 0.6);
}
#lang_bar li, #lang_bar li ul {
text-decoration: none;
list-style-type: none;
}
#lang_bar ul {
list-style: none;
padding-left: 0px;
}
#lang_bar ul li {
float: left;
width: 100px;
text-align: left;
line-height: 21px;
}
#lang_bar ul li a {
display: block;
color: #FFF;
background: transparent;
text-decoration: none;
text-align: center;
}
#lang_bar ul li ul {
display: none;
font-size:12px;
opacity: 0;
}
#lang_bar ul li:hover ul {
opacity: 1;
display: block; /* display the dropdown */
-webkit-transition: all .25s ease;
-moz-transition: all .25s ease;
-ms-transition: all .25s ease;
-o-transition: all .25s ease;
transition: all .25s ease;
}
#lang_bar ul li ul a:hover{
transition-duration: 0.6s;
background-color: rgba(255, 0, 0, 0.23);
}
As an alternative to the display: none solution, for accessibility reasons you can use position:absolute and then move the hidden element off screen:
ul li ul {
position:absolute;
top:-1000px;
}
ul li:hover ul {
top:auto;
}
It should work with visibility, since it hides the element (like display: none) but doesn't remove it from the DOM
Here is a working example: Dropdown Menu
HTML
<ul class="menu">
<li class="menu-item"> Dropdown Menu
<ul class="submenu">
<li class="submenu-item">Link</li>
<li class="submenu-item">Link</li>
<li class="submenu-item">Link</li>
<li class="submenu-item">Link</li>
<li class="submenu-item">Link</li>
</ul>
</li>
</ul>
CSS
.menu-item {
position: relative;
}
.menu-item:hover .submenu {
visibility: visible;
opacity: 1;
}
.submenu {
position: absolute;
visibility: hidden;
transition: all .2s ease;
opacity: 0;
top: 100%;
}
.submenu-item {
padding: .4em;
}
What about just using the adjacent sibling combinator:
Change: #lang_bar ul li:hover ul
To: #lang_bar ul li a:hover + ul
To add to the previous answer, the reason this works when you use the display property instead of visibility is because display removes the element from the document flow, and other elements reflow in its place. Visibility, on the other hand, hides the element, but leaves the empty space as if it were still there. So when you used visibility: hidden, your list item looked like it just contained the text "Language" and the link, but the hidden ul was still there, and still hoverable. That's why when you hovered over where the list item should have been, it reappeared; technically, you were hovering over that first list item, because the sub menu was a child of it.
In general, I use display:block/display:none to toggle hiding and showing of items, rather than visibility. Typically the use case is that you want the element completely hidden from the page, and elements around it to reflow, and the display property will do that for you.
I've got a menu made that utilizes left and right borders to separate each menu item. When hovering over the menu, the background changes to a lighter shade, which is what I want. However, hovering also covers the left border. How can I stop the border from disappearing? I'm sure this has been answered elsewhere, but I couldn't find it. Thanks, in advance.
http://jsfiddle.net/aYsKp/2/
HTML:
<div id="header">
<div id="menu">
<ul>
<li>HOME
</li>
<li>PRODUCTS
</li>
<li>VIDEOS
</li>
<li>DOWNLOADS
</li>
<li>CONTACT
</li>
<li>ABOUT
</li>
</ul>
</div>
</div>
CSS:
#header {
width:960px;
margin: 10px auto 5px auto;
background-color: #727272;
}
#menu {
max-width:828px;
bottom:0;
right:0;
font: 12px/18px sans-serif;
}
#menu a {
text-decoration: none;
display:block;
padding: 10px 32px;
color:#FFF;
}
#menu ul {
text-align: left;
display: inline;
margin: 0;
padding: 15px 4px 17px 0;
list-style: none;
}
#menu ul li {
display: inline-block;
margin-right: -4px;
position: relative;
cursor: pointer;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
border-right: 1px solid #FFF;
}
#menu ul li:first-child {
border-left: 1px solid #FFF;
}
#menu ul li:hover {
background-color:#818181;
}
Try this approach.
#header {
width:960px;
margin: 10px auto 5px auto;
}
#menu {
max-width:828px;
bottom:0;
right:0;
font: 12px/18px sans-serif;
background-color: white;
}
#menu a {
text-decoration: none;
display:block;
padding: 10px 32px;
color:#FFF;
}
#menu ul {
text-align: left;
display: inline;
margin: 0;
padding: 15px 4px 17px 0;
list-style: none;
}
#menu ul li {
display: inline-block;
position: relative;
cursor: pointer;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
background-color: #727272;
margin:0;
}
#menu ul li:hover {
background-color:#818181;
}
What I've done is just removed right margin and specified background color as white for the menu div.
I use to set border or space informations in A tag, not in LI, making LI like an "invisible" tag, setting all properties to A, using A display:inline-block.
I would like a topbar navigation, similar to one that you see with Foundation. The problem i'm having is that i've set margins for the page and dont know how to override them?
So for most of page (body) I need these margins but for the top bar i'd like it extending the full width of the browser.
Here's the code:
body {
font-family: 'Droid Sans', sans-serif;
font-size: 1.2em;
color: #000000;
background-color: white;
margin: 0em 6.5em 3.5em;
#nav ul {
width: 100%;
background-color: #212121;
font-size: 12px;
font-weight: bold;
color: white;
text-align: left;
display: block;
margin: 0;
padding: 15px 4px 17px 0;
list-style: none;
}
#nav ul li {
display: inline-block;
margin-right: -4px;
height: inherit;
margin-left: 20px;
position: relative;
padding: 15px 20px;
background: #212121;
cursor: pointer;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#nav ul li:hover {
background: #212121;
color: #fff;
}
#nav ul li ul {
padding: 0;
position: absolute;
top: 48px;
left: 0;
width: 150px;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
display: none;
opacity: 0;
visibility: hidden;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
#nav ul li ul li {
background: #212121;
display: block;
color: #fff;
}
#nav ul li ul li:hover { background: #212121; }
#nav ul li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
Html:
<body>
<div id="nav">
<ul>
<li>Home</li>
<li>Venue</li>
<li>Events</li>
<li>Stalls
<ul>
<li>Food</li>
<li>Arts & Crafts</li>
</ul>
</li>
<li>Contact</li>
</ul>
</div>
Besides using absolute positioning, you can just use negative margins for the #nav like this:
#nav {
margin-left:-6.5em;
margin-right:-6.5em;
}
Demo
Apply the following css for the header,
#nav{
position:absolute;
left:0;
right:0;
}
It's take the nav out of normal flow and stretch it from left to right.
Check this JSFiddle
If you set position:fixed; width:100%; then the header will be taken out of the normal flow and will be positioned relative to the window. It'll stay where it is even if the user scrolls down the page.
Use fixed positioning for the navigation bar you want at the top of your page.
#nav {
min-width:100%;
position:fixed;
top:0;
left:0;
}
Adding a min-width of 100% should ensure the navigation bar stretches across the width of your page. Setting top and left to zero, in conjunction with position:fixed, would anchor the nav div to the top-left.
I'm using ordered lists to create a menu, and I have run into two issues, the drop down does not align and the hover effect is applied to the drop downs and I don't want that to happen
Here is a JS Fiddle:
http://jsfiddle.net/HFMR5/
this is my HTML code:
<div id="menu">
<ul id="navigation">
<li>Home</li>
<li>Services
<ul>
<li>Residential</li>
<li>Buisiness</li>
</ul>
</li>
<li>Contact</li>
</ul>
</div>
and this is the CSS for the menu:
/*Navigation CSS*/
#navigation
{
width: 100%;
float: left;
margin: 0 0 3em 0;
padding: 0;
list-style: none;
background-color: #f2f2f2;
border-bottom: 1px solid #ccc;
border-top: 1px solid #ccc;
box-shadow: 0 8px 6px -6px black;
}
#navigation li
{
float: left;
}
#navigation li a
{
display: block;
padding: 8px 15px;
text-decoration: none;
font-weight: bold;
color: #FF6987;
border-right: 1px solid #ccc;
-webkit-transition: all 0.1s ease-in;
-moz-transition: all 0.1s ease-in;
-o-transition: all 0.1s ease-in;
}
#navigation ul
{
font-family: Arial, Verdana;
font-size: 14px;
margin: 0;
padding: 0;
list-style: none;
}
#navigation ul li {
display: block;
position: relative;
float: left;
}
#navigation li ul { display: none; }
#navigation li:hover ul {
display: block;
position: absolute;
}
#navigation li:hover li {
float: none;
font-size: 11px;
}
#navigation li:hover a { background: #f2f2f2; }
#navigation li a:hover
{
color: #FF6987;
background-color: #f2f2f2;
box-shadow: inset 0 8px 6px -6px black;
}
In order for the widths to be the same you need to actually set the width of the sub-menu (Not necessarily static) but if you let it be then it will just expand to the size of the contnent which obviously isn't desired, the CSS changes look like:
#navigation li{
float: left;
position:relative;
}
#navigation li:hover ul {
display: block;
position: absolute;
width: 100%;
}
The position: relative has the sub-menu know to use that element when determining what 100% width is instead of the body tag.
As for the hover effect showing up on sub-menu items all that you need to do is be more specific in your selector. The space you are using signifies that you will select and descendant of #navigation that is a li element. That includes the submenus. If you use a selector like the > which signifies a direct child then you will be able to bre more specific in targeting only top level menu items. CSS looks something like:
#navigation > li > a:hover{
color: #FF6987;
background-color: #f2f2f2;
box-shadow: inset 0 8px 6px -6px black;
}
A good reference for CSS selectors: http://www.w3schools.com/cssref/css_selectors.asp
I've made a css dropdown menu and I want each dropdown option to have a blue background when it is hovered on. However when I try this the background for the option will only be blue when the top half of it is hovered on. Here it is on jsfiddle. If you hover your mouse on the "products" option and then put the mouse under "plates" but above the gray horizontal line the background won't be blue. Can anybody help me? Thank you.
http://jsfiddle.net/hDWuJ/1/
HTML (Note this is a segment of my web page and so it does not have valid syntax)
<h1 id="title">Sample Text</h1>
<div id="HorzLineDiv"><hr></div>
<div id="MenuCenter">
<nav id="Menu" class="MenuBar">
<ul id="drop-nav">
<li>Home</li>
<li>Products <span id="arrowDown">▼</span>
<ul>
<li>Children's Stuff</li>
<li>Plates</li>
<li>Top Sellers</li>
</ul>
</li>
<li>Services <span id="arrowDown">▼</span>
<ul>
<li>Wash 'n' Fold</li>
<li>Blanket Making</li>
<li>Wedding Dress</li>
<li>Custom</li>
</ul>
</li>
</ul>
</nav>
</div>
CSS
body
{
background-color: #dfdfdf;
}
#title
{
text-align: center;
color: #07a8ca;
font-size:60pt;
margin: 0px;
padding: 0px;
text-shadow: 2px 2px 0px #888888;
}
h1
{
margin: 0px;
padding: 0px;
}
hr
{
height: 3px;
color: #07a8ca;
background: #07a8ca;
font-size: 0;
border: 0;
}
#HorzLineDiv
{
width: 95%;
margin: 2% 0% 3% 0%;
margin-left: auto ;
margin-right: auto ;
}
#Menu
{
width:100%;
}
#drop-nav
{
margin: 0 auto;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
}
ul
{
list-style: none;
padding: 0px;
margin: 0px;
}
ul li
{
display: block;
position: relative;
float: left;
display: inline;
padding: 12px 50px 8px 50px;
margin: 0px 5px 0px 5px;
border-left: 3px solid #07a8ca;
}
ul li:first-child
{
border-left: 0px;
}
li ul
{
display: none;
}
ul li a
{
display: block;
text-transform: uppercase;
text-decoration: none;
text-align:center;
color: #000;
font: 25px/1.1em "Kelly Slab","serif";
transition: color 0.4s ease 0s;
-moz-transition: color 0.4s ease 0s; /* Firefox 4 */
-webkit-transition: color 0.4s ease 0s; /* Safari and Chrome */
-o-transition: color 0.4s ease 0s; /* Opera */
}
ul li a:hover
{
color: #FF4D4D;
}
li:hover ul
{
display: block;
position: absolute;
}
li:hover li
{
float: none;
}
li:hover a
{
margin:0;
}
li:hover li a:hover
{
background: #21e8fa;
}
#drop-nav li ul li
{
border-top: 0px;
border-left: 0px;
}
#drop-nav ul li a
{
border-top: 3px solid #888;
padding: 13px 0px 13px 0px;
margin: -10px -8px;
text-align:center;
text-transform: none;
position:relative;
top: 13px;
color: #000;
}
#drop-nav ul
{
width:100%;
position:absolute;
right:-5px;
}
a
{
margin:0px;
padding:0px;
}
#arrowDown
{
font-size: 10pt;
vertical-align:text-bottom
}
The main issue is in your margins and padding, but this can be worked around by changing your ul li to display: block; instead of display: inline;.
Of course, this isn't a direct fix to the issue, and there still is an area at the bottom that doesn't work on hover, but it is much smaller than before. The proper way to go about fixing this is fixing your margins and padding.
Demo
UPDATE
Reading deeper into your code, I found the actual problem. It is not in margins or padding as I originally thought, but is a top property of 13px defined in #drop-nav ul li a. That top of 13px was creating a blank, inactive space in your list.
Get rid of that piece and it is working fine: DEMO