Last Comment Bug 571748 - appending element and changing style value within a single function fails to trigger CSS transition
: appending element and changing style value within a single function fails to ...
Status: RESOLVED WONTFIX
:
Product: Core
Classification: Components
Component: CSS Parsing and Computation (show other bugs)
: unspecified
: x86 All
: -- minor (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
:
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-06-13 01:52 PDT by Mathieu Pellerin
Modified: 2010-06-24 20:31 PDT (History)
2 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
test case (1.27 KB, text/html)
2010-06-13 01:52 PDT, Mathieu Pellerin
no flags Details

Description Mathieu Pellerin 2010-06-13 01:52:00 PDT
User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.3a6pre) Gecko/20100611 Minefield/3.7a6pre
Build Identifier: 

I noticed appending an element and changing style values within a single function fails to trigger CSS transitions.

If however you change the style values triggered by a very short timeout, it'll work fine.

I find it rather unpractical and at odd with what is to be expected of CSS transition. 

See attached test case.

Reproducible: Always
Comment 1 Mathieu Pellerin 2010-06-13 01:52:53 PDT
Created attachment 450909 [details]
test case
Comment 2 Boris Zbarsky [:bz] 2010-06-13 14:24:59 PDT
Not a js engine issue.

That said, I think this is invalid as the spec currently stands (and note that Webkit has the same behavior).  In general, transitions are meant to go from one "rendered" state to another, and this testcase never really renders the old state.

Specifically, note that http://www.w3.org/TR/2009/WD-css3-transitions-20091201/ section 3 says:

  When the value of an animatable property changes, implementations must decide
  what transitions to start based on the values of the ‘transition-property’,
  ‘transition-duration’, ‘transition-timing-function’, and ‘transition-delay’
  properties at the time of the change. Since this specification does not
  define what property changes are considered simultaneous, authors should be
  aware that changing any of the transition properties a small amount of time
  after making a change that might transition can result in behavior that
  varies between implementations, since the changes might be considered
  simultaneous in some implementations but not others. 

