简体   繁体   中英

Fade in with CSS transition Firefox

I want to fade in an overlay using a CSS transition when a user clicks a button.

The overlay element has a style with: transition: opacity 1s

I am using jQuery to set the display from none to block , then after a short delay setting the opacity to 1:

overlay.css('display', 'block');

setTimeout(function() {
    overlay.css('opacity', 1);
}, 10);

Without the delay the overlay will appear at full opacity.

This works fine on most browsers (Chrome, Safari, Internet Explorer 11, Edge...) but in Firefox the transition will often not happen. A longer timeout makes Firefox more reliable, and a shorter timeout will make it almost never show the transition.

How do I reliably wait for the display: block to be applied before setting the opacity?

 function show() { $('#square').css('display', 'block'); setTimeout(function() { $('#square').css('opacity', 1); }, 5); } function hide() { $('#square').css('display', 'none'); $('#square').css('opacity', 0); } 
 #square { width: 100px; height: 100px; background-color: red; opacity: 0; display: none; transition: opacity 1s; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button onClick="show()">Show</button> <button onClick="hide()">Hide (no animation)</button> <div id="square"></div> 

Not sure of the cause, but it seems Firefox new Quantum CSS is buggy, because what you are doing should work

Playing around with it, I thought I'd try to put the opacity change inside a request animation frame, but that failed about the same number of times as your code

Then, I nested requestAnimationFrame ... and it seems to work. All I can surmise is, by the time the second animation frame is triggered (ie about 16 to 32ms after the element is displayed) the rendering of the still invisible element is complete, so animation can take place (I'm making this up as I go along, can you tell)

 function show() { $('#square').css('display', 'block'); requestAnimationFrame(() => requestAnimationFrame(() => $('#square').css('opacity', 1))); } function hide() { $('#square').css('display', 'none'); $('#square').css('opacity', 0); } 
 #square { width: 100px; height: 100px; background-color: red; opacity: 0; display: none; transition: opacity 1s; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button onClick="show()">Show</button> <button onClick="hide()">Hide (no animation)</button> <div id="square"></div> 

Forcing a reflow by getting the offsetHeight of an element instead of a timeout seems to work consistently in all browsers:

$('#square').css('display', 'block');
$('#square').get(0).offsetHeight;
$('#square').css('opacity', 1);

USE VISIBILITY !

Like this :

<DOCTYPE html>
<html>
<head>
<style>
[ui="overlay"]
{
  display: block; /* always a block */
  z-index: 2;

  position: fixed;
  left: 0; 
  top: 0;
  width: 100vw; /* 100% of viewport width */
  height: 100vh; /* 100% of viewport height */

  background-color: rgba(0,0,0,0.8);

  transition-property: visibility, opacity;
  transition-duration: .0s, .5s; /* change only .5s opacity duration */
}

[ui="overlay"][ui-state="0"]
{
  transition-delay: .5s, .0s; /* visibility delay = opacity duration */
  transition-timing-function: ease-out;
  visibility: hidden;
  opacity: 0;
}

[ui="overlay"][ui-state="1"]
{
  transition-delay: .0s, .0s; /* no visibility delay */
  transition-timing-function: ease-in;
  visibility: visible;
  opacity: 1;
}
</style>
</head>
<body>

<div ui="overlay" id="mainOverlay" ui-state="0">
  <button ui="target-state" ui-target="#mainOverlay" ui-target-state="0">X</button>
</div>

<button ui="target-state" ui-target="#mainOverlay" ui-target-state="1">Show overlay</button>

<script src="http://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>

<script>
$(document).ready(function(){
  $('[ui="target-state"]').on('click',function(){
    var t = $(this).attr('ui-target');
    var s = $(this).attr('ui-target-state');
    $(t).attr('ui-state', s);
  });
});
</script>
</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM