Jump to content
Search Community

Chrome stacking issue

Wylkyn test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I have been experiencing issues with using TweenMax animations in Chrome. I don't have any example code I can post, because this involves complex HTML courseware that our company develops. But here's an example situation that comes up in our course slides: a slide animation consists of various fullscreen images with text over them. When one of those background images fades and scales in behind the text, the text gets thrown behind it (essentially disappearing) until the image is done animating, at which point it pops back in. This only happens in Chrome, and it only happens when using TweenMax version 1.15.0 or later. I can use 1.14.2, and I don't get that issue. That's why we didn't notice this earlier because we were using an old version of TweenMax until just recently.

 

I have been researching this issue, and I know that it has to do with how Chrome prioritizes the stacking layers for rendering. What I don't know is what the best solution is. Setting z-index for the various elements does nothing. Nor does putting the text into a separate div from the other content. The stacking ignores all of that. Setting force3D to true for the text element fixes it for that specific situation. But that seems more like a bandaid than a real solution and would be an added pain for content development. Having the code set force3D to either true or false for all elements in the slide also fixes it. But obviously that's a bad idea either way, and would cause lag, especially on more complex animations.

 

Anyway, I've been beating my head against this for a while and was hoping someone might have suggestions that I could try. I know that my description is vague and abstract, so I understand if it's not enough to get any help. Feel free to ask me questions if it would help clarify.

Link to comment
Share on other sites

I had read briefly about will-change, but because of warnings about applying too often and too early, and also having to remove it after the animation is done, it seemed like a potentially complicated solution that would possibly require me to do change a lot more in our course code, so I was putting on the back-burner until I got really, REALLY desperate. :D Right now, the temporary bandaid of choice is rolling back to TweenMax v1.14.2, which is working, but is obviously not ideal. I still don't completely understand will-change, so I'll look over the article. Thanks for the link!

 

And I will see if I can rig up a simplified example. Just that process may help me figure something else out.

  • Like 1
Link to comment
Share on other sites

1 hour ago, Wylkyn said:

Having the code set force3D to either true or false for all elements in the slide also fixes it. But obviously that's a bad idea either way, and would cause lag, especially on more complex animations.

I wouldn't just assume it's a bad idea. It depends on a lot of factors and might be totally reasonable for you to use.

 

You can set the default value so that you don't need to do it in every tween. But it's very difficult to troubleshoot blind. Something sounds a little fishy here - is there any chance you could provide a reduced test case? It doesn't need to use the "real" artwork or anything. I just want to see the effect you're describing, as it sounds very odd to me and I'm quite concerned that you feel the need to use such an ancient version of GSAP. There have been scores of bug fixes and improvements since then. 

  • Like 1
Link to comment
Share on other sites

1 hour ago, Wylkyn said:

This only happens in Chrome, and it only happens when using TweenMax version 1.15.0 or later. I can use 1.14.2, and I don't get that issue. That's why we didn't notice this earlier because we were using an old version of TweenMax until just recently.

 

 

From the v1.15.0 release notes.

https://github.com/greensock/GreenSock-JS/releases/tag/1.15.0

 

Quote

NEW transform-related animations (like rotation, scaleX, scaleY, x, y, z, etc.) will automatically get GPU-accelerated when possible by using 3D transforms which is just like applying the popular "translateZ(0)" hack. This will only be applied in browsers that recognize 3D transforms. This should be most noticable on mobile devices (improved performance).

 

Some info about stacking contexts/layers. 

https://greensock.com/forums/topic/17523-transform-and-z-index-stacking-context/?tab=comments#comment-79156

https://dassur.ma/things/forcing-layers/

 

Crazy little buggers. The difference between box1 and box2 is that box2 has an opacity of 0.99.

 

See the Pen 7938e99217bbb6037ccb5ef4599a062c by osublake (@osublake) on CodePen

 

Instead of looking for a band-aid, you should probably fix the problem.

 

One way to help prevent getting bit by z-index problems. 

 

