SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    5
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Nav menu lists not floating as expected

    Hi,

    I'm trying to create a navigation menu with a subnav containing floated lists. I'm using a floated ul inside an absolute positioned div, inside a floated li with relative positioning. The div needs to be absolutely positioned, I'm using relative positioning on the li because I want the absolute positioned divs to be placed relative to the list items and not the overall page. If I remove position: relative from the li then the lists float side by side in the div (exactly what I want) but the div is then not placed under the relevant menu item. With position: relative the div is placed where I want but the lists are stacked on top of each other. This is all in Firefox and Chrome.

    If I explicitly define the width on the div to be big enough to contain both lists side by side, it works properly, but this isn't much help as the lists will be dynamically generated.

    Here's some test code I've been using trying to simplify the problem as much as possible:

    Code:
    <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Home Page</title>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link media="all" href="teststyles.css" type="text/css" rel="stylesheet">
    </head>
    <body>
    <ul>
    <li class="navli"><a href="listtest.html">item1</a></li>
    <li class="navli"><a href="listtest.html">item2</a>
    <div class="listcontainer">
    <ul class="testlist col1">
    	<li><a href="listtest.html">test1</a></li>
    	<li><a href="listtest.html">test2</a></li>
    	<li><a href="listtest.html">test3</a></li>
    	<li><a href="listtest.html">test4</a></li>
    	<li><a href="listtest.html">test5</a></li>
    	<li><a href="listtest.html">test6</a></li>
    </ul>
    <ul class="testlist col2">
    	<li><a href="listtest.html">2test1</a></li>
    	<li><a href="listtest.html">2test2</a></li>
    	<li><a href="listtest.html">2test3</a></li>
    	<li><a href="listtest.html">2test4</a></li>
    	<li><a href="listtest.html">2test5</a></li>
    	<li><a href="listtest.html">2test6</a></li>
    </ul>
    </div>
    </li>
    <li class="navli"><a href="listtest.html">item3</a>
    </li>
    </ul>
    </body>
    </html>
    Code:
    .navli {
    	position: relative;
    	float: left;
    	padding: 10px 20px;
    }
    .listcontainer {
    	background-color: blue;
    	position: absolute;
    	padding: 5px;
    	left: 0px;
    	top: 30px;
    }
    .testlist {
    	color: red;
    	background-color: orange;
    	float: left;
    	width: 200px;
    }
    .col2 {
    	color: green;
    	background-color: pink;
    }
    Please help!

  2. #2
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,183
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    The only sure way you can accomplish what you need the child UL elements to do would be to define a static width on the parent DIV as by default absolutely positioned elements don't inherit any height or width which would cause floats to act like the display property with a value of block. Have a look at the following jsFiddle which i have added the static width to:

    http://jsfiddle.net/chrisupjohn/RHByH/

    The only sure way to to accomplish this would be to use JavaScript and calculate the total width of the child elements and then set it on the parent DIV which is a dirty fix but will work.
    Blog/Portfolio | Evolution Xtreme | DFG Design | DFG Hosting | CSS-Tricks | Stack Overflow | Paul Irish
    Having lame problems with your code? Let us help by using a jsFiddle

  3. #3
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    5
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok thanks for the help. I've hacked together some javascript which seems to work ok, is there anything stupid I've done here that might break anything? I'm executing it via body onload=.

    Code:
    function setsubnavwidth() {
    	//Sets width on container divs for navigation submenus
    	var subnavdivs=document.getElementsByClassName("listcontainer");
    	for (var i = 0; i < subnavdivs.length; i++) {
    		var subnavuls=subnavdivs[i].childNodes;
    		var totalWidth=0
    		for (var j = 0; j < subnavuls.length; j++) {
    			if (subnavuls[j].tagName=="UL") {
    				totalWidth = totalWidth+subnavuls[j].offsetWidth
    			}
    		}
    		subnavdivs[i].style.width=totalWidth;
    	}
    }

  4. #4
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    39,803
    Mentioned
    158 Post(s)
    Tagged
    4 Thread(s)
    Hi,

    You can do it quite easily like this without javascript.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>Home Page</title>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link media="all" href="teststyles.css" type="text/css" rel="stylesheet">
    <style>
    ul {
    	margin:0;
    	padding:0;
    	list-style:none
    }
    
    .navli {
    	position: relative;
    	float: left;
    	padding: 10px 20px;
    }
    .listcontainer {
    	background-color: blue;
    	position: absolute;
    	padding: 5px;
    	left: 0px;
    	top: 30px;
    	white-space:nowrap;
    }
    .testlist {
    	color: red;
    	background-color: orange;
    	display:inline-block;
    	width: 200px;
    	white-space:normal;
    }
    * html .testlist{display:inline}
    *+html .testlist{display:inline}
    .col2 {
    	color: green;
    	background-color: pink;
    }
    </style>
    </head>
    <body>
    <ul>
    		<li class="navli"><a href="listtest.html">item1</a></li>
    		<li class="navli"><a href="listtest.html">item2</a>
    				<div class="listcontainer">
    						<ul class="testlist col1">
    								<li><a href="listtest.html">test1</a></li>
    								<li><a href="listtest.html">test2</a></li>
    								<li><a href="listtest.html">test3</a></li>
    								<li><a href="listtest.html">test4</a></li>
    								<li><a href="listtest.html">test5</a></li>
    								<li><a href="listtest.html">test6</a></li>
    						</ul>
    						<ul class="testlist col2">
    								<li><a href="listtest.html">2test1</a></li>
    								<li><a href="listtest.html">2test2</a></li>
    								<li><a href="listtest.html">2test3</a></li>
    								<li><a href="listtest.html">2test4</a></li>
    								<li><a href="listtest.html">2test5</a></li>
    								<li><a href="listtest.html">2test6</a></li>
    						</ul>
    				</div>
    		</li>
    		<li class="navli"><a href="listtest.html">item3</a> </li>
    </ul>
    </body>
    </html>

  5. #5
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    5
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the reply, but this doesn't seem to work for me?

    Quote Originally Posted by Paul O'B View Post
    Hi,

    You can do it quite easily like this without javascript.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>Home Page</title>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link media="all" href="teststyles.css" type="text/css" rel="stylesheet">
    <style>
    ul {
    	margin:0;
    	padding:0;
    	list-style:none
    }
    
    .navli {
    	position: relative;
    	float: left;
    	padding: 10px 20px;
    }
    .listcontainer {
    	background-color: blue;
    	position: absolute;
    	padding: 5px;
    	left: 0px;
    	top: 30px;
    	white-space:nowrap;
    }
    .testlist {
    	color: red;
    	background-color: orange;
    	display:inline-block;
    	width: 200px;
    	white-space:normal;
    }
    * html .testlist{display:inline}
    *+html .testlist{display:inline}
    .col2 {
    	color: green;
    	background-color: pink;
    }
    </style>
    </head>
    <body>
    <ul>
    		<li class="navli"><a href="listtest.html">item1</a></li>
    		<li class="navli"><a href="listtest.html">item2</a>
    				<div class="listcontainer">
    						<ul class="testlist col1">
    								<li><a href="listtest.html">test1</a></li>
    								<li><a href="listtest.html">test2</a></li>
    								<li><a href="listtest.html">test3</a></li>
    								<li><a href="listtest.html">test4</a></li>
    								<li><a href="listtest.html">test5</a></li>
    								<li><a href="listtest.html">test6</a></li>
    						</ul>
    						<ul class="testlist col2">
    								<li><a href="listtest.html">2test1</a></li>
    								<li><a href="listtest.html">2test2</a></li>
    								<li><a href="listtest.html">2test3</a></li>
    								<li><a href="listtest.html">2test4</a></li>
    								<li><a href="listtest.html">2test5</a></li>
    								<li><a href="listtest.html">2test6</a></li>
    						</ul>
    				</div>
    		</li>
    		<li class="navli"><a href="listtest.html">item3</a> </li>
    </ul>
    </body>
    </html>

  6. #6
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    39,803
    Mentioned
    158 Post(s)
    Tagged
    4 Thread(s)
    In what way did it not work?

    Did I misunderstand what you wanted (quite likely)?

    I thought you wanted the nested uls to align in horizontal blocks like the attached image which is what the code produces. Did I miss something important again?
    Attached Images Attached Images

  7. #7
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    5
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No you understood correctly. I just tried again and see it works in Chrome/Safari but not in Firefox/IE. Here's what I'm seeing:
    Attached Images Attached Images

  8. #8
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    39,803
    Mentioned
    158 Post(s)
    Tagged
    4 Thread(s)
    Hi,

    Strange it's working more or less everywhere for me except for a bug in IE7 which I've addressed in the code below. The version I posted above was working in ie5.5, 1e6, 1e8, 1e9, firefox 3.6, 4, 5, 6,7,8, safari and chrome pc and mac.

    It won't work in Firefox 2 but that's dead and buried long ago.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>Home Page</title>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link media="all" href="teststyles.css" type="text/css" rel="stylesheet">
    <style>
    ul {
    	margin:0;
    	padding:0;
    	list-style:none
    }
    .navli {
    	position: relative;
    	float: left;
    	padding: 10px 20px;
    }
    .listcontainer {
    	background-color: blue;
    	position: absolute;
    	padding: 5px;
    	left: 0px;
    	top: 30px;
    	white-space:nowrap;
    }
    .testlist {
    	color: red;
    	background-color: orange;
    	display:inline-block;
    	width: 200px;
    }
    .testlist li{white-space:normal}
    * html .testlist{display:inline}
    *+html .testlist{display:inline;}
    .col2 {
    	color: green;
    	background-color: pink;
    }
    </style>
    </head>
    <body>
    <ul>
    		<li class="navli"><a href="listtest.html">item1</a></li>
    		<li class="navli"><a href="listtest.html">item2</a>
    				<div class="listcontainer">
    						<ul class="testlist col1">
    								<li><a href="listtest.html">test1</a></li>
    								<li><a href="listtest.html">test2</a></li>
    								<li><a href="listtest.html">test3</a></li>
    								<li><a href="listtest.html">test4</a></li>
    								<li><a href="listtest.html">test5</a></li>
    								<li><a href="listtest.html">test6</a></li>
    						</ul>
    						<ul class="testlist col2">
    								<li><a href="listtest.html">2test1</a></li>
    								<li><a href="listtest.html">2test2</a></li>
    								<li><a href="listtest.html">2test3</a></li>
    								<li><a href="listtest.html">2test4</a></li>
    								<li><a href="listtest.html">2test5</a></li>
    								<li><a href="listtest.html">2test6</a></li>
    						</ul>
    				</div>
    		</li>
    		<li class="navli"><a href="listtest.html">item3</a> </li>
    </ul>
    </body>
    </html>
    Did you change something in my code or have you got a very old browser version?

  9. #9
    SitePoint Member
    Join Date
    Nov 2011
    Posts
    5
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorted it, you left the link to my external stylesheet in, and since I was testing in the same folder that was breaking it. Thanks for the help, now to try and understand *why* it works

  10. #10
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    39,803
    Mentioned
    158 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Goom View Post
    Sorted it, you left the link to my external stylesheet in, and since I was testing in the same folder that was breaking it.
    lol - of course - I should have thought of that

    Thanks for the help, now to try and understand *why* it works
    The basics are that instead of floating the uls we make them inline-blocks which mean that they align side by side just like words would. They also have the same behaviour as words in that if you set white-space:nowrap then the words won't wrap to a new line and neither will the inline-block elements and that forces them to stay on the same line.

    The problem with absolute elements is that they are a "shrink to fit element" and therefore the floats don't line up horizontally as there is no actual space to the right of the float above. There was also a solution in setting the parent li to a great big width (or using large negative margins) and then hiding the overflow but would have caused some issues.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •