Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Wix Wow!Team

Chrome and clearprops:"transform" unexpected behavior

Recommended Posts

I came across an unexpected behaviour:

apparently Chrome 36 and up supports both prefixed and unprefixed 'transform' property.

 

So, if you set initial transform values on an element (not with GSAP) like so:

someElement {
    -webkit-transform:rotate(30deg);
    transform:rotate(30deg)
}

and do

TweenMax.set(someElement, {clearProps: 'transforms'})

only the unprefixed version is being cleared and the rotation remains on the element.

Link to post
Share on other sites

I think this is just a misunderstanding of how clearProps functions. clearProps only clears the properties from the style attribute; it doesn't modify or delete anything from your stylesheets. i.e.

<div id="foo" style="transform: rotate(50deg)"></div>
TweenLite.set("#foo", { clearProps:"transform" });
<div id="foo" style=""></div>

Any styles in your CSS will no longer be overridden by the style attribute so they'll be restored.

  • Like 4
Link to post
Share on other sites

My example was wrong. I meant inline style of course.

someElement.style.transform = 'rotate(30deg)'
someElement.style.webkitTransform = 'rotate(30deg)'
Link to post
Share on other sites

Hi Wow!Team  :)

 

try this : { clearProps: "-webkit-transform" }

someElement.style.transform = 'rotate(30deg)';
someElement.style.webkitTransform = 'rotate(30deg)';

TweenMax.set(someElement, {clearProps:"-webkit-transform"});
TweenMax.set(someElement, {clearProps:"transform"});
// or TweenMax.set(someElement, {clearProps:"all"});
  • Like 1
Link to post
Share on other sites

And you can separate multiple props with a comma

TweenMax.set(someElement, {clearProps:"-webkit-transform,transform"});
  • Like 4
Link to post
Share on other sites

Sorry for being rude, but you are both stating the obvious, and missing the point.

When using Greensock I'm not supposed to worry about vendor prefixes.

This is a bug, since I clear the transforms but because of a non-standard Chrome behaviour they are not completely cleared.

 

(Sorry for using 2 different users, the other one is my team's club member user )

Link to post
Share on other sites

Hey Tom. Sorry to hear about the frustration. I have a few questions for you:

  1. Why are you setting an inline style like that, with both prefixed and non-prefixed versions of the same property? If you're using GSAP anyway, why wouldn't you use it to manage the transforms for you? That'd be much cleaner and more performant because it can cache the values rather than having to parse the whole matrix string initially. I would strongly recommend that you use GSAP and avoid setting multiple inline styles for the same property. 
  2. If Chrome does honor BOTH of those transforms (prefixed and non-prefixed), can you see how that'd pose problems in terms of managing the values? If both are set to different values ("transform:rotate(30deg); -webkit-transform:rotate(10deg)" for example), which should be honored? And do you really want to have 2 values set each time something is updated? It's twice the work (worse performance).

When GSAP loads (well, CSSPlugin), it checks to see if the browser recognizes non-prefixed transforms and if so, that's what it uses (clearly that's how it should work, since prefixes are more like band-aids and they'll eventually be dropped by browsers). It doesn't keep checking and say "oh, it handles non-prefixed...and also prefixed...let's do BOTH!" because that'd be wasteful. So that conditional logic runs once at startup and locks in the appropriate property name ("transform" in this case). So yes, GSAP automatically handles prefixing for you if/when it's necessary. But I don't think it's reasonable to expect it to handle situations like this where you're trying to manually set BOTH prefixed and non-prefixed values inline on the same property. Frankly, if you're going to manually set inline stuff like that, I think it's on you to properly sense the appropriate property name and always prioritize non-prefixed when the browser supports it. 

 

I'm not sure what a better alternative would be. If we injected code into GSAP to constantly check if you happen to be manually assigning prefixed values when the browser doesn't need it, and then GSAP has to set both values, can you see how that'd be a heavy price to pay for everyone (performance-wise and kb-wise) just to remedy this edge case that arguably shouldn't be an issue anyway? 

 

So it seems like there are three solutions on the table:

  1. Use GSAP to manage your transforms (I'd strongly recommend this) 
  2. Do the proper sniffing on your end to assign the correct property name inline ("transform" or "-webkit-transform" if necessary, but not both).
  3. Use Jamie's suggestion of a comma-delimited list that includes prefixed and non-prefixed flavors. 
  • Like 3
Link to post
Share on other sites

Hi Jack,

as I told you some time ago, we rewrote our entire system with ReactJS.

React uses it's own (very cool) method to render HTML - The general idea is that It holds a virtual JSON representation of the DOM and handles DOM reads and writes for you using precise JSON diff methods in a very performant way.

 

So When you build a site based on React components you actually never interact with the DOM, you interact with React, and React in it's turn decides when its the best time to read or write the DOM.

 

Some of the consequences of this method is that you get a lot of inline style declarations for mutable values, and, you don't have the opportunity to use DOM heavy tools like GSAP to do elementary operations.

 

We use GSAP almost solely for animations, which by their nature happen after the rendering lifecycle of a site ended,  after everything is built and presented to the user where it cannot interfere with with DOM read/write performance.

 

This specific bug happens where someone applies a rotation (not a rotation animation) on a component and the system just applies it somewhere in the rendering process.

I eventually worked around this by writing a more robust browser prefix detection function for css transforms, so the -webkit- prefix is no longer applied in Chrome.

 

I still think that since this behaviour of chrome is non-standard, frameworks that by design are built to spare the user the hassle of handling browser prefixes should handle it too.

 

Thanks for the quick replies btw.

GSAP Rocks! :)

Link to post
Share on other sites

I totally see why you'd want (and maybe even expect) GSAP to just handle anything and everything related to prefixing for you. And sure, we could inject code for edge cases like this. The key question is SHOULD we do that, and why? 

 

It's always a balancing act for us - we place a HUGE priority on performance because animation is probably the single most performance-sensitive thing in every project. Nobody will care if GSAP makes development more convenient if runtime performance sucks and you get jerky animations. Another big priority is flexibility and making things "just work" (getting around various browser bugs, inconsistencies, etc. to make your job easier as a developer to have fun animating). But again, every feature has to pass through a decision making matrix that compares the benefits and costs. 

 

In this case, the following facts are important to keep in mind:

  1. In all our years of doing this, you're the first person who has ever requested a feature like this (or run into the problem you're describing). So adding the necessary code to work around the issue benefits one person now (maybe more in the future), representing a tiny fraction of the user base, but we'd be forcing every user to pay the performance and file size price. The cost-benefit ratio is pretty bad.
  2. In my opinion, this issue is not the result of any problem in GSAP but rather a poor practice in another framework that's leaking out (if I understood correctly, you're saying React doesn't properly sense browser prefixes and prioritize non-prefixed properties - it applies BOTH). So really the fix should be applied on the other end, not in GSAP. That's the cleanest approach that would deliver the best performance and tightest file size. 

