inorganik
inorganik

Reputation: 25525

Can CSS3 drop-down menu fade-in and fade-out?

I've implemented a drop-down menu with CSS3 that fades in the drop-down nicely when the parent li is hovered. But the drop-down will not fade-out and here's why. Since you can't transition the display property, the fade is accomplished by transitioning the opacity. Since just the opacity is transitioned, you need to move the sub ul out of the way - otherwise the invisible sub-menu will appear when hovered.

I've created a JS Fiddle that demonstrates this- without the left:1000px; rule on ul#mainNav li ul, it will fade-out just fine. But then you can hover the invisible menu. - http://jsfiddle.net/YZvdm/

So how would I go about making it fade-out without making it not accidentally hoverable? height:0; will also eliminate the fade-out, so that's not an option.

Upvotes: 6

Views: 38858

Answers (6)

Khan
Khan

Reputation: 2982

The key to making this work is using visibility:hidden instead of display:none and using a transition-delay on the visibility until after opacity goes to 0.

.nav li ul {
  visibility: hidden;
  opacity: 0;
  -prefixes-transition-property: opacity, visibility;
  -prefixes-transition-duration: .4s, 0s;
  -prefixes-transition-delay: 0s, .4s;
}

.nav li:hover ul {
  visibility: visible;
  opacity: 1;
  -prefixes-transition-delay: 0s, 0s;
}

Fiddle: http://jsfiddle.net/YZvdm/29/

Upvotes: 24

Moby's Stunt Double
Moby's Stunt Double

Reputation: 2550

I'm late to this party, but here is what I ended up with faced with a similar prospect:

Fiddle: https://jsbin.com/bibokaqumi/1/edit?html,css,output

Markup:

<nav>
  <ul>
    <li>Link One</li>
    <li class="sub">Link Two
      <ul>
        <li>Sub-Link One</li>
        <li>Sub-Link Two</li>
      </ul>
    </li>
    <li>Link Three</li>
  </ul>
</nav>

CSS3:

nav li {
    list-style: none;
}

nav > ul > li {
    height: 100px;
    padding-right: 50px;
    float: left;
}

    nav > ul > li.sub {
        position: relative;
    }

        nav > ul > li.sub ul {
            position: absolute;
            top: 20px;
            width: 200px;
            visibility: hidden;
        }

        nav > ul > li.sub ul {
            opacity: 0;
            transition-property: opacity;
            transition-duration: 0.3s;
        }

        nav > ul > li.sub:hover ul {
            opacity: 1;
            transition-delay: 0.1s;
            visibility: visible;
        }

Upvotes: 0

hayatbiralem
hayatbiralem

Reputation: 689

I have created a demo on Codepen and that is work on Firefox or others:

http://codepen.io/hayatbiralem/pen/Gdfie

Hope this helps.

Screenshot

Upvotes: 1

jamesplease
jamesplease

Reputation: 12869

Here's a Github to an all-CSS dropdown with fade-in and fade-out. It should be able to do everything you can do with Javascript.

http://github.com/jmeas/CSS3-Dropdown-With-Fade

Upvotes: 3

inorganik
inorganik

Reputation: 25525

Turns out is was a far-better solution for me to simply implement a jQuery fade-in and out, like so:

$(function() {

    $('#topNav ul').find('ul').show().hide();
    $('#topNav > ul > li').hover(function() {
        $(this).children('ul').stop().fadeIn(300);
    }, function() {
        $(this).children('ul').stop().fadeOut('fast');
    });

}

Upvotes: 3

name
name

Reputation: 457

I haven't actually tested this, but you should be able to get around it by defining your own special 'delayed' animation, and applying it to the sub-menus.

#mainNav > li > ul {  
    -moz-animation-duration: 3s;  
    -moz-animation-name: delaySlide;     
}  

@-moz-keyframes delaySlide {  
    from {  
      height: auto;  
    }  

    95% {  
       height: auto;
    }  
    to {  
      height: 0;  
    }     
}

Doing so, and timing it properly, should make your menu's height animation happen after the fadeout.

Sample code taken off https://developer.mozilla.org/en/CSS/CSS_animations#Defining_the_animation_sequence_using_keyframes

Upvotes: 0

Related Questions