2

Suppose I have some CSS so #joe { transition: opacity 500ms; opacity: 0; }

Then I have JavaScript so when you click the page it adds the div and then animates opacity to = 1.

document.body.onclick = function () {
  var joe = document.createElement('div')
  joe.innerHTML = 'yo!'
  joe.id = 'joe'
  document.body.appendChild(joe)
  joe.style.opacity = 1
}

Well, it doesn't animate. (I guess because the CSS transition considers it an 'initial page load')

But if you add a timeout

document.body.onclick = function () {
  var joe = document.createElement('div')
  joe.innerHTML = 'yo!'
  joe.id = 'joe'
  document.body.appendChild(joe)
  setTimeout(function () {
    joe.style.opacity = 1
  }, 100)
}

Then the animation works.

But in some situations, even a 100ms delay has a visible affect on the apparent responsiveness of the page. And, unfortunately, setting the timeout to 1ms doesn't work.

So, what should the timeout be? I am looking to have animation that works most all the time across major browsers, but I don't want to raise the timeout without good reason.

I am not interested in jQuery animation because in my experience it is less efficient than CSS transitions, and doesn't sync multiple animations well. I'm open to suggestion if there's another JavaScript implementation that wins over CSS, but don't let that stop you from answering the question.

If there is an initial animation for CSS, that would be nice to know...

But what I really want to know is how the timeout should be set, because sometimes I animate left or width and I don't want to have to code in start and finish into CSS, when I need to use JavaScript to dynamically calculate these values.

7
  • 1
    jQuery animation is more efficient, javascript animation is not necessarily though. Commented May 8, 2014 at 18:54
  • 1
    velocity.js is an even more efficient version of animate(); , but I think the OP needs a callback(); after the div is inserted to the dom, to fade it from 0 to 1 opacity or something. Commented May 8, 2014 at 19:05
  • I have 'seen' where jQuery is less 'smooth' than the native CSS animation. This is more noticeable when you have a larger number of elements involved. But that may just be my personal browser experience. Still, it stands to reason that 'native' CSS animation should be more efficient and thus more smooth than JavaScript (jQuery, etc) could ever be. (that's my opinion) Commented May 8, 2014 at 19:06
  • 1
    davidwalsh.name/css-js-animation Facts are fact. I use them all for different reasons in different places. hovers with css, and more complicated animations with velocity. The problem seems to me, to be about the order of things and not really animation at all. If you create the div, and then add the style after, like the bandaid timeout, then it'll work. Commented May 8, 2014 at 20:54
  • 1
    I think it has to do with the browser - and how it handles it... I'm not sure.. but I wouldn't be surprised - if everything leads back to scripting... - as in... what makes the CSS declaration do anything anyways? The browser... and if the browser can't paint things fast enough... then it's not going to be optimal... but maybe in a year CSS transition declarations... and whatever actually drives them under the browser's hood... might be way smoother... Most html5 stuff is javascript modules... so the 3 amigos are html css and javascript. No use in leaving one out - it's already there... Commented Jun 8, 2014 at 19:18

2 Answers 2

1

It is possible to implement it without setTimeout using window.getComputedStyle().

Basic idea is:

joe.style.opacity = 0; //unnecessary in this case, set by css class   
window.getComputedStyle(joe).getPropertyValue("width");
joe.style.opacity = 1;   

Here is the jsfiddle: http://jsfiddle.net/4Vy9n/2/

Sign up to request clarification or add additional context in comments.

1 Comment

Any benefit in using window.getComputedStyle(joe).getPropertyValue("width"); rather than the more simple approach joe.offsetWidth;? Sure both are terribly hackish, but as far as I can see both of them just flush the repaint/reflow(relayout) queue.
0

Very simple, here is a pure CSS solution:

Demo http://jsfiddle.net/X7Zg5/7/

CSS:

.joe {
    font-size: 100px;
    -webkit-animation-duration: 500ms;
    -webkit-animation-name: fadeIn;
    -moz-animation-duration: 500ms;
    -moz-animation-name: fadeIn;
    -o-animation-duration: 500ms;
    -o-animation-name: fadeIn;
    animation-duration: 500ms;
    animation-name: fadeIn;
}
@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
@-webkit-keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
@-moz-keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
@-o-keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

JS:

document.documentElement.onclick = function () {
    var joe = document.createElement('div');
    joe.innerHTML = 'yo!';
    joe.className = 'joe';
    document.body.appendChild(joe);
}

2 Comments

See my question "sometimes I animate left or width and I don't want to have to code in start and finish into CSS". The primary problem with coding it in this way is that I don't actually know the 'start' and 'finish' position without using JavaScript to make the calculation.
@sheriffderek Actually the JS is commented out but I removed it anyways.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.