0

I want add a transition on height property, dynamicly in JS, and change the height poperty in same time (to rig the transition) like:

$('#foo').css({transition: 'height 5s linear', height: '100%'});

the height change right, but no transition happend. If i rechange the height, this time, transition is effective.

So why don't works the first time? How can I do it?

EDIT

I discover the true problem: I create DOM element #foo in JS, just before try to change her CSS: http://jsfiddle.net/31d57n55/2/ if you uncomment line 2, it will work, because it let the time to new DOM to be ready to use... So how can I know when this new node of DOM is ready?

Matrix
  • 3,458
  • 6
  • 40
  • 76
  • I think the transition is started with cached value of the current height... Instead of describding what is not working, If you explain what you meant by *"to rig the transition"* - there might be some other way. – T J Oct 12 '14 at 16:32
  • I try to do it in two times: ```$('#foo').css({transition: 'height 5s linear'});``` and ```$('#foo').css({height: '100%'});```, but same result – Matrix Oct 12 '14 at 16:57
  • I don't think changing it before the transition end will restart it. Like i said, if you explain what you're trying to do instead of saying what is not working you might get help... – T J Oct 12 '14 at 17:00
  • I want to trigger a animation with JS. What is not clear? Transition is not in css because change dynamically in JS code. – Matrix Oct 12 '14 at 17:20

2 Answers2

0

Try using .animate() instead of .css().

$('#foo').animate({'height': '100%'}, 500);

If you want to include some easing effects, you need to include jQueryUI effects also, and then the code would be:

$('#foo').animate({'height': '100%'}, {easing: 'easeInOutCirc', duration: 500});

EDIT: Alright, then make a class for the element, say, .in-transition, which would be:

.in-transition{
    -webkit-animation: animateHeight 0.5s linear forwards;
    -moz-animation: animateHeight 0.5s linear forwards;
    -ms-animation: animateHeight 0.5s linear forwards;
    -o-animation: animateHeight 0.5s linear forwards;
    animation: animateHeight 0.5s linear forwards;
}

@keyframes animateHeight {
    0% {
        height: (enterCurrentHeight || set it to 0 beforehand);
    }

    100% {
        height: 100%;
    }
}

@-webkit-keyframes animateHeight {
    0% {
        height: (enterCurrentHeight || set it to 0 beforehand);
    }

    100% {
        height: 100%;
    }
}

And then you only add/remove that class:

$('#foo').on('click', function(){
    var this = $(this);
    this.addClass('in-transition'); //or use toggleClass
});

Explanation for (enterCurrentHeight || set it to 0 beforehand):

If your #foo element has some height already when you want to start the animation, you need to set the animation's height value to that height as a starting point. e.g. #foo{height: 60px;} before animation starts. In that case, animation's keyframes would look like this:

@keyframes animateHeight {
    0% {
        height: 60px;
    }

    100% {
        height: 100%;
    }
}

Otherwise you'd have that jump effect, where the element's height would go from 60px to 0 (animation start point) and then to 100%.

BUT, if the element's height is 0 beforehand e.g. #foo{height: 0;}, you would set 0 as animation's starting point.

@keyframes animateHeight {
    0% {
        height: 0;
    }

    100% {
        height: 100%;
    }
}

Last solution: Ok, now I get your problem, but you can't solve it using .css(). My suggestion is this, instead of creating and appending the #foo element on load, make it directly in your HTML. As its initial height is defined as 0 by CSS, it won't be seen. Then you would only add .in-transition class to it on load.

Notice: #(id) selector beats .(class) selector, so you need to attach .in-transition to #foo, e.g. #foo.in-transition, very important

HTML:

<div id="foo"></div>

CSS:

#foo{
    height: 0;
    width: 100px;
    background: red;
    transition: all 0.5s ease;
    -webkit-transition: all 0.5s ease;
}

#foo.in-transition{
    height: 100px;
}

JS:

(function(){
    var $foo = $('#foo');
    $foo.addClass('in-transition');
} 

Working example: http://jsfiddle.net/31d57n55/5/

Man, talk about a long answer.

Davion
  • 881
  • 6
  • 12
  • No, animate function is crappy function, I use only CSS3 on my app ;) – Matrix Oct 12 '14 at 17:28
  • I gave you one more solution ;) – Davion Oct 12 '14 at 17:41
  • I don't know "set it to 0 beforehand", it's possible in CSS? – Matrix Oct 12 '14 at 18:00
  • Yes, for example like this: `#foo{height: 0}` or `#foo{height: 60px}` or `#foo{height: valueThatYouWant}`. I can almost smell the trolling here. – Davion Oct 12 '14 at 18:05
  • I explained that part in my original post. – Davion Oct 12 '14 at 18:24
  • Ok, I have miss understoud. I want use Transition, not animation, but the true problem is the trigger, in your exemple you used "click" event, so you don't have my problem with this method. My problem occure when in same frame you add transition rule and change the property of this rule. – Matrix Oct 12 '14 at 19:04
  • Well, it doesn't really matter what kind of event I was using in this 2nd example, it's all the same. I can't help you more than this unless I see your code, as I have no idea why would you add transitions inside `frames` (I don't even know if that works). – Davion Oct 12 '14 at 19:10
  • In fact, in my use case, I create DOM element in JS and after I want add the transition and to triger it. So my problem is the time to append this new élement: http://jsfiddle.net/31d57n55/2/ (if you uncomment console.log() it will work, if you add a setTimeout too). So the good solution it's how can I do a callback when new DOM element is ready to use?! – Matrix Oct 12 '14 at 19:26
0

The problem: it's the time to append DOM element (http://jsfiddle.net/31d57n55/2/)

$('<div id="foo"></div>').appendTo('body') //console.log($('#foo')); $('#foo').css({height: '100px', transition: 'height 5s linear'}); if uncomment line 2, it will work (on FF, on chrome setTimeout of 0 work: http://jsfiddle.net/31d57n55/8/), because it's let the time to DOM to be ready...

SOLUTIONS: 2 hack possible, look at CSS Transition Not Firing

Community
  • 1
  • 1
Matrix
  • 3,458
  • 6
  • 40
  • 76