CSS Only MegaMenu


#1

Im trying to make a mega menu with CSS only. - my code for the menu is generated from db, and is based on nested lists. This is the generated HTML:

<h1>This is megaMenu:</h1>
<div id="megaMenu">
	<ul>
		<li class="first selected"><a href="index.cfm?id=298168">1 Menu Item</a><span></span>
			<ul>
				<li class="first"><a href="index.cfm?id=298172">1.1 Menu Item</a><span></span>
					<ul>
						<li class="first"><a href="index.cfm?id=298178">1.1.1 Article</a><span></span> </li>
						<li class=""><a href="index.cfm?id=298177">1.1.2 Article</a><span></span> </li>
						<li class="last"><a href="index.cfm?id=298176">1.1.3 Article</a><span></span> </li>
					</ul>
				</li>
				<li class="selected"><a href="index.cfm?id=298173">1.2 Menu Item</a><span></span>
					<ul>
						<li class="first"><a href="index.cfm?id=298184">1.2.1 Article</a><span></span> </li>
						<li class=""><a href="index.cfm?id=298183">1.2.2 Article</a><span></span> </li>
						<li class="selected"><a href="index.cfm?id=298182">1.2.3 Article</a><span></span> </li>
						<li class=""><a href="index.cfm?id=298181">1.2.4 Article</a><span></span> </li>
						<li class="last"><a href="index.cfm?id=298180">1.2.5 Article</a><span></span> </li>
					</ul>
				</li>
				<li class="last"><a href="index.cfm?id=298174">1.3 Menu Item</a><span></span>
					<ul>
						<li class="first"><a href="index.cfm?id=298187">1.3.1 Article</a><span></span> </li>
						<li class="last"><a href="index.cfm?id=298186">1.3.2 Article</a><span></span> </li>
					</ul>
				</li>
			</ul>
		</li>
		<li class=""><a href="index.cfm?id=298169">2 Menu Item</a><span></span>
			<ul>
				<li class="first"><a href="index.cfm?id=298592">2.1 Menu Folder</a><span></span>
					<ul>
						<li class="first"><a href="index.cfm?id=298597">2.1.1 Article</a><span></span> </li>
						<li class=""><a href="index.cfm?id=298596">2.1.2 Article</a><span></span> </li>
						<li class=""><a href="index.cfm?id=298595">2.1.3 Article</a><span></span> </li>
						<li class="last"><a href="index.cfm?id=298594">2.1.4 Article</a><span></span> </li>
					</ul>
				</li>
				<li class="last"><a href="index.cfm?id=298593">2.2 Menu Folder</a><span></span>
					<ul>
						<li class="first"><a href="index.cfm?id=298599">2.2.1 Article</a><span></span> </li>
						<li class="last"><a href="index.cfm?id=298598">2.2.2 Article</a><span></span> </li>
					</ul>
				</li>
			</ul>
		</li>
		<li class=""><a href="index.cfm?id=298170">3 Menu Item</a><span></span> </li>
		<li class="last"><a href="index.cfm?id=298171">4 Menu Item</a><span></span> </li>
	</ul>
</div>

my CSS so far is like this:

/* Wrapper */
#megaMenu {
	min-height: 400px;
	height: auto !important;
	height: 400px;
	float: left;
	clear: left;
	width: 900px;
	}

/* Level 1 */
#megaMenu ul {
	width: 900px;
	margin: 0;
	padding: 0;
	}
#megaMenu ul li {
	position: relative;
	list-style: none;
	width: auto;
	height: 30px;
	float: left;
	margin: 0;
	padding: 0;
	background: none;
	}
#megaMenu ul li a {
	display: inline-block;
	}
#megaMenu ul li span {}
/* Level 1 - Hover */
#megaMenu ul li:hover {}
#megaMenu ul li a:hover {}
/* Level 1 - Selected */
#megaMenu ul li.selected {}
#megaMenu ul li.selected a {}

/* Level 2 */
#megaMenu ul li ul {
	display: none;
	position: absolute;
	left: 0;
	top: 30px;
	xwidth: 600px;
	xbackground: #eee;
	float: left;
	}
#megaMenu ul li:hover ul {
	background: yellow;
	width: auto;
	}
#megaMenu ul li:hover ul li ul {background: none;/*remove inherited backgrounds*/}
#megaMenu ul li:hover ul {
	display: inline;
	position: absolute;
	left: 0;
	top: 30px;
	width: 960px;
	xbackground: #eee;
	float: left;
	}
