Drop down menu

hi,
My apologies for the ignorance but I been really struggling to understand a nested inside drop down menu and how it work. I know that we need the main menu to be relative and drop down to be absolute. But how do we treat a 3 prd level drop down menu, And how it on hover. E.g I need to make vertical menu and it has menu opened when u hover it, but some menu has submenu to it and when you hover over them, the menu expands more and open nested menu. How can I make a absolute menu open up another absolute menu while pushing the menu down.

menu
—about
------my work
------photography
------things I do
—portfolio
—contact me

Hi

Here is an example I made for you to play with: http://jsfiddle.net/megazd/8x8z6oja/

2 Likes

@megazoid The problem that comes in, i don’t know how the menu get pushed, if the submenu doesn’t open up horizantaly (like in your example), but vertically below the parent li. I tried

nav ul li:hover > ul {
    display:block;
    position:absolute;
    left:0;
}

but, it opens up after the last li, not under the parent li.

In my example I’ve manually specified left margin for all submenus:

/* second and deeper levels */
nav > ul ul { 
    display: none; 
    position:absolute;
    left:140px;  /* <=== move 140px left from parent */
    top:0;
}

Yes, that means all menu items should have equal fixed width (140px in my example) but it’s okay usually. Maybe there is more advanced techinques available but I use this one without any problems.

@megazoid if you take out the left:140px, the menu should open under, parent menu pushing the menu to get space for open up but it opens under the last li.

Finally I understand what you’re trying to achieve :smiley:
If you want submenus to just expand down there is no need to use absolute positions at all: http://jsfiddle.net/megazd/8x8z6oja/8/

But I have to say that approach isn’t too usable as menu jumps when you move mouse from up to down

@megazoid that is what i want, and yes i agree with jumping issue. What you think of work around, use js to get onclick? or use css3 events (if any)
Edit: what changed besides the position from last example?

Don’t expand them on hover, definitely.
The most common solution (I think) is to use something like [+] sign near every item that has sub items, and expand them on click (like tree menus usually work).

@megazoid i reckon, it will done via JavaScript? If so, i haven’t done it in JS this thing, even can you be kind enough what shows the nested listed items, i wasn’t able to figure it out for days and your are brilliant to do in quick fix.

Yes, you have to use JavaScript to handle clicks.
Here is an example using jQuery: http://jsfiddle.net/megazd/8x8z6oja/9/

To implement this on your own page you’ll need to add this at the bottom of the page (before closing body tag):

<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(document).ready(function(){
    $('nav a').each(function(){        
        var link = $(this);
        var item = link.parent('li');        
    	if (!item.children('ul').length) { return; }        
        $(this).click(function(e){
            e.preventDefault();
            item.children('ul').eq(0).toggle();
        });        
    });    
});    
</script>

UPD: Maybe this can be also implemented using only CSS3 tricks with checkboxes and pseudo selectors but I haven’t enough time to experiment with it now.

@megazoid woh, that is some code i am unable to understand. can you tell me what’s going on here. i seem to be lost :fearful:

/* when document is ready (page loaded) */
$(document).ready(function(){

    /* let's do something with each <a> inside <nav> (nav a) */
    $('nav a').each(function(){        

        /* store <a> into link and it's <li> parent into item */
        var link = $(this);
        var item = link.parent('li');        

        /* if there is no nested <ul> inside current <li> */
        /* then skip it and go to the next <a> */
    	if (!item.children('ul').length) { return; }        

        /* when this <a> is clicked... */
        $(this).click(function(e){
            
            /* prevent default action (don't open any links) */
            e.preventDefault();

            /* toggle visibility of first <ul> nested into parent <li> */
            item.children('ul').eq(0).toggle();

        });        

    });    

});
1 Like

@megazoid thanks, i will try to decode and if i can’t i will bug you again :grin: now a problem has arise. My css for transform a image for dropdown doesn’t work along with JS. My code is like following

.dropdown-menu li a:hover:after{
-ms-transform: rotate(18deg); 
-webkit-transform: rotate(180deg); /* Safari */
transform: rotate(180deg);
-webkit-transition-timing-function: linear; /* Safari and Chrome */
transition-timing-function: linear;

}

I can’t say anything about this until I’ll see the problem by myself.

@megazoid here, i updated it , if you see when i hover it, it changes, i don’t think i can do in css, as menu i.e when menu open the > changes and when it close it return to previous state.

Here http://jsfiddle.net/megazd/8x8z6oja/11/
I’ve added one line to JS code:

item.toggleClass('expanded');

It adds .expanded class to <li> when it opens and removes when it closes
So your transform rule can be applied using that class

nav li.expanded > a:after

@megazoid Thank you so much for the help. Although its foreign language to me now. But i will give it read over and over again. Though what is good place to learn jQuery that is advance like that?

@megazoid i found one problem, the parent li of submenu isn’t clickable, as a link although its a anchor tag but doesn’t go anywhere. I reckon it’s because of e.Default?

Yes. That line prevents default click event behavior for <a> tag.
In current implementation there is no point to make them “clickable” because in such case you’ll be navigated to other page immediately instead of expanding sub menu. If you want these “root” links to remain active, you have to use additional links to toggle sub menus visibility.

Here is a bit more complicated example with additional switch links added dynamically