Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS transition on child element where parent toggles display property

Tags:

html

css

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/

like image 994
caramba Avatar asked Sep 21 '16 08:09

caramba


People also ask

Does transition work with display?

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.

When working with the transition property How can you target all available CSS properties for the transition effect?

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.

Are transition properties inherited?

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.

Can you animate display CSS?

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 .


2 Answers

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>
like image 195
AA2992 Avatar answered Nov 08 '22 17:11

AA2992


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

like image 4
Ryan O'Connor Avatar answered Nov 08 '22 18:11

Ryan O'Connor