2

I run into this problem in every single project, and I'm fed up enough at this point to ask.

I'm wanting to use css3 for fade animations on things because of how nice and smooth it is compared to fadeIn, etc.

The problem is, 99% of the time I'm fading in something that is initially set to display:none; (meaning, just having it at opacity: 0 to start, and changing it to opacity: 1 with jQuery isn't good enough.

For example, for my drag and drop functionality, I have an absolute positioned div: #dropzone, and that obviously can't be covering the entire app (but just set to zero opacity the whole time).

If I try adding $('#dropzone').show().css('opacity',1) there is no fade.

When it finishes .show(), it's still set to opacity 0 (I know because if I stop it right there, nothing shows up. It's set to display:block with opacity: 0) -- it also already has the proper css3 transition properties on it, so why would it not animate by the time it hits .css()?

This has plagued me so much, I would love to fix this or know the proper way.

Thanks

http://jsfiddle.net/fPtU5

edit added jsfiddle

Tallboy
  • 12,847
  • 13
  • 82
  • 173

3 Answers3

1

Figured it out with the help of this article: http://www.greywyvern.com/?post=337#

.dropzone {
    visibility:hidden;
    opacity:0;
    background: rgba(0,0,0,.85);
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9999;
  -webkit-transition: visibility 0s ease-in-out .2s, opacity .2s ease-in-out;
   -moz-transition: visibility 0s ease-in-out .2s, opacity .2s ease-in-out;
    -ms-transition: visibility 0s ease-in-out .2s, opacity .2s ease-in-out;
     -o-transition: visibility 0s ease-in-out .2s, opacity .2s ease-in-out;
        transition: visibility 0s ease-in-out .2s, opacity .2s ease-in-out; 
}  

.opaque {
    visibility:visible;
    opacity:1;
    transition-delay:0s;
} 

And then when you want to trigger fade in/out add/remove this class

$('.dropzone').addClass('opaque');

Tallboy
  • 12,847
  • 13
  • 82
  • 173
1

I don't know why the display property hoses the css animation, but here are some interesting observations/modifications to your original fiddle. http://jsfiddle.net/5RF5A/. Even just a ms of delay between setting the display to block and the opacity to 1 will allow the css animation to work.

I run into this issue all the time when trying to use css to animate opacity, but at the same time needing display:none to take the element out of the document flow. I usually add position:absolute or height/width:0 or visibility:hidden (while opacity is 0) instead of display:none so I can still animate the opacity.

My guess, (and i'm curious enough to go do some research after this), is it is some sort of browser reflow/repaint thing. Could be way off but that's where i'll start looking

Edit: Found Transitions on the display: property. Has some very good answers/insight into the issue.

Community
  • 1
  • 1
brains911
  • 1,310
  • 7
  • 5
  • Another interesting note is you can also get to see the animation if you just use $('div').show(0).css('opacity',1); (see http://jsfiddle.net/3leven11/fPtU5/5/) It would obviously have something to do with the default time for show() holding display:none; and at the same time, starting the next call which triggers the animation via CSS. – samazi Nov 10 '12 at 06:43
0

I tried a bit, then got it working using a plugin, then realized the code actually worked without the plugin, apparently using the transition.

JSFiddle

$('a').click(function(){
    $('div').show().animate({'opacity':1});
});
DSKrepps
  • 641
  • 1
  • 7
  • 15
  • without the plugin it's animating with a variant of fadeIn(), which is okay mostly but definitely not for performance (css3 is gpu accelerated). I did find from an article though that changing the display property at any point will destroy a css3 animation and prevent it from running. I dont understand why but it seems i must use visibility: hidden. It still makes it difficult to fade out however – Tallboy Nov 10 '12 at 05:39
  • So then does `animate` just lift the duration from the CSS3 and apply it to it's own animation? It doesn't look any different on my PC. – DSKrepps Nov 10 '12 at 05:45
  • animate() is an out of the box jquery method that iteratively changes the opacity (or whichever property), although its resource intensive for large elements. Css3 is something entirely different, and is much much smoother, but is quirky sometimes. – Tallboy Nov 10 '12 at 05:47
  • I mean to say that in my JSFiddle the duration of the animation is from the transitions, despite being activated by `animate`. If you remove the CSS3, the animation speed is jQuery's default. So the CSS3 is definitely doing something even when `animate` is called. – DSKrepps Nov 10 '12 at 05:49