Brad Woods
Brad Woods

Reputation: 1546

transitioning within display: none

I have an inner and outer div. When the outer div changes from display: none to display: block, the inner div is supposed to transition from opacity 0 to opacity 1. This doesn't work however, the inner div just immediately goes to opacity 1. Any ideas why? Fiddle below -

http://jsfiddle.net/bradjohnwoods/umureqvq/

<div id="outer" class="hide">
    <div id="inner" class="hide">
    </div>
</div>

<button type="button">press</button> 

div#outer{
    height: 200px;
    width: 200px;
    background-color: tomato;
}

div#inner{
    height: 100px;
    width: 100px;
    background-color: lightgrey;
    opacity: 1;
    transition: all 1000ms;
}

div#outer.hide{
    display: none;

}

div#inner.hide{
     opacity: 0;
}

var outer = $('#outer');
var inner = $('#inner');
var btn = $('button');

btn.click(function(event){
    outer.removeClass('hide')
    inner.removeClass('hide');
});

Upvotes: 0

Views: 131

Answers (4)

agiopnl
agiopnl

Reputation: 1344

Another solution is to set a 1ms timeOut between the display and the opacity. I think that also is a bit tacky. I'm looking for a better solution, but I guess there is none.

Upvotes: 0

V Maharajh
V Maharajh

Reputation: 9629

display:none does not work well with transitions. I've used the following instead:

.hide {
  display: block;
  position: absolute;
  top: -9999px;
  left: -9999px;
}

In addition to addressing the transition issue, this also leads to a better user experience since the browser:

  1. pre-fetches the resources of the element (eg. images), and
  2. pre-renders the layout of the element

Upvotes: 0

Jacob
Jacob

Reputation: 2154

It has to do with the outer div's display property. You can set its width and height to 0 instead. It has the same effect but allows the inner div to transition.

Updated JSFiddle

CSS

div#outer{
    height: 200px;
    width: 200px;
    background-color: tomato;
    overflow: hidden;
}

div#inner{
    height: 100px;
    width: 100px;
    background-color: lightgrey;
    opacity: 1;
    transition: all 1000ms;
}

div#outer.hide{
    width: 0;
    height: 0;

}

div#inner.hide{
     opacity: 0;
}

Upvotes: 0

kthornbloom
kthornbloom

Reputation: 3730

I think it's attempting the fade at the same time it's changing to be visible, so technically it's not visible yet. Therefore it's not doing the transition. Setting a timeout forces it to first be visible, then handle the opacity.

http://jsfiddle.net/umureqvq/6/

var outer = $('#outer');
var inner = $('#inner');
var btn = $('button');

btn.click(function (event) {
    outer.removeClass('hide');
    setTimeout(function () {
        inner.removeClass('hide');
    }, 0);
});

Upvotes: 1

Related Questions