* {
  position: relative;
}

 

1 hour ago, Wylkyn said:

I had read briefly about will-change, but because of warnings about applying too often and too early, and also having to remove it after the animation is done, it seemed like a potentially complicated solution that would possibly require me to do change a lot more in our course code

 

Read the docs.

https://developer.mozilla.org/en-US/docs/Web/CSS/will-change

 

You should only put will-change on elements that WILL CHANGE. Do you need to remove will-change after animation? Like everything else in programming, it depends. I haven't found the need to.

 

I like Surma's conclusion:

Quote

For now, we only have will-change and my advice is: Use will-change: opacity or backface-visibility: hidden to force an element onto its own layer as it seems like the side-effects are the most unlikely to be a problem. Only if you are truly going to change the transform should you be using will-change: transform.

 

  • Like 4
Link to comment
Share on other sites

14 hours ago, GreenSock said:

Something sounds a little fishy here - is there any chance you could provide a reduced test case?

I will attempt to do so. Our HTML course code is fairly complex having been developed since 2013 (it involves an HTML UI shell that loads content HTML pages into an iFrame), so any example is going to have to be massively reduced. And I've never used Codepen before. But I will give it a shot and see if I can produce a similar issue.

 

I know it's ridiculous to ask people to help me blind. I guess I was hoping that my issue would sound familiar to someone. I'll see what I can come up with and hopefully it will be close enough to be helpful. Or, if I can't manage to replicate a similar issue in any simplified example, maybe that will tell me something. Either way, I'll let you know.

 

Thanks!

Link to comment
Share on other sites

14 hours ago, OSUblake said:

Instead of looking for a band-aid, you should probably fix the problem.

Oh, I hear you! I am definitely looking for an actual solution rather than a band-aid. I do not trust quick fixes because they usually end up making more work in the long run. But, unfortunately, I don't typically get to dictate how I spend my hours. At the moment, I've been tasked to fix this and have an unknown amount of time to get it done, so I want to find a solution before another task pushes this onto the back-burner again. That's why I wrote my post, and I really appreciate you all taking time from your own busy schedules to offer me guidance! I'll look over the links you provided, and I'm going to try to see if I can produce some sort of simplified test case. Thanks again!

Link to comment
Share on other sites

I made a simplified version of one of our slides in Codepen, but could not recreate the issue in that environment. So there must be something in our complex course code that is contributing to the issue. For example, the UI HTML page loads the individual content pages into an iFrame, the content elements are created dynamically, the animation for the content is run by the parent UI, etc. I don't know what might be contributing to the issue, and trying to eliminate all these possible factors one at a time is problematic.

 

I'm already being pulled off onto another project (that didn't last long), but I will continue to research and try to figure this out. Thanks!

Link to comment
Share on other sites

Everything you described sounds like a stacking context issue. We get a similar question like every month. 

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context

 

You can look in the layers tool in Chrome's dev tools to see why a layer was created. 

 

Some more links for people who come across this thread. Understanding how z-index works. It's kind of important.

https://philipwalton.com/articles/what-no-one-told-you-about-z-index/

https://www.smashingmagazine.com/2009/09/the-z-index-css-property-a-comprehensive-look/

 

 

  • Like 1
Link to comment
Share on other sites

Hi @Wylkyn and Welcome to the GreenSock Forum!

 

Try to inspect the transformed childrens parent that have the transform. More than likely your children are getting put on a new stacking context (layer). Which means their parent will also need to be put on its own new stacking context if you see clipping or other stacking issues. This way it can render correctly with its transformed children.

 

Also most of the time its the original markup and position offsets setup of the position offsets: fixed, absolute and relative. They can easily be figured out by looking at the top most parents of the positional offset children. That is why you make sure that your top most parent of your absolutely positioned elements have position relative along with z-index if needed. But that will help you troubleshoot and position elements with z-index much easier.

 

But since we cant see your markup and rendered css causing your issue.. then when in doubt.. add a new stacking context to your transformed childs parent.

( see what gives a new stacking context here )

 

