Closed Bug 571748 Opened 14 years ago Closed 14 years ago

appending element and changing style value within a single function fails to trigger CSS transition

Categories

(Core :: CSS Parsing and Computation, defect)

x86
All
defect
Not set
minor

Tracking

()

RESOLVED WONTFIX

People

(Reporter: nirvn.asia, Unassigned)

Details

Attachments

(1 file)

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
Attached file test case
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.
Assignee: general → nobody
Component: JavaScript Engine → Style System (CSS)
QA Contact: general → style-system
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.
> 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.
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 :)
> 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.
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?
Status: UNCONFIRMED → RESOLVED
Closed: 14 years ago
Resolution: --- → WONTFIX
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.
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.
Mathieu, apparently the www-style moderator is away...  I've forwarded along your mail.
Thanks
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: