Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 animations breaking fixed positioning when page scrolled

I'm having trouble trying to figure out why chrome (which makes the fixed header completely disappear, Firefox keeps it there but lets absolutely positioned elements flow over the fixed element, I've averted the problem using opacity:.99, but I still wracks my mind how that does anything to fix it.

http://www.rickpascua.cu.cc/newsite-snazzy/index.html <--- problem page.

like image 463
user1538291 Avatar asked Jul 19 '12 14:07

user1538291


4 Answers

Set following CSS to the disappear element

-webkit-transform: translate3d(0, 0, 0);
transform        : translate3d(0, 0, 0);

The transform attribute translated3d doesn't exist. translate3d does, and should resolve fixed positioning with animated elements on the same page.

like image 175
Ryan Wu Avatar answered Nov 16 '22 06:11

Ryan Wu


EDIT: user @jacob points out that this is a wrong approach that can negatively impact performance. Any property that forces hardware acceleration will do the trick, but instead of applying this rule globally, try applying this rule to the elements that break only.

just encountered a similar issue when combining animate.css with foundation by zurb.

the solution i came up with based on Ryan Wu's answer

* {
backface-visibility: hidden;
}

It worked for my problem (fixed elements losing padding/borders and other nasties during animation)

like image 39
r3wt Avatar answered Nov 16 '22 07:11

r3wt


I still don't actually know why the CSS animation is breaking the layout. In my testing, with the animations running, having overflow:hidden;z-index on the header was causing it to lose fixed positioning! However, I do have an answer.

To begin with, remove

overflow:hidden;
visibility:visible;
z-index:99;

from the fixed position header element <div id="header">.

However with those 3 properties removed, the <div id="slide-contain"/> will still overlap! This is because of the implicit stacking context layering, see the 7 layers in the CSS_absolute_and_fixed_positioning#The_third_dimension article.

The unwanted overlap occurs because position:relative has been set on the <div id="slide-contain"/> (which is a descendent of the <div id="wrapper"/>) but there is no z-index on that element. I realise that the relative positioning was added because you want to absolutely position some child elements inside.

Therefore the <div id="slide-contain"/> element is on the same Z-plane as every other element without a z-index on the page, which includes the fixed header. Both elements are at Level 6 - Positioned descendants with the stack level set as auto or (zero), according to the linked article and stacking defaults to the order in which the elements appear on the DOM, so the <div id="slide-contain"/> is rendered over `.

So a z-index:1 is required on the header to always render the header on top. It just needs to be greater than 0, so change z-index:99 to z-index:1

An alternate solution would be to supply a negative z-index (and position:relative) on the following sibling <div id="wrapper"/>.

You might think that adding a negative z-index on the <div id="slide-contain"/> would be enough but it would need duplicating to the element ancestors, otherwise the <div id="slide-contain"/> would be pushed behind its parent.

like image 37
andyb Avatar answered Nov 16 '22 07:11

andyb


I believe this bug happens because the container's animation is offloaded to the GPU; however, the fixed-positioning takes the descendant out of the flow, so it is not offloaded along with the container. And then the fixed-position element is incorrectly composited. Adding any hardware-accelerated property (ex translate3d) to the fixed-positioned element appears to "fix" the problem (I believe because it is then also offloaded to the GPU, avoiding the issue during compositing).

Ex

<div class="container">
  <div class="fixed"></div>
</div>

.container {
  animation-duration: 0.8s;
  animation-name: some-animation;
}

.fixed {
  /* transform: translateX(-200%); */
  transform: translate3d(-200%, 0, 0);
  position: fixed;
  top: 10rem;
}
like image 1
Jakob Jingleheimer Avatar answered Nov 16 '22 07:11

Jakob Jingleheimer