user1452062
user1452062

Reputation: 805

Opacity transition (triggered by an extra class) doesn't work backwards

I'm firing a transition with an extra class (.opened) with jQuery.

.box {
    width: 200px;
    height: 200px;
    background: red;
    opacity: 0;
    visibility: hidden;
    transition: opacity 1.3s ease;
}

.box.opened {
    visibility: visible;
    opacity: 1;
}

The transition is smooth when the jQuery adds the .opened class, but not when jQuery removes it.

Should I use animate() or is it possible to get the expected result with CSS?

I think it's because of the visibility property, but why doesn't work it backwards?

Live demo

Upvotes: 2

Views: 241

Answers (2)

Rene van der Lende
Rene van der Lende

Reputation: 5301

Here is an alternative without using jQuery (as in pure CSS). It uses the :target pseudo-class to toggle between an ON and an OFF state.

It also shows how to use an icon-font with menu/close button.

@import url("https://fonts.googleapis.com/icon?family=Material+Icons");

#box                        { width: 200px; }
#box a                      { width: 100%; position: relative; text-decoration: none }

.menu__content              { width: 100%; height: 200px; padding: 8px; opacity: 0;
                              background: rgba(255,0,0,.3); transition: opacity 0.5s ease }

#box        .menu__open     { display: block } /* initial state */
#box:target .menu__open     { display: none  } /* hidden when __content visible */
#box        .menu__close    { display: none  } /* initial state, inverse of __open */
#box:target .menu__close    { display: block } /* hidden when __content invisible */
#box        .menu__content  { opacity: 0;    } /* __close state */
#box:target .menu__content  { opacity: 1; position: relative; } /* __open state */
<div id="box">
  <a   class="menu__open material-icons"  href="#box">menu</a>
  <a   class="menu__close material-icons" href="#"   >close</a>
  <div class="menu__content">Hello. This is some stuff inside a nice red box.</div>
</div>

Upvotes: 1

Harry
Harry

Reputation: 89780

The reason is because only the opacity is being transitioned whereas the visibility is not and so the element disappears immediately. Because of this immediate disappearance, opacity transition is not visible. Transition the visibility also like in below snippet.

.box {
    width: 200px;
    height: 200px;
    background: red;
    opacity: 0;
    visibility: hidden;
    transition: opacity 1.3s ease, visibility 1.3s ease;
}

.box.opened {
    visibility: visible;
    opacity: 1;
}

$(document).ready(function() {
  $('.trigger').click(function(e) {
    e.preventDefault();
    $('.box').toggleClass('opened');
  });
});
.box {
  width: 200px;
  height: 200px;
  background: red;
  opacity: 0;
  visibility: hidden;
  transition: opacity 1.3s ease, visibility 1.3s ease;
}
.box.opened {
  visibility: visible;
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="" class="trigger">Trigger</a>

<div class="box"></div>

Note: You don't really need to change visibility because it almost does the same thing as what is done by opacity: 0. Hence you can do away with the visibility property change.

$(document).ready(function() {
  $('.trigger').click(function(e) {
    e.preventDefault();
    $('.box').toggleClass('opened');
  });
});
.box {
  width: 200px;
  height: 200px;
  background: red;
  opacity: 0;
  transition: opacity 1.3s ease;
}
.box.opened {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="" class="trigger">Trigger</a>

<div class="box"></div>

But retaining visibility property change and doing away with the opacity change will not produce the same output (like seen in the below snippet).

$(document).ready(function() {
  $('.trigger').click(function(e) {
    e.preventDefault();
    $('.box').toggleClass('opened');
  });
});
.box {
  width: 200px;
  height: 200px;
  background: red;
  visibility: hidden;
  transition: visibility 1.3s ease;
}
.box.opened {
  visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="" class="trigger">Trigger</a>

<div class="box"></div>

You can find the list of properties that can be transitioned or animated here in the specs.

Upvotes: 3

Related Questions