Happy Tweening :0

  • Like 2
Link to comment
Share on other sites

On 10/2/2019 at 11:21 AM, OSUblake said:

Everything you described sounds like a stacking context issue. We get a similar question like every month.

 

Yeah, I actually had read some of your previous posts about that before I even wrote my question. They were very helpful. That's the only reason why I knew it had to do with the stacking context, and how I found out that the Layers dev tool even existed in Chrome! I'm just having trouble figuring out the proper fix here because our course code is so complicated. I can try to explain how it works, though it probably won't be all that useful.

 

Our courses consist of a main UI HTML page that loads individual content HTML pages into an iFrame. The UI HTML controls all the navigation (menu, next and previous buttons, pause/play, etc.), and runs the animation for each loaded content HTML, usually based on the timecode of an audio or video file. Once a content HTML file is loaded and before the animation for that slide begins, each element that will appear in that slide is dynamically created and wrapped in its own div that has display:block and position:absolute. These elements are added to the content HTML file's container div which has position:relative. And the whole course scales to fit the browser, so many of the elements have transforms on them, including the content HTML file's container div.

 

Here's a screenshot of the layers in a course slide where two background images change behind some text:

image.thumb.png.5d0575663ab657239f42b75e95489e68.png

The above image shows the layers of an animation where there are two images underneath some text. This is the moment where the second image behind the text is scaling/fading in. The selected layer (that the Details section is describing), the one with the red arrow pointing at it, has the first image and the text composited together. The second image that is coming in is the layer with the blue arrow. The odd thing is, even when I tried animating the text (changed its opacity from 1 to 0.999) at the same time as the second image, it still is composited with the first image.

Link to comment
Share on other sites

I would assume the best way to fix it might be to change how some of your layers are nested, and possibly by forcing the creation of layers with CSS. That should have the same effect as setting force3D to true.

 

I like the challenge from this article. It really helped me understand how layers worked.

https://philipwalton.com/articles/what-no-one-told-you-about-z-index/

 

Try to get red square behind the green and blue squares.

See the Pen ksBaI by philipwalton (@philipwalton) on CodePen

 

He used opacity, but you could use will-change.

div:first-child {
  will-change: transform;
}

/* OR */
div:first-child {
  will-change: opacity;
}

 

I know you said you were hesitant about using will-change, but I think a lot of the initial problems have been ironed out over time. I don't remove will-change from an element unless I notice a problem. And in Firefox's dev console, it will give you a warning if you're using will-change too much.

 

  • Like 1
Link to comment
Share on other sites

On 10/1/2019 at 3:19 PM, Wylkyn said:

Setting force3D to true for the text element fixes it for that specific situation. But that seems more like a bandaid than a real solution and would be an added pain for content development. Having the code set force3D to either true or false for all elements in the slide also fixes it.

 

BTW, here's a little hint about force3D. You can set it once, and GSAP will remember that setting so you don't have to add it to every animation.

TweenMax.set(element, { force3D: true });

 

  • Like 3
Link to comment
Share on other sites

5 minutes ago, OSUblake said:

I know you said you were hesitant about using will-change, but I think a lot of the initial problems have been ironed out over time. I don't remove will-change from an element unless I notice a problem. In Firefox's dev console, it will give you a warning if you're using will-change too much.

Thanks,I really do appreciate all your suggestions. I will fool around with will-change and see what happens.

  • Like 1
Link to comment
Share on other sites

I'm happy to say that implementing will-change seemed to do the trick. I added code that looks at the animation data for the content slide, and if there are transforms or opacity changes, then it sets the will-change for that element accordingly. Since most of the elements in our courses are at least faded in, this means that most elements will wind up having some sort of will-change set. Hopefully that won't be an issue. But I set up a stress test where I animated a large number of images and text with scaling and opacity changes and I didn't see any lag.

 

So we are now back with the latest version of TweenMax. Thanks to everyone for all the help!

  • Like 3
Link to comment
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.
×
×
  • Create New...