Different CSS transition for *IN* and *OUT* (or returning from transitioned state)

53.4k views Asked by At

I have a loading image which comes up during an Ajax load event. The image shows/hides by adding or removing a "loading" class to the body element. Currently, the loading image animates background-size from 0 to 100%, and fades in the opacity (vice versa for the 'return' transition).

I want to have the background-size transition happen instantly (not transition) on the fade out, so:

  • Fade in: opacity from 0 to 1 in .2s, background size from 0 to 100% in .2s

  • Fade out: opacity from 1 to 0 in .2s, background size from 100% to 0 should happen instantly

     #loader {
         width: 100%;
         height: 100%;
         position: fixed;
         top: 0;
         left: 0;
         z-index: -1;
         opacity: 0;
         -moz-opacity: 0;
         transition: all .2s ease-in-out
     }
    
    
     #loader .image {
         width: 400px;
         height: 138px;
         display: block;
         position: absolute;
         z-index: 2000; 
         top: 50%; 
         left: 50%; 
         margin: 0;
         background: url(assets/images/loading.png) no-repeat;
         background-size: 0 0;
         transition: all .2s ease-in-out;
         -webkit-animation: pulse 400ms ease-out infinite alternate;
         -moz-animation: pulse 400ms ease-out infinite alternate;
         -o-animation: pulse 400ms ease-out infinite alternate;
         animation: pulse 400ms ease-out infinite alternate
     }
    
     .loading #loader {z-index: 1000; background-color: rgba(255,255,255,.7)}
    
     .loading #loader .image {
         background-size: 100% 100%; 
         margin: -69px 0 0 -200px;
         transition: opacity .2s ease-in-out
     }
    

I've changed transition property for this selector .loading #loader .image to "opacity" rather than "all", but it still performs the background-size transition.

Does anyone know how to achieve the different fade in and fade out transitions described above with CSS?

2

There are 2 answers

3
bookcasey On BEST ANSWER

Here is a simplified test case:

div {
    background: blue;
    opacity: 0;
    transition: opacity 2s ease-in-out;
}

div.loading {
    opacity: 1;
    background: red;
    transition: opacity 2s ease-in-out, background 1s ease-in;
}

Notice how the opacity fades the same in and out, but the background only fades in, and immediately turns blue on fade out.

I used :hover as an example, but it should work the same when adding and removing classes with JavaScript.

Demo

If you'd like a more specific example please provide a reduced test case on dabblet or Jsfiddle.

1
Tigerrrrr On

Use the :hover for the 'transition out' effect, and the base selector for the 'transition in' effect:

div {
  background: transparent;
  transition: 3s; /* Mouse Leave */
}

div:hover {
  background: red;
  transition: 1s; /* Mouse Enter */
}

Working Example: https://jsfiddle.net/obtd6nxz/15/

Brief Explanation: :hover rule will override the base rule, but only while hovering. As soon as your mouse leaves, the transition-out effect will continue from what your base rule declares.