In some ways it's our own fault for delivering so much convenience and cross-browser compatibility that we've trained our users to just expect that GSAP will solve everything, so I don't blame you for being disappointed that GSAP doesn't just automatically sense what you're doing and solve it. But again, I'd ask you to look past your immediate frustration and see the bigger picture and how it affects ALL users and the product as a whole. There are certain common practices we expect users to follow and CSS/HTML imposes some structural constraints that we all must live within, and if GSAP starts getting overzealous about "fixing" certain types of issues, it can cross boundaries that shouldn't be crossed. 

 

For example, perhaps a user has this HTML:

<div style="display:none;">
    <div id="thing"></div>
</div>

And then they run this tween:

TweenLite.set("#thing", {visibility:"visible"});

And then they're so used to GSAP "just working" that they get frustrated when their "#thing" doesn't show up as visible on the screen, blaming GSAP. Well, their parent container has display:none on it, so obviously that won't work but the user could legitimately complain, saying GSAP should figure out that when they make something "visible", it should...figure out how to do that (in this case, walk up the chain through all ancestor elements, check their visibility and display values and ensure they're...um...not invisible). Hopefully it's clear why we wouldn't do that, though. So there are certain expectations we place on users to follow common standards and not expect GSAP to solve issues they're introducing (at least within reason). Yes, we'll provide conveniences wherever we can, as long as it's not too costly performance-wise or kb-wise. 

 

Make sense? 

 

I do apologize that GSAP seems to be letting you down in this scenario, but I hope you see why applying a "fix" would be too costly. My goal here is to make sure your app (and everybody else's) gets the absolute best performance it possibly can. 

 

I'm glad to hear you figured out a solution on your end. 

  • Like 2
Link to post
Share on other sites

Thanks for the detailed answer Jack.

 

1st - GSAP is not letting me down in any way.

I worked around this days ago on my side. As you said, part of the problem was bad practice on our side

 

But as you can imagine in a project like the Wix Editor we are stretching the abilities of the browser and of various frameworks we work with to their max.

You won't believe how many weird edge cases and bugs we encountered and worked around or solved in the past couple of years. 

 

We work with libraries like GSAP, React, RequireJS, Zepto, Grunt and many others on the client side, and even more on the server side, and we contribute back tons of enhancements and bug fixes every day.

 

To the topic - 

This bug is a new bug. It doesn't exist for so long, just since chrome 36.

Also, many frameworks and preprocessing tools don't try to detect browser prefixes, they just add all the prefixes for the browsers you tell them you support (the very popular Autoprefixer for example).

 

As a framework maintainer you know that you are not living on your own isolated island, you have hundreds of other frameworks and the browsers themselves you have to play nice with. Also, stupid browser bugs come and go with every version and we as developers that our work is seen by millions of people every day have to deal with them. even if they are arbitrary or temporary or not our fault.

 

Thats it. I'll stop poking this issue now.

  • Like 1
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×