2

How do you transition using CSS the properties of elements with display none? My current solution is to set display to block with JavaScript, wait 10 milliseconds for repaint, then apply the class that changes the properties I want to animate.

Note: I'm using jQuery for code brevity.

CSS - animating opacity as an example. Don't care about $.show().

.element
{
    display:none;
    opacity:0;
    -webkit-transition:all 0.5s;
    -moz-transition:all 0.5s;
    -ms-transition:all 0.5s;
    -o-transition:all 0.5s;
    transition:all 0.5s;
}
.element.shown
{
    opacity:1;
}

JavaScript

function show()
{
    var $element=$('.element');
    $element.css({display:'block'});
    
    //Add class a few moments later than chaning display to block, otherwise animations CSS Transitions won't fire
    setTimeout(function(){
        $element.addClass('shown');
    },10);
}
function hide()
{
    var $element=$('.element');
    $element.removeClass('shown');
    
    //Remove element from display after transition ends
    $element.on('webkitTransitionEnd otransitionend oTransitionEnd MSTransitionEnd transitionend',function()
    {
        $element.css({display:'none'});
    });
}

I feel there should be a better way though, a CSS-only way. Is there?

Community
  • 1
  • 1
Francisc
  • 77,430
  • 63
  • 180
  • 276
  • [`.show`?](http://api.jquery.com/show/) – Griffin Jun 21 '13 at 14:35
  • Instead of display: none, could you make make it height: 0 and then add height: on what it transitions to? – Derek Story Jun 21 '13 at 14:37
  • jQuery guys, stop looking at `css-transition` tags! Haha. Also, `opacity`? It's just an example. – Francisc Jun 21 '13 at 14:37
  • dwreck: Yeah, but that would be a workaround of which there are many. Setting display none makes the element not being painted. Also, height:0 still means I have to remove borders, padding and margin, then re-add them. – Francisc Jun 21 '13 at 14:39
  • I see. This page may or may not be useful: http://stackoverflow.com/questions/3331353/transitions-on-the-display-property – Derek Story Jun 21 '13 at 16:17

1 Answers1

2

I just found workaround. All you need is use animation and start it little bit after you apply display:block. Like this:

@keyframes submenu_animation {
    from {
        opacity: 0;
    }
    1% {
        opacity: 0;
    }
    99% {
        opacity: 1;
    }
    to {
        opacity: 1;
    }
}

li ul {
    opacity: 0;
    display: none;
    animation-name: submenu_animation;
    animation-duration: 300ms;
    animation-direction: reverse;

li ul.open {
    display: block;
}

li:hover ul {
    animation-direction: normal;
    opacity: 1;
}

Javascript is pretty the same, It will apply class "open" once you hover on required element. When you hover-out it will remove "open" class little bit later, when animation is finished.

Lapak
  • 165
  • 1
  • 2
  • 9