I have an ul that works fine, but when I add a nested ul the li above, moves. Does anyone know why? how to solve it?
I have the example here: http://jsfiddle.net/y5DtE/
HTML:
<ul>
<li> first
<ul>
<li> 1.2 </li>
</ul>
</li>
<li> second </li>
<li> third eally, really long </li>
</ul>β
CSS:
body {
margin:0px;
}
ul {
margin:40px auto;
list-style-type:none;
padding:0;
text-align: center;
}
ul li {
padding: 0 15px;
margin-right: 5px;
background-color: #f2f2f2;
display: inline-block;
height: 30px;
line-height: 30px;
font-family: verdana;
font-size:10px;
color: #666
}
ul li:last-child { margin-right: 0px; }
ul li ul {
margin:5px 0;
}β
li {
position: relative;
}
ul ul {
position: absolute;
left: 0;
}
To make sublist go under parent element apply this:
ul li {
display: block;
float: left;
}
To prevent floating of sub items add the following rule:
ul li ul li{
float: none;
}
Related
I have a dropdown list item in my navbar and can't get the dropdown section to align underneath the parent link. I am trying to use just css and know I've done it before, it's just stumping me at the moment. None of the other examples I've come across use the same menu format so it's been troubling trying to force fit pieces of code. Please help me with this easy solution
HTML
<div id="navbar">
<li>Home</li><!--
--><li>Link2</li><!--
--><li>Link3</li><!--
--><li><a href="#">Link4
<ul>
<li>SubLink1</li><br />
<li>SubLink2</li><br />
<li>SubLink3</li><br />
<li>SubLink4</li>
</ul>
</a></li><!--
--><li>Link5</li>
</div>
CSS
#navbar {
width:75%;
margin:0px auto;
text-align:right;
position:relative;
top:218px;
}
#navbar li {
list-style:none;
display:inline;
position:relative;
}
#navbar a {
background-color:#862D59;
font-size:18px;
width:60px;
margin:0px;
padding:10px 15px;
color:#FFF;
text-decoration:none;
text-align:center;
}
#navbar a:hover {
background-color:#602040;
border-bottom:solid 4px #969;
}
#navbar li ul {
display:none;
}
#navbar li:hover ul {
position:absolute;
display:block;
}
Working Example
https://jsfiddle.net/o6Ldutp5/
Firstly, you should use a reset css of some kind to remove the default margin / padding attached to ul & li.
Then validate your HTML, it contained a number of errors such as missing the opening ul etc.
Then it's just a matter of using position:absolute and appropriate values.
top:100% will place the menu directly below the li parent (with position:relative) regardless of the height of the li.
left:0 will align the left edge of the submenu to the left side of the parent li.
#navbar {
margin: 0px auto;
text-align: right;
}
ul,
li {
margin: 0;
padding: 0;
}
#navbar li {
list-style: none;
display: inline-block;
position: relative;
}
#navbar a {
background-color: #862D59;
font-size: 18px;
width: 60px;
margin: 0px;
padding: 10px 15px;
color: #FFF;
text-decoration: none;
text-align: center;
display: block;
}
#navbar a:hover {
background-color: #602040;
border-bottom: solid 4px #969;
}
#navbar li ul {
display: none;
position: absolute;
top: 100%;
left: 0;
}
#navbar li:hover ul {
display: block;
}
<div id="navbar">
<ul>
<li>Home
</li>
<li>Link2
</li>
<li>Link3
</li>
<li>Link4
<ul>
<li>SubLink1
</li>
<li>SubLink2
</li>
<li>SubLink3
</li>
<li>SubLink4
</li>
</ul>
</li>
<li>Link5
</li>
</ul>
</div>
I've written my own minimal CSS without the styling, try replacing your whole CSS with this -
I've also edited your HTML by removing the comments and <br /> tags
div#navbar li {
display: inline-block;
}
div#navbar li ul {
width: 200px;
position: absolute;
display: none;
top: 10px;
}
div#navbar li ul li {
display: block;
width: 150px;
}
div#navbar li:hover ul {
display: block;
}
ul,ol,li {
margin-left: 0;
padding-left: 0;
}
Here is the fiddle
i want to center align whats in the nav bar( so that the img is the center of the nav bar. I know that i have float: left; but if i dont, the(left thing, right thing) will drop down to the bottom edge of the img. So what i want is to keep float left, but be able to display: inline-block, or something equal. I also want the dropdown bar for the (left thing) to start at the img's left side, and then build out to the right side.
demo fiddle
HTML
<div id="nav">
<div id="container">
<ul>
<li>
Left thing
<ul>
<li><----- want it to go this way
</li>
<li>i want this to start under left thing
</li>
</ul>
</li>
<li>
<img src="http://www.jonathanjeter.com/images/Square_200x200.png" style="height:70px" />
</li>
<li>
Right thing
<ul>
<li>This starts right
</li>
<li>And this is right
</li>
</ul>
</li>
</ul>
</div>
</div>
CSS
* {
padding: 0;
margin: 0;
}
#body {
padding: 0;
margin: 0;
font-family: Arial;
font-size: 17px;
}
#nav {
background-color: 72776A;
width: 100%;
position:fixed;
height:50px;
}
#nav ul {
list-style-type: none;
padding: 0;
margin: 0;
position: relative;
display:block;
}
#nav ul li {
float:left;
}
#container {
text-align:;
}
#nav ul li:hover {
background-color: #333;
}
#nav ul li a, visited {
color: ACD661;
display: block;
padding: 15px;
text-decoration: none;
}
#nav ul li:hover ul {
display: block;
}
#nav ul ul {
display: none;
position:absolute;
color: red;
border: 1px solid black;
}
#nav ul ul li {
display: block;
}
#nav ul ul li a:hover {
color: #699;
}
replace
#container {
width: 270px;
margin: 0px auto;
}
Check this fiddle
Before talk about solution let's talk about your CSS, i removed repeats for margin:0, padding:0, highlighted forgetted selectors or mistyping. You need to precise a width to your container div and add margin-left and margin-right auto to achieve what you want :
/* {
padding: 0;
margin: 0;
} not the best solution, everybody don't need this rule */
/* instead here a group of selectors */
body,
#nav ul {
padding: 0;
margin: 0;
}
/*#*/body { /* you mean just body right ? */
font-family: Arial;
font-size: 17px;
}
#nav {
background-color: #72776A; /* you forgot # here */
width: 100%;
position:fixed;
height:50px; /*it's smaller than your image*/
}
#nav ul {
list-style-type: none;
position: relative;
/*display:block; don't need */
}
#nav li {
float:left;
}
#container {
/*text-align:; seems it's missing something here ? */
margin: 0 auto;
width: 300px;
}
#nav ul li:hover {
background-color: #333;
}
#nav ul li a,
#nav ul li a:hover,
#nav ul li a:visited {/ { /* you mean a:visited ? */
color: #ACD661; /* here again # forgot */
display: block;
padding: 15px;
text-decoration: none;
}
#nav li:hover ul { /*ul don't need (i mean #nav ul li...) */
display: block;
}
#nav ul ul {
display: none;
position:absolute;
color: red;
border: 1px solid black;
}
#nav li li { /* shorter then ul ul li */
display: block;
}
#nav a li a:hover {
color: #699;
}
You can see code here
Just learning HTML and CSS and wondering how I could have an expandable list within an expandable list. I have the problem that the second expandable list is already expanded when I click the first expandable list. Yo dawg, I heard you like expandable lists....
Here is my code:
<!DOCTYPE html>
<head>
<title>Sample</title>
</head>
<style>
body {
padding: 0;
margin: 0;
font-size: 18px;
font-family: Arial;
}
#nav {
background-color: black;
}
#navbar {
margin: auto;
width: 960px;
text-align:left;
}
#nav ul{
position: relative;
list-style-type: none;
padding:0;
margin: 0;
}
#nav ul li {
display: inline-block;
}
#nav ul li a {
text-decoration: none;
color: white;
padding: 15px;
display: block;
}
#nav ul li:hover {
background-color: silver;
}
#nav ul ul{
display: none;
margin: 0;
background-color: black;
position: absolute;
}
#nav ul li:hover ul {
display: block;
}
#nav ul ul li {
display:block;
}
#nav ul ul ul{
display: none;
position: absolute;
margin-left: 110px;
margin-top: -52px;
background-color: black;
}
#nav ul ul li:hover ul{
display: block;
}
#nav ul ul ul li {
display: block;
}
</style>
<body>
<div id="nav">
<div id="navbar">
<ul>
<li>Home</li>
<li>Contact</li>
<li>About</li>
<li>Social
<ul>
<li>Facebook</li>
<li>Twitter</li>
<li>YouTube
<ul>
<li>Our Page</li>
<li>Top Videos</li>
<li>Popular</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</body>
Use the child (direct descendant) selector > instead of the descendant selector
#nav ul>li:hover>ul {
display: block;
}
Demo
What you are currently doing is saying: when hovering over the li set any decendant ul, no matter what the depth, to display:block.
The new code says: when hovering over the li set any uls that are children (or direct descendants) of that li to display:block. Any uls nested deeper will be untouched.
I have been trying to add a drop down menu to this code but always seem to get turned around. I just want a basic look to the subnav with a simple rollover effect. Every time i try different code it uses home image in the drop down menu and will not disappear when it is not hovered over. Ideas?
HTML:
<ul class="navbar">
<li class="navbar1">Home
<ul class="subnav">
<li>Menu 1 </li>
<li>Menu 2 </li>
</ul>
</li>
</ul>
CSS:
ul.navbar {
width:1000px;
list-style:none;
height:40px;
}
ul.navbar li {
display:inline;
}
ul.navbar li a {
height:40px;
float:left;
text-indent:-9999px;
}
/* Home 0 */
ul.navbar li.navbar1 a {
width:86px;
background:url(../pelican%20outfitters/navbar2.fw.png)
no-repeat 0 0;
}
ul.navbar li.navbar1 a:hover {
background-position:0 -40px;
}
ul.navbar li.navbar1 a.current {
background-position:0 -80px;
}
HTML
<nav>
<ul class="navbar">
<li class="navbar1">Home
<ul class="subnav">
<li>Menu 1
</li>
<li>Menu 2
</li>
</ul>
</li>
</ul>
</nav>
CSS
nav {
margin: 20px auto;
}
nav ul ul {
display: none;
}
nav ul li:hover > ul {
display: block;
}
nav ul li
{
width:100px;
}
ul li ul li
{ width:200px;
}
nav ul {
font-size: 25px;
background: white;
padding: 0px;
border-radius: 10px;
border-style: solid;
list-style: none;
position: relative;
display: inline-table;
}
nav ul:after {
content:"";
clear: both;
display: block;
}
nav ul li {
float: left;
}
nav ul li:hover {
background: black;
position:relative;
z-index:1;
}
nav ul li:hover a {
color: white;
position:relative;
z-index:1;
}
nav ul li a {
display: block;
padding: 15px 20px;
color: black;
text-decoration: none;
}
nav ul ul {
background: #000000;
border-radius: 0px 0px 10px 10px;
padding: 0;
position: absolute;
top: 100%;
}
nav ul ul li {
float: none;
}
nav ul ul li a {
padding: 15px 20px;
}
nav ul ul li a:hover {
background: #2E2E2E;
border-radius: 10px;
}
Output:
Working Fiddle
You should delete the text-indent:-9999px and add this to your css
Delete row:
ul.navbar li a { text-indent:-9999px }
Css:
.navbar li ul {display:none;}
.navbar li:hover ul {display:block;}
Than you have a basic navbar with hidden subnavs.
From here you can try it with your image.
The demo is your code with the new code..
DEMO
More like you want is, dont delete the css.. but only add those 2 lines and this 1:
.navbar li:hover li a{ text-indent:1px; background:white; }
DEMO 2 (without your img (don't know what it is)).
Latest update after the fiddle comment:
You should specify your html and css.. a just added a class to the first link class="home" and to accomodations class="accomodations"
And changed it in the css..
/* Home */
ul.navbar li.navbar1 a.home {
width:86px;
background:url(http://s12.postimg.org/rszejjscd/navbar2_fw.png)
no-repeat 0 0;
}
/* Accomodations */
ul.navbar li.navbar2 a.accomodations {
width:220px;
background: url(http://s12.postimg.org/rszejjscd/navbar2_fw.png) no-repeat -86px 0;
}
DEMO 3
How do I make nested li's the same width?
When I use the below code each nested li is only as wide as it's text + margin.
I'd like all of the li's to be as wide as the widest li under the parent ul.
eg:
<ul id="menu">
<li Menu a</li>
<li Menu b</li>
<li Nested Menu
<ul>
<li <a href="#" title="Menu Item">Menu Item</li>
<li Long Menu Item</li>
<li Longer Menu Item</li>
</ul>
</li>
<li Menu z</li>
</ul>
with css:
<style type="text/css" media="all">
* {
padding:0;
margin:0;
}
body, html {
width: 100%;
height: 100%;
}
#wrapper {
width: 800px;
height: 100%;
margin: auto;
}
#menu {
margin: 0 0 0 8px;
padding: 0;
font-size: 14px;
font-weight: normal;
}
#menu ul {
list-style-type:none;
list-style-position:outside;
position:relative;
z-index:300;
height: 32px;
font-weight:bold;
white-space: nowrap;
padding:0;
}
#menu a {text-decoration:none;
line-height: 32px;
}
#menu a:hover {
}
#menu li {
float:left;
position:relative;
display: inline;
height: 100%;
list-style-type: none;
padding: 0 20px;
background: #ccc;
}
#menu ul {
position:absolute;
display:none;
left:0px;
background: #BDCCD4;
width:100%;
}
#menu ul a, #menu li a {
display: block;
}
#menu li ul {
background: #BDCCD4;
display:block;
}
#menu li ul a {
font-weight: normal;
height:auto;
float:left;
}
#menu ul ul {
padding: 0 9px;
display:block;
}
#menu li ul li {
padding: 0 9px;
background: #BDCCD4;
}
#menu li:hover {
background: #ddd;
height: 32px;
}
#menu li li:hover, #menu li li li:hover {
background: #ddd;
height: 32px;
}
#menu li a:link, #menu li a:visited {
text-decoration: none;
color: #003E7E;
margin: auto;
}
Simply adding width: 100% for #menu li ul li works for me. To make it work for even longer items, use width: auto on #menu li ul. EDIT 2: Added padding workaround.
The new CSS:
<style type="text/css" media="all">
* {
padding:0;
margin:0;
}
body, html {
width: 100%;
height: 100%;
}
#wrapper {
width: 800px;
height: 100%;
margin: auto;
}
#menu {
margin: 0 0 0 8px;
padding: 0;
font-size: 14px;
font-weight: normal;
}
#menu ul {
list-style-type:none;
list-style-position:outside;
position:relative;
z-index:300;
height: 32px;
font-weight:bold;
white-space: nowrap;
padding:0;
}
#menu a {text-decoration:none;
line-height: 32px;
}
#menu a:hover {
}
#menu li {
float:left;
position:relative;
display: inline;
height: 100%;
list-style-type: none;
padding: 0 20px;
background: #ccc;
}
#menu ul {
position:absolute;
display:none;
left:0px;
background: #BDCCD4;
width:100%;
}
#menu ul a, #menu li a {
display: block;
}
#menu li ul {
background: #BDCCD4;
display:block;
width: auto;
}
#menu li ul a {
font-weight: normal;
height:auto;
float:left;
}
#menu ul ul {
padding: 0 0 0 9px;
display:block;
}
#menu li ul li {
padding: 0 9px;
background: #BDCCD4;
width: 100%;
}
#menu li:hover {
background: #ddd;
height: 32px;
}
#menu li li:hover, #menu li li li:hover {
background: #ddd;
height: 32px;
}
#menu li a:link, #menu li a:visited {
text-decoration: none;
color: #003E7E;
margin: auto;
}
The result is here: http://jsfiddle.net/y83zm/2/
EDIT 2 Added fix to solve a weird padding issue, see http://jsfiddle.net/y83zm/5/
You'll need to use JavaScript to set all LIs the same width as the widest LI. Here's the code if you want to use the jQuery library:
$(document).ready(function(){
$("#menu > li > ul").each(function() { // Loop through all the menu items that got submenu items
var Widest=0; // We want to find the widest LI... start at zero
var ThisWidth=0; // Initiate the temporary width variable (it will hold the width as an integer)
$($(this).children()).each(function() { // Loop through all the children LIs in order to find the widest
ThisWidth=parseInt($(this).css('width')); // Grab the width of the current LI
if (ThisWidth>Widest) { // Is this LI the widest?
Widest=ThisWidth; // We got a new widest value
}
});
Widest+='px'; // Add the unit
$(this).parent().css('width',Widest);
$(this).children().css('width',Widest);
});
});
CSS change:
#menu li ul li {
padding: 0 9px;
background: #BDCCD4;
padding: 0 20px;
}
Check it out at JSFiddle.
Edit: Fixed my misunderstanding. :)
There would be a very simple dynamic solution. To your CSS, as you posted it in the Question, just add
#menu ul {
display: inline-block;
min-width: 100px;
}
#menu ul li, #menu ul li a{
width: 100%;
display:block;
}
and then it will be exactly as you want it to be.
You can see how it looks here:
<style type="text/css" media="all">
* {
padding:0;
margin:0;
}
body, html {
width: 100%;
height: 100%;
}
#wrapper {
width: 800px;
height: 100%;
margin: auto;
}
#menu {
margin: 0 0 0 8px;
padding: 0;
font-size: 14px;
font-weight: normal;
}
#menu ul {
list-style-type:none;
list-style-position:outside;
position:relative;
z-index:300;
height: 32px;
font-weight:bold;
white-space: nowrap;
padding:0;
}
#menu a {text-decoration:none;
line-height: 32px;
}
#menu a:hover {
}
#menu li {
float:left;
position:relative;
display: inline;
height: 100%;
list-style-type: none;
padding: 0 20px;
background: #ccc;
}
#menu ul {
position:absolute;
display:none;
left:0px;
background: #BDCCD4;
width:100%;
}
#menu ul a, #menu li a {
display: block;
}
#menu li ul {
background: #BDCCD4;
display:block;
}
#menu li ul a {
font-weight: normal;
height:auto;
float:left;
}
#menu ul ul {
padding: 0 9px;
display:block;
}
#menu li ul li {
padding: 0 9px;
background: #BDCCD4;
}
#menu li:hover {
background: #ddd;
height: 32px;
}
#menu li li:hover, #menu li li li:hover {
background: #ddd;
height: 32px;
}
#menu li a:link, #menu li a:visited {
text-decoration: none;
color: #003E7E;
margin: auto;
}
#menu ul {
display: inline-block;
min-width: 100px;
}
#menu ul li, #menu ul li a{
width: 100%;
display:block;
}
<ul id="menu">
<li Menu a</li>
<li Menu b</li>
<li Nested Menu
<ul>
<li <a href="#" title="Menu Item">Menu Item</li>
<li Long Menu Item</li>
<li Longer Menu Item</li>
</ul>
</li>
<li Menu z</li>
</ul>
To make all of the list items the same length as the longest, you will need to manually set the widths. There is no pure CSS method of achieving this automatically as far as I know.
li{width:100%} Will make the list items fill the width of their container. If that is not set, then it will be the width of the user's browser window.
A simple jQuery solution worked for me:
$(document).ready(function(){
$('.sub-menu').each(function(){
$(this).width(2000);
var width = 0;
$(this).children('li').each(function(){
if ($(this).children('a').width() > width)
width = $(this).children('a').width();
});
$(this).width(width);
});
});
I used following CoffeeScript to achieve described behavior:
$ ->
menu_toggle = (e, show) ->
ul = $(e).find('ul')
ul.toggle()
computed = ul.hasClass 'computed_width'
if show && !computed
ul.width 2000 # enormous with to be sure that liβsβ texts are not wrapped
max_width = 0
ul.find('li').each ->
li = $(this)
width = li.width()
max_width = width if width > max_width
ul.width max_width + 30 if max_width # 20 is 2 * padding + some reserve
ul.toggleClass 'computed_width' # no need to compute every time
$('li').has('ul').hover ->
menu_toggle this, true
, ->
menu_toggle this, false