#megaMenu ul li ul li {
	display: block;
	xfloat: left;
	width: 200px;
	xbackground: #CCC;
	}
#megaMenu ul li ul li.last {}
#megaMenu ul li ul li a {}
#megaMenu ul li ul li span {}
/* Level 2 - Hover */
#megaMenu ul li ul li:hover {}
#megaMenu ul li ul li a:hover {}
/* Level 2 - Selected */
#megaMenu ul li ul li.selected {}
#megaMenu ul li ul li.selected a {}

/* Level 3 */
#megaMenu ul li:hover ul li ul {
	display: inherit;
	float: none;
	xoverflow: hidden;
	background: none;
	}
#megaMenu ul li:hover ul li ul li {
	float: none;
	clear:both!important;
	}
#megaMenu ul li ul li ul li a {}
#megaMenu ul li ul li ul li span {}
/* Level 3 - Hover */
#megaMenu ul li ul li ul li:hover {}
#megaMenu ul li ul li ul li a:hover {}
/* Level 3 - Selected */
#megaMenu ul li ul li ul li.selected {}
#megaMenu ul li ul li ul li.selected a {}

My problem is that the ul that is the wrapper for second and third level do not go neatly around it like a square.

Is it possible to make ul nested 3 level lists as megamenu with only css - i know most use jquery - but i would rather make it with just css if possible - and i also can endure dropping IE6 to make it happend


#2

like this? http://www.visibilityinherit.com/code/mega-drop-down-demo.php


#3

Hi, along with what Eric said, I think you should know that doing hte min-height trick

#megaMenu {
	min-height: 400px;
	height: auto !important;
	height: 400px;
	float: left;
	clear: left;
	width: 900px;
	}

It fails in IE, the real way you should be doing min-height is this

#megaMenu {
	min-height: 400px;
	float: left;
	clear: left;
	width: 900px;
	}
* html #megaMenu{height:400px;}

Also when you float something, and absolutely position it, the absolute position wins out and the float is ignored :)..

Also, I have to ask, what in the world is this? Rubbish smile

#megaMenu ul li ul li {
	display: block;
	[B]xfloat[/B]: left;
	width: 200px;
	[B]xbackground[/B]: #CCC;
	}

#4

Hi Ryan,
I have seen people do that instead of using css comments to nullify a rule when testing or building pages. It is surely not good practice and just results in invalid css, but I would guess that is what the OP was doing.

Actually it is not even nullifying the float in this case since a float was set on all the LIs' higher up in the cascade. It should be float:none; if the goal was to override it.


#5

i made a site with the code live here
My problem is that ul ul wich is the wrapper for second and third level do not wrap neatly around third level - why?
Also is there a way to have ul ul widths set to auto?

the "xbackground..." is as Rayzur says to comment out rules when im trying different things. - would of course not recomend using that when going live.

in the link above i have deleted css rules not necesarry so far...

any ideas?


#6

The first level LI's height of 30px is inherited by the second level LI. So its child UL background is restrained to that height, but its content is overflowing visible.

(Thanks for posting your code together with your question! It was a good help to see the problem.)


#7

What Erik said plus If you want the yellow to surround the three menus then float the nested uls inside the parent ul.

e.g. Something like this:

#megaMenu ul li li {
    height:auto;
}
#megaMenu ul li ul {
    position: absolute;
    left: 0;
    top: 30px;
    background: yellow;
    width: 450px;
    margin-left:-999em
}
#megaMenu ul li:hover ul {
    margin-left:0;
}
#megaMenu ul li ul li ul{
    float:left;
    position:static;
}


Also use the off left hiding routine rather than display none as it is better for accessibility.

Full code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CSS only MegaMenu</title>
<style type="text/css">
/* ----- Design Layout ----- */
body {
    width:1000px;
    margin:0 auto;
}
/* Wrapper */
#megaMenu {
    min-height: 400px;
    height: auto !important;
    height: 400px;
    float: left;
    width: 1000px;
}
/* Level 1 */
#megaMenu ul {
    width: 900px;
    margin: 0;
    padding: 0;
}
#megaMenu ul li {
    position: relative;
    list-style: none;
    width: auto;
    height:30px;
    float: left;
    margin: 0;
    padding: 0;
}
#megaMenu ul li li {
    height:auto
}
#megaMenu ul li ul li ul{
    float:left;
    position:static;
}

#megaMenu ul li a {
    padding: 0 10px;
}
#megaMenu ul li span {
}
/* Level 1 - Hover */
#megaMenu ul li:hover {
}
#megaMenu ul li a:hover {
}
/* Level 1 - Selected */
#megaMenu ul li.selected {
}
#megaMenu ul li.selected a {
}
/* Level 2 */
#megaMenu ul li ul {
    position: absolute;
    left: 0;
    top: 30px;
    background: yellow;
    width: 450px;
    margin-left:-999em
}
#megaMenu ul li:hover ul {
    margin-left:0;
}
#megaMenu ul li ul li ul{
    float:left;
    position:static;
}

#megaMenu ul li ul li {
    width: 150px;
}
#megaMenu ul li ul li.last {
}
#megaMenu ul li ul li a {
}
#megaMenu ul li ul li span {
}
/* Level 2 - Hover */
#megaMenu ul li ul li:hover {
}
#megaMenu ul li ul li a:hover {
}
/* Level 2 - Selected */
#megaMenu ul li ul li.selected {
}
#megaMenu ul li ul li.selected a {
}
/* Level 3 */
#megaMenu ul li:hover ul li ul {
    background:none;
}
#megaMenu ul li:hover ul li ul li {
    float: none;
}
#megaMenu ul li ul li ul li a {
}
#megaMenu ul li ul li ul li span {
}
/* Level 3 - Hover */
#megaMenu ul li ul li ul li:hover {
}
#megaMenu ul li ul li ul li a:hover {
}
/* Level 3 - Selected */
#megaMenu ul li ul li ul li.selected {
}
#megaMenu ul li ul li ul li.selected a {
}
</style>
</head>
<body>
<h1>This is megaMenu:</h1>
<div id="megaMenu">
    <ul>
        <li class="first selected"><a href="#">1 Menu Item</a><span></span>
            <ul>
                <li class="first"><a href="#">1.1 Menu Item</a><span></span>
                    <ul>
                        <li class="first"><a href="#">1.1.1 Article</a><span></span> </li>
                        <li class=""><a href="#">1.1.2 Article</a><span></span> </li>
                        <li class="last"><a href="#">1.1.3 Article</a><span></span> </li>
                    </ul>
                </li>
                <li class="selected"><a href="#">1.2 Menu Item</a><span></span>
                    <ul>
                        <li class="first"><a href="#">1.2.1 Article</a><span></span> </li>
                        <li class=""><a href="#">1.2.2 Article</a><span></span> </li>
                        <li class="selected"><a href="#">1.2.3 Article</a><span></span> </li>
                        <li class=""><a href="#">1.2.4 Article</a><span></span> </li>
                        <li class="last"><a href="#">1.2.5 Article</a><span></span> </li>
                    </ul>
                </li>
                <li class="last"><a href="#">1.3 Menu Item</a><span></span>
                    <ul>
                        <li class="first"><a href="#">1.3.1 Article</a><span></span> </li>
                        <li class="last"><a href="#">1.3.2 Article</a><span></span> </li>
                    </ul>
                </li>
            </ul>
        </li>
        <li class=""><a href="#">2 Menu Item</a><span></span>
            <ul>
                <li class="first"><a href="#">2.1 Menu Folder</a><span></span>
                    <ul>
                        <li class="first"><a href="#">2.1.1 Article</a><span></span> </li>
                        <li class=""><a href="#">2.1.2 Article</a><span></span> </li>
                        <li class=""><a href="#">2.1.3 Article</a><span></span> </li>
                        <li class="last"><a href="#">2.1.4 Article</a><span></span> </li>
                    </ul>
                </li>
                <li class="last"><a href="#">2.2 Menu Folder</a><span></span>
                    <ul>
                        <li class="first"><a href="#">2.2.1 Article</a><span></span> </li>
                        <li class="last"><a href="#">2.2.2 Article</a><span></span> </li>
                    </ul>
                </li>
            </ul>
        </li>
        <li class=""><a href="#">3 Menu Item</a><span></span> </li>
        <li class="last"><a href="#">4 Menu Item</a><span></span> </li>
    </ul>
</div>
</body>
</html>



#8

nicly - thanks Paul O'B and others cool