In this case, all the style sets involved are simultaneous in Gecko now that lazy frame construction landed, so in fact the computed value of the property (which is what the above should explicitly say it's talking about in the first clause) never actually "changes".  The old specified value just never makes it through to a computed value, so the computed value starts at the new specified value.  Same in webkit.  This behavior is almost certainly not robust, though; you can produce the behavior you want by tossing "document.body.offsetWidth" right after your appendChild call.

Which seems suboptimal, so maybe we do need a spec change.  But I don't think we'd ever really want something like this:

  var div = document.createElement("div");
  div.style.backgroundColor = "red";
  document.body.appendChild(div);
  div.style.backgroundColor = "green";
  div.style.backgroundColor = "red";

to trigger transitions... though note that right now in Webkit and Gecko it can if you toss some style flushes in there (e.g. "document.body.offsetWidth" before that last style set).

In any case, this seems like a discussion for www-style@w3.org.
Comment 3 Mathieu Pellerin 2010-06-13 18:37:07 PDT
Without some sort of support for triggering transition within JS function after creating/appending element(s), CSS transition loses a lot of its usefulness in a dynamic HTML context.

Maybe it requires for the DOM to get a new function, like element.style.apply(), which would consider styles rendered/applied and trigger transition of styles subsequent to the calling of this function.

I'm afraid that without a spec addition/change to deal with CSS transition in a dynamic HTML context, the CSS transition won't really grow behind the "hey, cool HTML5 demo" that makes text spins using :hover declaration.
Comment 4 Boris Zbarsky [:bz] 2010-06-13 19:07:47 PDT
> triggering transition within JS function after creating/appending element(s)

Transitions are meant for going from one state the user sees to another state the user sees.  In the situation you're describing the user isn't seeing the first state at all.

Further, since you're in a situation where you know initial value, final value, and desired transition duration all in one spot, it seems to me that a different technology (SMIL animation, for example) might be closer to what you're actually trying to accomplish.  That is, transitions might just be the wrong tool for what you're trying to do.

> I'm afraid that without a spec addition/change 

The right place to bring that sort of thing up is the mailing list I mention at the end of comment 2.
Comment 5 Mathieu Pellerin 2010-06-13 19:23:26 PDT
Boris, thanks, I'll send something to the www-style mailing list.

Re what I'm trying to accomplish, I first thought it did not and now is of the opinion it should not be beyond the scope of CSS transition. I basically have a <div id="container"> in which I want to append a number of dynamic elements (for e.g. people description forms). I was hoping the CSS transition could offer a nice and clean way to fade-in the added forms within the container (versus simply going from nothing to the form). A transition from nonexistence to being.

That being said, ATM, the setTimeout trick isn’t the dirtiest workaround out there.

I did continue this discussion over bugzilla as you're putting forward good arguments which is always interesting to follow up :)
Comment 6 Boris Zbarsky [:bz] 2010-06-13 19:28:35 PDT
> I was hoping the CSS transition could offer a nice and clean way to fade-in the
> added forms within the container

Hmm.  Yeah, I can see how this would be nice to address (though if you were just using CSS to unhide existing display:none stuff that wouldn't transition either....)  Let's pick this up on www-style where we can get input from more people.
Comment 7 David Baron :dbaron: ⌚️UTC+2 (mostly busy through August 4; review requests must explain patch) 2010-06-13 20:33:03 PDT
I think this is an inherent flaw in the CSS Transitions spec, and I don't see a reasonable way around it.  So I'm going to mark WONTFIX for now, although if a way to fix it comes out of that discussion, we can reopen.

I think CSS transitions is designed for causing changes that are already going to be visible as changes to animate; wanting to cause other things to animate would probably work much better as a separate mechanism, though I'm not really sure what.  Maybe some sort of style attribute setter that says to set the value gradually?
Comment 8 Mathieu Pellerin 2010-06-14 22:04:15 PDT
Boris, I wrote to www-style@w3.org; since I'm not per default authorized to post, hopefully a maintainer will push it to the list soon.

I find it interesting to notice the setTimeout workaround for the current CSS transition limitation (or should we say lack in the current spec) is now being used within Firefox to animate the new tabs (see patch: https://bug543206.bugzilla.mozilla.org/attachment.cgi?id=450956).

Clearly, CSS transition could take an important role into offering visual transition for newly created elements.
Comment 9 Mathieu Pellerin 2010-06-22 00:50:54 PDT
Boris, I wrote to www-style@w3.org 9 days ago but my email has yet to be published on the mailing list (pretty hard to get a debate started if the argument doesn't reach the list :) ).

Would it be possible for a member, for e.g. you, to post it? Text below a copy/paste of email who I had hoped would reach the mailing list:

Greetings,

I recently started playing with CSS transitions and seem to have stumbled upon an important issue that could seriously restrict the usefulness and relevance of CSS transitions used within a dynamic HTML context.

Scenario: A web application makes use of a <div id=”container”></div> to dynamically append an indefinite number of form elements. The web developer would like to use CSS transition rules to create a visually pleasing fade-in when elements are appended.

The scenario translated into code:

<html>
<style>
div#container > div {
 opacity:0;
 transition-property:opacity;
 transition-duration:400ms;
</style>
<script>
function addForm() {
 var container = document.getElementById('container');
 var form = document.createElement('div');
 
 [...]
 
 //in theory, the div's opacity should be 0 when appended
 //as per defined in the CSS rule above
 container.appendChild(form);
 form.style.opacity = "1";
}
</script>
<body>
<div id="container"></div>
<input type="button" value="add form" onclick="addForm();">
</body>
</html>

Right now, current implementations (Mozilla, Webkit, Opera) respecting the CSS transitions spec all fail to provide a transition from opacity 0 to 1 when the appended form.style.opacity is modified within the function.

The desired effect can be obtained by delaying the opacity style change using a setTimeout() function. That is however subobtimal and rather impractical.

Without a modification or addition to the spec in order to deal with style change of appended elements within a dynamic HTML context, chances are CSS transition will be limited to :hover contexts only.

I hope this message is clear enough and can result in a fruitful discussion.
Comment 10 Boris Zbarsky [:bz] 2010-06-24 19:40:42 PDT
Mathieu, apparently the www-style moderator is away...  I've forwarded along your mail.
Comment 11 Mathieu Pellerin 2010-06-24 20:31:08 PDT
Thanks

Note You need to log in before you can comment on or make changes to this bug.