RSS Feed Twitter Posts RSS Comments RSS

Wednesday, August 26, 2009

CSS Only Cross-Browser DropDown menu with tabbing (Valid HTML and Free to use)

My CSS Only Cross-Browser DropDown Menu (100% valid HTML, Tested in IE5.5-IE8, Firefox, Opera, Chrome, Safari)

with tab button support and no JavaScript

Live Demo
this demo has no javascript involved at all, neither does it have any ugly tables
Background info
some months ago i started to work on a major website, that required a dropdown menu, now i can honestly say, i hated dropdown menu's, because they would need javascript to work, sure the usage of IE5-IE6 is no longer that large, especially ie6 users with js turned off, but its still possible, and i do not like the idea of having a critical part of my website not work in my website, so after reading a million posts on the internet saying this is impossible i made it my duty to make it work, after thinking for some time, i realized that general relativity was the answer, because it also applies to websites css/html, and used that as the basis on making this css dropdown work in all browsers


The Problem
Internet Explorer <=6 does not support the :hover pseudo state on anything except links that have a valid href="#", for example: <a href="#link">link</a> , so we cannot have a hover state on a div that contains all the dropdown links in IE6, there are some cool (and very dirty solutions) that i will link on the end of the post
The Solution
Everything in websites consists of positioned boxes, each box also has an effect on another box, for example the box below it.
now we can position a div with the dropdown links (sub-links) below a link, then add position:absolute; the div with the sub-links, and then add a margin-bottom:200px; or border-bottom:dashed transparent 200px; to the link on its hover state

<style type="text/css">
a:hover {
  border:bottom solid red 100px;
}
div {
  position:absolute;
}
</style>

<a href="#link">link</a>
<div>
<ul>
<li>link 1</li>
<li>link 2</li>
<li>link 3</li>
</ul>
</div>


, and the link will move the div below it, and this happens in every browser identically. (except opera at times, opera seems to ignore the margin, and thus you can either use a average dropdown method or use borders to push the div down).

Now this is great and all, but what about the sub-links that are inside that you hover over? the menu will immediately hide when you move your mouse away from the main link.
now this was a big problem at the start, but because anything is possible in css, and as long as something is being hovered i can do anything to the website, i found a solution.

each dropdown sublink in the div below the main link is being floated against a shifter div (thats what i called it), basically the links are pressed against a very high but very thin shifter div that will make them "float drop" in case that the one of the sub-links expands (increases width).

so one main link moves the absolutely positioned div that contains the sublinks dropdown, in which each and every link has the ability to do the same.
Cons
  • ¦ the mouses path from the main link to any of the sublinks must remain on top of some link
  • ¦ requires extra div's per link, one for shifter one for containing the sub-links
  • ¦ the dropdown links have to have a fixed (defined) with
  • ¦ the height of the main link has to be fixed (defined)
  • ¦ a little dirty example (will post a better example soon)
  • ¦ has quirks when hovering and tabbing at the same time.
  • ¦ requires some IE5-6 specific css (can be made to work without conditional comments)
  • ¦ the dropdown block needs to have a fixed height (usually min screen height of supported screen sizes. this applies only to ie5-6)

Pros
  • ¦ It's Free
  • ¦ Works in all browsers using only CSS without browser specific html
  • ¦ Completely valid HTML/CSS (semantically correct xhtml/css) and can be made to work without any IE hacks (will give example later)
  • ¦ Has natural tabbing, tabbing works just like that, tabbing can be easily disabled by removing the :focus and :active from the CSS.
  • ¦ JavaScript can be added to improve user experience
  • ¦ Works great and smooth in all browsers


The Idea
The idea itself of general relativity in websites can be taken to much higher and interesting lengths, and this is simply a small example that demonstrates that this area of css has not yet been explored.



Example ready made Code

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>valid browser overflow test</title>
<style type="text/css">
a {
color:#000;
}
.navigation {
height:2em;
width:56.25em;
background:#efefef;
}
.link {
height:2em;
position:relative;
float:left;
z-index:10;
}
a.main {
position:relative;
display:inline-block;
text-decoration:none;
line-height:2em;
height:2em;
z-index:10;
}
a.main b {
position:relative;
display:inline-block;
padding:0 .5em 0 .5em;
line-height:2em;
cursor:pointer;
}
.sublinkscontainer {
position:absolute;
}
.sublinks {
position:relative;
float:right;/*can be any float*/
margin-top:-2em;
}
.sublinks a {
display:block;
background:orange;

padding:.2em 0 .2em 0;
text-decoration:none;

}
.shifter {
position:relative;
float:right;
}
.sublinks .bgthing {
height:2em;
background:orange;
display:block;
}

ul, li {
margin:0;
padding:0;
list-style:none;
}




/*height limit*/
.link {
top:-25em;
}
a.main {
top:25em;
}
a.main:hover, a.main:active, a.main:focus {
margin-bottom:25em;
background:#000;
color:#fff;
outline:none;
}
a.main:active b, a.main:focus b {
outline: dotted thin;/*resetting the outline*/
}
.sublinkscontainer, .shifter {
height:25em;
}
/*valid browser height maximization*/
.nav > .link {
top:-1000em;
}
.link > a.main {
top:1000em;
}
.link > a.main:hover, .link > a.main:active, .link > a.main:focus {
margin-bottom:1000em;
}
.link > .sublinkscontainer, .sublinkscontainer > .shifter {
height:1000em;
}
/*/valid browser height maximization*/


/*width limit*/
.sublinkscontainer {
width:12.563em;
}
.sublinks a {
width:12.5em;/*12.5 - padding*/
}


.sublinks a:hover, .sublinks a:active, .sublinks a:focus {
margin-right:0.063em;
background:#333;
color:#fff;
}
.sublinks:hover a {/*opera fix*/
margin-right:0.063em;
}
a.main:focus + div .sublinks a, a.main:active + div .sublinks a {/*valid browser tab+hover fix*/
margin-right:0;
}

.shifter {
width:0.063em;
}
.sublinks .bgthing {
width:12.5em;
}



.content {
clear:both;
}



a.main span {/*this nullifies the masks effects*/
position:absolute;
right:0;
top:0;
line-height:0;
}
a.main span i {/*the mask*/
display:block;
position:absolute;
width:12.5em;
background:#efefef;/*must be bg color for masking*/
height:2em;
top:0;
right:auto;
}



.hidehotspot {
position:relative;
float:left;
background:red;
height:2em;
z-index:10;
}
.hidehotspot b {
position:absolute;
background:#efefef;
height:2em;
width:56.25em;
display:block;
}


/*ie5 fault for not supporting paddings on links*/
.sublinks a b {
font-weight:normal;
position:relative;
padding-left:.5em;
display:block;
}

/*valid browser height fix*/
.link > a.main:hover,
.link > a.main:active,
.link > a.main:focus {
margin-bottom:0;
}
.link > a.main:hover + div .sublinks a,
.link > a.main:active + div .sublinks a,
.link > a.main:focus + div .sublinks a {
margin-right:0.063em;
}
/*/valid browser height fix*/
</style>

<!--[if lte IE 6]>
<style type="text/css">
.link {
margin-bottom:-2000px;/*only for ie5-6*/
}
/*ie5 fix*/
li {
float:left;
}
.nav {/*only ie5-6 need this*/
height:25em;
position:absolute;
width:56.25em;
overflow:hidden;
}
</style>
<![endif]-->
</head>
<body>
<div class="navigation">
<div class="nav">
<div class="link">
<a class="main" href="#MAIN"><b>MAIN LINK</b><span><i> </i></span></a>

    <div><!--IE6 needs this div-->
<div class="sublinkscontainer">
<div class="shifter"></div>
<ul class="sublinks">
             <li class="bgthing"> </li>
     <li><a href="#test1"><b>test test</b></a></li>
         <li><a href="#test2"><b>test test test test test test test test test test test test </b></a></li>
         <li><a href="#test3"><b>test test</b></a></li>

         <li><a href="#test4"><b>test</b></a></li>
         <li><a href="#test5"><b>test test</b></a></li>
</ul>
</div>
</div>
</div>
<div class="link">
<a class="main" href="#MAIN"><b>MAIN CAN BE LONG</b><span><i> </i></span></a>

    <div><!--IE6 needs this div-->
<div class="sublinkscontainer">
<div class="shifter"></div>
<ul class="sublinks">
             <li class="bgthing"> </li>
     <li><a href="#test1"><b>test test</b></a></li>
         <li><a href="#test2"><b>test test test</b></a></li>
         <li><a href="#test3"><b>test test</b></a></li>

         <li><a href="#test4"><b>test</b></a></li>
         <li><a href="#test5"><b>test test</b></a></li>
</ul>
</div>
</div>
</div>
<div class="link">
<a class="main" href="#MAIN"><b>MAIN</b><span><i> </i></span></a>

    <div><!--IE6 needs this div-->
<div class="sublinkscontainer">
<div class="shifter"></div>
<ul class="sublinks">
             <li class="bgthing"> </li>
     <li><a href="#test1"><b>test test</b></a></li>
         <li><a href="#test2"><b>test test test test test test test test test test test test </b></a></li>
         <li><a href="#test3"><b>test test</b></a></li>

         <li><a href="#test4"><b>test</b></a></li>
         <li><a href="#test5"><b>test test</b></a></li>
</ul>
</div>
</div>
</div>


<div class="hidehotspot"><b> </b></div>
</div>

</div>

<div class="content">
stuff<br />
stuff stuff stuff
</div>
</body>
</html>


Other available dropdowns
I found this post after i made my dropdown, i was slightly dissapointed that my css dropdown was not the first pure css dropdown, Notice that only one of them is pure CSS, it involved very dirty/invalid/heavy code, and does not support tabbing.

i will post more examples of how this method of relative html can be used to make very interesting css features.


Stu Nicholls has designed his own version of this dropdown

Copyright info
The software referenced within this license is distributed free of charge and free from any warranty. It may be used freely for any purpose whatsoever. The author created and released this work because he is genuinely a Nice Person!

Users are encouraged to use, modify, distribute, improve and otherwise manipulate the code. After all, it’s free.

The author sincerely hopes that end users enjoy and appreciate the hard work that went into creating it, and would appreciate being referenced in future modifications of the code since it was based on the author’s original concept and work.

Users are nonetheless encouraged to provide reciprocity whenever possible as it provides positive reinforcement and encouragement to the author. Furthermore, the minimum reciprocation I ask is to leave a ‘thank you’ comment in the area below:
»»  read more

About ThinkHTML.

I'm Timo Huovinen.
I've been making websites since 2007 and I keep this blog as a log of web ideas.
You may be wondering why a web developer would use blogspot to write his website thoughts and ideas instead of making his own website for this purpose, well there are several reasons why I chose blogger, the main reason was that i have absolutely no time to make a website for myself.

I have been making websites for a while now and there is always some web project that I need to do, but in the end I still don't have a personal website, and no place to log my ideas and thoughts and to write tutorials for the people starting with html, css, js and server side languages.

A personal proper website needs time to be made, needs time to be maintained, needs time to be designed.

Thus it was simply a cheaper and faster way for me to log my ideas, and to open up useful information for people on the internet.

p.s. all images/photos used on this website were made by me.
»»  read more