4

I am trying to create a transition on a full screen overlay that is full width and full height with nonactive styles of visibility: hidden and opacity: 0. When clicking on a hamburger icon, an .active class is added to the div and it has the following styles: visibility: visible and opacity: 1.

Here is the CSS:

  .overlay {
    position: fixed;
    left: 0;
    right: 0;
    height: 100%;
    width: 100%;
    background: '#272727';
    z-index: 100;
    transition: visibility 500ms ease, opacity 500ms ease;
    visibility: hidden;
    opacity: 0;
    &.active {
      visibility: visible;
      opacity: 1;
    }
  }

The transition is occurring as expected on Chrome and Safari but the "fade-in" part of the transition fails on Firefox. It's basically skipping from the first frame to the last frame without transitioning. Here is a link to the page if you want to see it in action: link to webpage

And a video of what is occurring if you are unable to replicate the issue on your browser screen recording:

Why is this transition not working on Firefox?

Joel Hoelting
  • 1,862
  • 2
  • 23
  • 45

2 Answers2

6

I think this is due to when the visibility is changed in the transition and seems to display inconsistently between browsers.

This demonstrates your code and for me in Firefox if you toggle the element quickly it does not transition smoothly. This is always how I've done similar transitions and only recently started noticing the problem.

var element = document.querySelector(".element")
var toggle = document.querySelector(".element-toggle")

toggle.addEventListener("click", function(event) {
  element.classList.toggle("active");
});
.element{
  opacity: 0;
  visibility: hidden;
  transition: opacity 500ms ease, visibility 500ms ease;
}

.element.active{
  opacity: 1;
  visibility: visible;
}
<div class="element">This is a div element</div>

<button type="button" class="element-toggle">Toggle</button>

After reviewing, this is what works for me:

var element = document.querySelector(".element")
var toggle = document.querySelector(".element-toggle")

toggle.addEventListener("click", function(event) {
  element.classList.toggle("active");
});
.element{
  opacity: 0;
  visibility: hidden;
  transition: opacity 500ms ease, visibility 0s ease 500ms;
}

.element.active{
  opacity: 1;
  visibility: visible;
  transition: opacity 500ms ease, visibility 0s ease 0s;
}
<div class="element">This is a div element</div>

<button type="button" class="element-toggle">Toggle</button>
Moucky
  • 76
  • 1
  • 4
  • Welcome to SO! Nice answer. In the future or in this answer, you can also use [code snippet option](https://meta.stackoverflow.com/a/356679/10892074) to add live code to your answer! It will make a life a lot easier for future visitors and for OP him/herself. – Vepth Jun 18 '20 at 20:31
  • Tested your code in Firefox. After 1 or 2 clicks - the same issues started. Fading up without transition. – focus.style Jun 18 '20 at 21:21
  • @focus.style, that's strange. I've added both the snippets to the answer and just looked at them both in Firefox. Seems to be showing first the issue and then the solution working correctly for me. – Moucky Jun 18 '20 at 21:33
  • Indeed. Second one woks stable. – focus.style Jun 18 '20 at 21:36
  • I wish we knew why some browsers have broken the ability to animate the 'visibility' property. If anyone finds anything out please let us know! – Joel Hoelting Jun 19 '20 at 19:17
2

Seems like visibility doesn't have transition options. So the transition works incorrect.

In .bbfIaB this part

transition: visibility 500ms ease 0s, opacity 500ms ease 0s;

Change to this

transition: opacity 500ms ease 0s;

UPDATED

The best solution in this situation will be next:

  1. Removing visibility from transition in CSS.
  2. Removing visibility: hidden; from .bbfIaB
  3. Add new css class, like .hidden {visibility: hidden;}
  4. Add a JavaScript, which will add .hidden 500ms after removing .active
  5. Class .hidden should be added to the template by default, should be removed with activation of class .active

UPDATE 2

Working example without visibility transition at all.

var element = document.querySelector(".element")
var toggle = document.querySelector(".element-toggle")

toggle.addEventListener("click", function(event) {
  if (element.classList.contains("active")) {
    setTimeout(function() {
      element.style.visibility = '';
    }, 500);    
  } else {
    element.style.visibility = 'visible';
  }  
  element.classList.toggle("active");
});
.element{
  opacity: 0;
  visibility: hidden;
  transition: opacity 500ms ease;
}

.element.active{
  opacity: 1;
}
<div class="element">This is a div element</div>
<button type="button" class="element-toggle">Toggle</button>
focus.style
  • 6,612
  • 4
  • 26
  • 38
  • According to the accepted answer from this post you can transition the visibility property: https://stackoverflow.com/questions/3331353/transitions-on-the-css-display-property?page=1&tab=votes#tab-top – Joel Hoelting Apr 18 '20 at 00:28
  • This accepted answer tells the other point. https://stackoverflow.com/questions/27900053/css-transition-with-visibility-not-working – focus.style Apr 18 '20 at 00:33
  • Yeah, i see, the visibility in now on the accepted list. But it works incorrect in Firefox and we can't do anything with it for now. Updated the answer with te possible solution. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties – focus.style Apr 18 '20 at 00:44
  • If it's in the documentation as an animatable property then what gives? I am fairly certain that previous versions of FF have been able to animate opacity/visibility. – Joel Hoelting Apr 18 '20 at 16:03
  • Yeah. i See, now it is in documentation. Interesting that with and without console it works different way in FF. I think, int's FF bug. I suggest to abstain of using visibility. Updated my answer yesterday with some recommendations . – focus.style Apr 18 '20 at 18:13
  • Illustrated the idea of my answer in code. Working without visibility transition but with correct set or `visibility` after animation. – focus.style Jun 18 '20 at 21:48