2

I have previously asked a question about triggering a CSS transition with JavaScript & setTimeout (JavaScript: Trigger CSS Transition with window.setTimeout). This question is trying to get more information on that.

I have a function which changes the content and fades in a paragrapn p#test:

function test() {
    var done=false;
    var p=document.querySelector('p#test');
    window.setInterval(doit,4000);
    var data=0;

    function doit() {
        p.removeAttribute('on');    //  1
        p.offsetHeight;             //  2   force update
        p.innerHTML=data++;         //  3
        p.setAttribute('on',null);  //  4
    }
}

The CSS is:

p#test {
    opacity: 0;
}
p#test[on] {
    transition: opacity 1s;
    opacity: 1;
}

I note that the transition property must be set in the p#test[on] rule. If set for the p#test rule, it will not work.

I find that steps 2 & 3 above can be interchanged.

However, I cannot get it working at all if I try to set the properties in JavaScript alone:

function doit() {       //  DOES NOT WORK
    p.style.opacity=0;
    p.offsetHeight;
    p.innerHTML=data++;
    p.style.opacity=1;
}

So I conclude:

  • Changing an attribute (or class) in JavaScript will trigger a CSS transition
  • Changing a CSS property in JavaScript will not trigger a transition
  • The transition will only be triggered if the transition property in in the triggered rule.

Sorry about the long preamble. The question is:

Precisely what JavaScript will actually trigger a CSS transition? Is it only a change of class or attribute, or will anything else work?

I have added a Fiddle here: https://jsfiddle.net/comparity/a7qt297m/

Community
  • 1
  • 1
Manngo
  • 14,066
  • 10
  • 88
  • 110
  • Could you please paste your example on https://jsfiddle.net/ ? – TylerY86 Sep 27 '16 at 05:35
  • @TylerY86 Done. See above … – Manngo Sep 27 '16 at 05:42
  • So you are saying `doit2` won't trigger the transition, even if `transition:opacity 1s;` is in the `p#test` rule? – TylerY86 Sep 27 '16 at 06:12
  • @TylerY86 That’s right. Ideally I would put it all in the JavaScript so that the effect doesn’t depend on separate CSS, but I don’t think it will work. – Manngo Sep 27 '16 at 06:15
  • You should be aware of the difference between changing the style state of the element and triggering a transition; style state changes have no *lag*, they don't animate or transition. Changing anything is selectable by a rule on the element allows new rules to apply, triggering transitions. Explicitly setting opacity does not trigger a transition. Selector precedence also comes into play to determine if style state actually changed. – TylerY86 Sep 27 '16 at 06:19
  • *Changing anything **that** is selectable .... – TylerY86 Sep 27 '16 at 06:46

1 Answers1

0

Dumb question, but does the base element (p#test) also have the transition property on it? In your example code, the transition property is only there for the "on" state.

If that's not it, it could be because you're changing the opacity from 0 to 1 in immediate succession in the same function. See if a tiny setTimeout can make a difference for the opacity=1 line.

Jon Uleis
  • 17,693
  • 2
  • 33
  • 42
  • In my testing, it doesn’t work if I put the `transition` on the base element. I don’t know why. As regards the changes, it works perfectly if I remove and set the attribute, so long as I include the `p.offsetHeight` (or any other statement which is known to trigger the layout). – Manngo Sep 27 '16 at 05:31