I read this: SO css-transition-from-display-none-on-class-change but I'm trying to toggle the display property on parent element. Is there a workaround to make it work?
CSS transition works like so fiddle https://jsfiddle.net/v1aym7wd/
HTML:
<div id="wrap">
<div class="fade"></div>
</div>
CSS:
#wrap {
background-color: orange;
width: 200px;
height: 200px;
/*display: none;*/
}
#wrap.show {
/*display: block;*/
}
.fade {
background-color: green;
width: 100px;
height: 100px;
opacity: 0.2;
transition: opacity 10s;
}
#wrap.show .fade {
opacity: 1;
}
JS:
var wrap = document.getElementById('wrap');
wrap.classList.add('show');
But as soon as I toggle display:block/none
on parent element the CSS transition does not work. Why is this? Any way to make it work?
See here: https://jsfiddle.net/v1aym7wd/1/
display is not one of the properties that transition works upon. See Animatable CSS properties for the list of CSS properties that can have transitions applied to them.
Transitioning two or more properties You can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property. You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.
Specifically around properties, like transition properties, that are not inherited by default. Run this demo in my JavaScript Demos project on GitHub. First off, this is not an AngularJS-specific problem (as you might be lead to believe from the post title). This is just a byproduct of CSS behavior.
CSS can't natively animate transitions that use display: none . You can hack around this limitation by using a mix of visibility: hidden and height: 0 to make it "close enough." While these solutions are probably fine in most cases, it isn't quite the same as using display: none .
Since display:none
on a parent also takes out descendants from the DOM tree, one solution could be to drop transitions and use animations instead.
The animation will kick in when the child element is displayed.
Do use the necessary vendor prefixes.
.fade {
opacity: 0.2
}
#wrap.show .fade {
animation: reveal 10s forwards;
}
@keyframes reveal {
100% {
opacity: 1
}
}
/* set timeout to show how animation starts. */
setTimeout(function reveal() {
var wrap = document.getElementById('wrap');
wrap.classList.add('show');
}, 2000);
#wrap {
background-color: orange;
width: 200px;
height: 200px;
display: none;
}
#wrap.show {
display: block
}
.fade {
background-color: green;
width: 100px;
height: 100px;
opacity: 0.2
}
#wrap.show .fade {
animation: reveal 10s forwards;
}
@keyframes reveal {
100% {
opacity: 1
}
}
<div id="wrap">
<div class="fade"></div>
</div>
As CBroe said, it can be done by using visibility instead of display.
https://jsfiddle.net/ryanoconr/v1aym7wd/2/
var wrap = document.getElementById('wrap');
wrap.classList.add('show');
#wrap {
background-color: orange;
width: 200px;
height: 200px;
display: block;
visibility: hidden;
}
#wrap.show {
visibility: visible;
}
.fade {
background-color: green;
width: 100px;
height: 100px;
opacity: 0.2;
transition: opacity 10s;
}
#wrap.show .fade {
opacity: 1;
}
<div id="wrap">
<div class="fade"></div>
</div>
The code doesn't seem to work in the snippet but it is working on JSFiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With