incompleteness incompleteness - 4 months ago 24
CSS Question

workaround for display block and css transitions not triggering

Sorry all for so many updates in this question and I'm glad for everyone trying to help me. I think below there is a more clear way to understand this problem:

CSS transitions will not apply if you set the display property of an element to block immediately before changing the property with the transition attached. Consider the following code:

CSS:

#creative {
display: none;
opacity: 0;
transition: opacity 0.5s;
}


HTML:

<div id="creative">
<span>Sample text</span>
</div>


Javascript:

var dom = {};
dom.creative = document.getElementById('creative');
dom.creative.style.display = 'block';
dom.creative.style.opacity = 1;


The element will properly show, but without any transition. A workaround for this problem is to force a repaint by accessing one of the visual properties of the element:

dom.creative.style.display = 'block';
var a = dom.creative.offsetHeight; /* <-- forces repaint */
dom.creative.style.opacity = 1;


is there a good way around this? and by good i mean not adding a extra line of javascript code everytime i need to change the display property and a property with a transition attached.

Answer

Based on the code you present in your question I'm going on a completely different way here, and use animation instead, which will make the whole repaint issue go away

Updated with a script the set the div to display: block

var dom = {};
dom.creative = document.getElementById('creative');
dom.creative.style.display = 'none';

var butt = document.getElementById('button');
butt.addEventListener('click', function(e) {
  
  if (dom.creative.style.display == 'block') {
    dom.creative.style.display = 'none';    
  } else {
    dom.creative.style.display = 'block';
  }

})
#creative {
  display: none;
  opacity: 0;
  animation: opac 1s forwards;
  margin: 20px;
}
@keyframes opac {
  100% {
    opacity: 1;
  }
}
button {
  margin: 20px;
}
<button id="button">Toggle display</button>

<div id="creative">
  <span>Sample text</span>
</div>

If display: none is not needed, one can use transition and simply toggle a class like this

var dom = {};
dom.creative = document.getElementById('creative');

var butt = document.getElementById('button');
butt.addEventListener('click', function(e) {
  
  dom.creative.classList.toggle('show');

})
#creative {
  opacity: 0;
  transition: opacity 1s;
  margin: 20px;
}
#creative.show {
  opacity: 1;
  transition: opacity 1s;
}
button {
  margin: 20px;
}
<button id="button">Toggle display</button>

<div id="creative">
  <span>Sample text</span>
</div>

Comments