Positioning Nested List in CSS on Hover - css

I am creating a center, nested navigation menu, and am trying to use pure CSS. See a working demo HERE: http://jsfiddle.net/jenstechs/MKtTN/2/
HTML:
<nav>
<ul id="primary">
<li>Link One</li>
<li>Link Two</li>
<li>Link Threee
<ul class="secondary">
<li>Services One</li>
<li>Services Two</li>
</ul>
</li>
<li>Link Four</li>
<li>Link Fiiiiive</li>
</ul>
</nav>
CSS:
nav {
margin:15px auto 10px auto;
width:100%;
}
nav ul#primary {
width: 100%;
padding: 10px 0;
margin: 0;
background-color: #FFF;
text-align: center;
}
nav ul#primary>li {
display: inline;
padding:5px 0;
margin-left:0;
}
nav ul#primary>li>a {
padding: 0px 30px;
margin-right:-6px;
color: #000;
text-decoration: none;
border-right:2px solid #999;
}
nav ul#primary>li>a:hover,
nav ul#primary>li.active>a {
background-color: #900;
color:#FFF;
padding-top:10px;
padding-bottom:25px;
}
nav ul#primary>li:first-child a {
border-left:2px solid #999;
}
ul.secondary {
padding-top:0;
position:absolute;
display:none;
}
ul.secondary li {
}
nav ul#primary li:hover ul.secondary {
display:block;
}
nav ul#primary li:hover ul.secondary li {
}
ul.secondary li a {
display:block;
width:7em;
color:#FFF;
background-color:#900;
font-size:0.8em;
text-decoration:none;
text-align:left;
line-height:1.4em;
border-bottom:1px solid #FFF;
}
ul.secondary li:last-child a {
border-bottom:0;
}
ul.secondary li a:hover {
color:#DDD;
}
​
I also have a minimal reset, the only styles it has on lists is a few default margins.
Since this is a centered navigation bar, the CSS I'm using is inline, not floated. So I have no idea what to put in the CSS to position the sub-menu actually underneath its parent element. Most examples I've seen have position:absolute but that seems to keep it at the left. I've tried various methods of hiding and showing (display:, left:) but can't seem to find that magic combination.
Here I only have the one sub-list, actually, but what if I had sublists for all of them?
Thanks for any tips or links to examples...

To make position: absolute elements position relative to their parent, make the parent position: relative.
In your case:
nav ul#primary>li {
display: inline;
padding:5px 0;
margin-left:0;
position: relative;
}
Demo: http://jsfiddle.net/MKtTN/3/

Related

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

Make <li> fit the width of the <ul> using CSS

I'm trying to make the <li> fit the width of the <ul> but even with width:auto it doesn't work at all, and I don't know why. I tried to use display:inline-block but this is the same. I don't know how many tabs I will have so this is why I am not using a percentage directly.
I would like to display the list inline when I display the page on a desktop and display one li per line when I am on a smartphone (with media queries).
I have this:
<ul id='menu'>
<li class="button"><a class='current' href='http://'>Home</a></li>
<li class="button"><a href='http://'>Products</a></li>
<li class="button"><a href='http://'>Support</a></li>
<li class="button"><a href='http://'>Contact</a></li>
<li class="button"><a href='http://'>Contact</a></li>
</ul>
and my CSS looks like this:
ul#menu
{
margin:0;
padding:0;
list-style-type:none;
width:100%;
position:relative;
display:block;
height:30px;
font-size:12px;
font-weight:bold;
font-family:Arial, Helvetica, sans-serif;
/*border-bottom:1px solid #000000;
border-top:1px solid #000000;*/
}
li.button {
background:transparent url(../images/nav_bg.png) repeat-x top left;
height:30px;
width:auto;
}
ul#menu li
{
display:inline-block;
margin:0;
padding:0;
width:auto;
}
ul#menu li a
{
display:inline-block;
color:#999999;
text-decoration:none;
font-weight:bold;
padding:8px 20px 0 20px;
width:auto;
}
ul#menu li a:hover
{
color:#FFFFFF;
height:22px;
background:transparent url(../images/nav_bg.png) 0px -30px no-repeat;
}
ul#menu li a.current
{
display:inline-block;
height:22px;
background:transparent url(images/nav_bg.png) 0px -30px no-repeat;
margin:0;
}
I've found this way to deal with single-line full-width ul where an undefined number of li elements need to be spaced out evenly:
ul {
width: 100%;
display: table;
table-layout: fixed; /* optional */
}
ul li {
display: table-cell;
width: auto;
text-align: center;
}
Basically, it emulates a table. Works in Gecko, Webkit, IE8+.
For IE7 and downwards you should use some inline-block hackery :)
JSFiddle
Since the li count can change, I can only think of accomplishing this with javascript/jquery as you suggested. Just divide 100 by the # of li's and set the width on each one.
var width = Math.floor(100 / $("ul#menu li").size());
$("ul#menu li").css('width', width + "%");
You will probably have to play with the width depending on padding and what not.
As a side note, If you haven't already, I recommend getting a tool like firebug, which will let you edit css and execute js on the fly. It is infinitely useful for fine tuning appearances.
If you want to fill the width of the <ul> with the five <li>s, you will have to give those <li>s a width of 20% each.
Note that you need to change some other details of the CSS if you want to make this work; e.g. with a display:inline-block you make the spaces between the <li> count, so the total width of the <ul> content will be more than 100% wide. I'd suggest removing the display:inline-block and giving them float:left.
Edit: Or do you want them to be distributed proportionally according to their contents? That would be a different challenge.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
body{
margin:0 auto;
}
.main{
width:650px;
border:1px solid red;
padding:5px;
}
ul {
padding:0;
margin:0;
width: 100%;
border-bottom: 0;
}
li{
display: table-cell;
width: 1%;
float: none;
border:1px solid green;
margin:2px;
padding:10px;
text-align:center;
}
</style>
</head>
<body>
<div class="main">
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
<li>Link 5</li>
</ul>
</div>
</body>
</html>
#menu {
padding: 0;
margin: 0;
border: 1px solid red;
position: absolute;
}
#menu li {
list-style-type: none;
float: left;
position: relative;
padding-right: 10px;
}
#menu li a {
text-decoration: none;
}
<ul id="menu">
<li>1A1CASĂ </li>
<li>H1TML-CSS </li>
<li>J1VASCRIPT </li>
<li>PHP </li>
<li>TESTE </li>
<li>CONTACT </li>
</ul>
Wow stumbled upon a very old question here.
For anyone also seeing this and scrolling down here, in 2022 this is easily doable via flexbox.
#menu {
display: flex;
gap: 1rem;
}
li {
list-style-type: none;
}
<ul id='menu'>
<li class="button"><a class='current' href='http://'>Home</a></li>
<li class="button"><a href='http://'>Products</a></li>
<li class="button"><a href='http://'>Support</a></li>
<li class="button"><a href='http://'>Contact</a></li>
<li class="button"><a href='http://'>Contact</a></li>
</ul>
try below css:
style.css (line 87)
ul#menu li {
float: left;
margin: 0;
padding: 6px 0;
width: 11.1%;
}
style.css (line 113)
ul#menu li a.current {
background: url("images/nav_bg.png") no-repeat scroll 0 -30px transparent;
height: 22px;
margin: 0;
}
style.css (line 95)
ul#menu li a {
color: #999999;
font-weight: bold;
padding: 8px 20px 0;
text-decoration: none;
width: auto;
}
see screen shot:

how to make sub menu appear when hover over link?

how do i make a sub menu dissapear and appear when i hover over a link?
this is my menu:
<div class="sideMenu2">
<ul>
<li><a href>retail</a>
<ul class="subsideMenu2">
<li>cabot circus</li>
<li>st. stephen's</li>
<li>silverburn</li>
<li>braehead</li>
</ul>
</li>
<li><a href>sports & leisure</a>
<ul class="subsideMenu2">
</ul>
</li>
</ul>
</div>
This is my current css:
.sideMenu2 ul li.on a
{
height:2em;
padding-top: 2px;
background:url(../images/point.png) no-repeat;
font-weight:bold;
}
.sideMenu2 ul
{
padding: 15px 0px 0px 0px;
list-style-type:none;
font-size:0.9em;
width:20em;
color:#fff;
margin-left:-10px;
}
.sideMenu2 ul a{
padding: 2px 20px 0px 0px;
color:#fff;
text-decoration:none;
float:left;
width:19.2em;
}
.sideMenu2 li a
{
height:2em;
padding-top: 1px;
padding-left:15px;
}
.sideMenu2 li a:hover{
background:url(../images/point.png) no-repeat;
cursor:pointer;
padding-left:-15px;
}
.subsideMenu2 {
display: none;
}
.sideMenu2 li:hover .subsideMenu2 {
display: block;
}
But won't work in old Internet Explorer, for them the only option is javascript.
see this example script of header menu dropdwon style
http://bit.ly/1abEJ9o

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.

CSS style fix for active element

First of I am new to CSS and don't seem to understand how classes interact with id's, thats why I can not get the following menu to work.
<div id="navmenu">
<ul>
<li>Home</li>
<li>Menu2</li>
<li>Menu3</li>
</ul>
</div>
This is my CSS:
#navmenu ul {
margin: 0;
padding: 0;
list-style-type: none;
list-style-image: none;
}
#navmenu li {
width:114px;
text-align:center;
float:left;
}
#navmenu ul li a {
text-decoration:none;
color: white;
background: #CE140B;
}
#navmenu a {
padding-top:4px;
padding-bottom:4px;
display:block;
width:100%;
}
#navmenu ul li a:hover {
color: #CE140B;
background: white;
}
This changes background and foreground color when the mouse is hovered over a menu item.
Now i wanted to add an active class to this, so that when I am on the Home page, the Home menu item looks the same as when it is hovered. The following code does not work.
I have tried changing the menu to this:
<li><a class="active" href="#">Home</a></li>
and also
<li class="active">Home</li>
and my CSS to:
#navmenu ul li a:hover a:active {
color: #CE140B;
background: white;
}
and
#navmenu ul li a:hover li:active {
color: #CE140B;
background: white;
}
Neither works. Thanks for your help on getting this to work.
Either
li.active:hover {
}
Or
a.active:hover {
}
Should work

Resources