EscalatedQuickly
EscalatedQuickly

Reputation: 402

Drop down menu hiding menus

I'm building a drop down menu for a project I'm working on, but I don't get it working entirely as is should. I want it to show the sub-menus when I hover the root-level menus, and then close again after a short delay when the menu or sub-menu is not hovered anymore. Most of it works; the sub-menus are showed when root-level items are hovered and it is hidden when I stop hovering the root-level item. The problem is that the sub-menus are also hidden when I move my cursor from the root-level item to a sub-menu item other than the first and hover that. This is obviously not good, so help would be appreciated.

I created a JSFiddle with the code which shows the issue more clearly.

So, here's my code:

menu.htm

<div id=m_wrapper>
    <ul id=menu>
        <li onMouseOver="show_sub_menu('0')" onMouseOut="start_timer()">Item 1
            <div id=s0 onMouseOver="show_sub_menu('0')" onMouseOut="start_timer()">
                <a href=#>Item 1.1</a>
                <a href=#>Item 1.2</a>
                <a href=#>Item 1.3</a>
            </div>
        </li>
    </ul>
</div>

menu.css

#m_wrapper {
    position:relative;
    display:table;
}
#menu {
    position:relative;
}
#menu li {
    width:100px;
    position:relative;
    float:left;
    list-style-type:none;
}
#menu div {
    position:absolute;
    visibility:hidden;
    display:inherit;
    width:100%;
    z-index:30
}
#menu div a {
    position:relative;
    display:block;
    z-index:35;
}

menu.js

var countdown = 300;
var timer = null;
var menu_item = null;

window.show_sub_menu = function(cath) {
    if (menu_item) {
        menu_item.style.visibility = 'hidden'; //Make sure to show one menu at a time
    }

    menu_item = window.document.getElementById("s" + cath);
    menu_item.style.visibility = 'visible'; //Show menu

    if (timer) {
        window.clearTimeout(timer); //Reset timer, so menu is kept open
        timer = null;
    }
};

window.start_timer = function() {
    timer = window.setTimeout(close_sub_menu, countdown);
};

window.close_sub_menu = function() {
    menu_item.style.visibility = 'hidden';
};

Upvotes: 0

Views: 2333

Answers (5)

Bartek Bielawa
Bartek Bielawa

Reputation: 572

Remember that.. if You decide to implement the fade version, You should use crosbrowser opacity, like this:

 -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
 filter: alpha(opacity=100);
 -moz-opacity: 1;
 -khtml-opacity: 1;
 opacity: 1;

Upvotes: 0

Steely Wing
Steely Wing

Reputation: 17607

A pure CSS drop down menu

http://jsfiddle.net/steelywing/GANeX/8/

.nav {
    background-color: #def;
    height: 20px;
}

.nav * {
    transition: all 0.4s ease 0s;
    -moz-transition: all 0.4s ease 0s;
    -webkit-transition: all 0.4s ease 0s;
    -o-transition: all 0.4s ease 0s;
}
li {
    display: inline-block;
    height: 20px;
}

.dropdown li {
    display: block;
}

.dropdown ul {
    visibility: hidden;
    opacity: 0;
    margin-top: -2px;
}

.dropdown:hover ul {
    visibility: visible;
    opacity: 1;
}

Upvotes: 1

Colin Bacon
Colin Bacon

Reputation: 15609

This can quite easily be achieved with HTML and CSS alone. Using CSS transitions we can make the menu fade when we hover off.

Example

I have also put this on JsFiddle

HTML

<nav>
    <ul id="menu">
        <li>
            <a href="#">Home</a>
            <ul>
            <li>Item1</li>
            <li>Item2</li>
            <li>Item3</li>                                
            </ul>
        </li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</nav>

CSS

#menu li
{
    position: relative;  
    display: inline;
    list-style: none;
    padding-left: 15px;  
}

#menu ul
{
    margin: 0;
    padding: 0;
    list-style: none;    
    opacity: 0;
    position: absolute;
    top: 20px;
    left: 5px;
    // Transitions for our fade effect.
    -webkit-transition: opacity 2s ease-in-out; 
    -moz-transition: opacity 2s ease-in-out;
    -ms-transition: opacity 2s ease-in-out;
    -o-transition: opacity 2s ease-in-out;
    transition: opacity 2s ease-in-out;   
}

#menu ul li
{
    display: block;    
}

#menu li:hover > ul
{
    opacity: 1;    
    // This stops the transition from happening on hover.
    -webkit-transition: none; 
    -moz-transition: none;
    -ms-transition: none;
    -o-transition: none;
    transition: none;
}

Upvotes: 1

Manish Mishra
Manish Mishra

Reputation: 12375

you don't have to make it that complex.

ofcourse you can do same through javascript, but see how easy, readable and simple it is through jQuery.

See this DEMO

Just use following script

$('#menu li').hover(
    function(){
            $(this).stop().animate({height: '100px'},1000,function(){});
            $(this).find('div').show(600);
        }//gets called upon mousehover
    ,
    function(){
            $(this).stop().animate({height: '20px'},1000,function(){});
        } //gets called upon mouseout
  ); //hover ends

and also, I don't know why you have written tonns of CSS. Just use these:

#menu
{
    list-style:none;
}
#menu li
{
    width:100px;
    border:1px Solid #CCC;
    text-align:Center;
    cursor:pointer;
    height:20px;
    overflow:hidden;

}
#menu li div
{
    border:1px Solid #CCC;
}
#s0 
{
    height:auto;
}
#s0 a
{
    display:block;
}

There's plenty you can do through it, like selected dropdown item. selection through arrow key and what not. jQuery makes it simple for you.

Upvotes: 1

Bartek Bielawa
Bartek Bielawa

Reputation: 572

first of all You should avoid <div> in <li> tags, because is not semantic.

Quite good is multi level menu build only with html and css styles.

HTML

 <div id=m_wrapper>
     <ul id=menu>
            <li>Item 1
                <ul>
                    <li><a href=#>Item 1.1</a></li>
                    <li><a href=#>Item 1.2</a></li>
                    <li><a href=#>Item 1.3</a></li>
                </ul>
            </li>
            <li>Item 2</li>
     </ul>
 </div>

CSS STYLES

#m_wrapper, #menu, #menu li  {
    position:relative; 
}
#m_wrapper {
    display:table; 
}
#menu li {
    float:left;
    width:100px;
    list-style-type:none;
}
#menu li ul {
    display: none;
}
#menu li:hover ul {
    display: block;
    margin: 0 10px;
    padding: 0;
}

Upvotes: 1

Related Questions