Z-index behavior differs from chrome to firefox

I have a bunch of CSS that applies to a parent element and its children:

.parent { position: fixed; top: 0px; } .el { position: fixed; top: 5px; z-index: 100; } .bodycontent { z-index: 1; position: relative; } 
 <div class="parent"> <div class="el"> <button></button> </div> </div> <div class="bodycontent"></div> 

The page is made so that when it scrolls, .parent goes under .bodycontent , but .el goes beyond it. This works the way I want in Firefox, but not in Chrome.

Any suggestions? I tried communicating with different z-index values โ€‹โ€‹and different position values โ€‹โ€‹without success.

+6
source share
1 answer

Both Chrome and Firefox work as intended

Starting with version 22 , Chrome specifically intends to handle fixed elements. As stated in the google article itself:

In Chrome 22, the layout position:fixed layout behavior is slightly different from previous versions. All position:fixed elements now form new stacking contexts. This will change the stacking order of some pages, which may disrupt page layouts.

( https://developers.google.com/web/updates/2012/09/Stacking-Changes-Coming-to-position-fixed-elements?hl=en )

Firefox works as it intends. Mozilla docs point out that this behavior is localized to WebKit Mobile and Chrome 22 onwards:

on mobile WebKit and in Chrome 22+, position: fixed always creates a new stacking context, even when the z-index is โ€œautoโ€

( https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context )

Why is this happening

The result of this change means that Chrome will always create a new stacking context, even if the z-index parent container set to auto (default). This is different from position: absolute; and position: relative; in that they create their own stacking context when the z-index not set to auto .

Most of the elements on the page are in the same root context of the stack, but absolutely or relatively positioned elements with non-automatic z-index values โ€‹โ€‹form their own stacking contexts (that is, all their children will be z-ordered within the parent element and will not alternate with content from outside the parent) . Starting with Chrome 22, position:fixed elements will also create their own stacking contexts.

( https://developers.google.com/web/updates/2012/09/Stacking-Changes-Coming-to-position-fixed-elements?hl=en )

The effect of this means that in your example .el z-index calculated relative to its parent, .parent . It displays under .bodycontent because:

  • .bodycontent z-index refers to the root
  • .el z-index refers to .parent
  • .parent z-index refers to the root
  • .parent z-index not specified, so it is set to auto by default (essentially 0 )
  • .parent has a lower z-index than .bodycontent and therefore appears below it. Since .el belongs to him, it is also displayed under .bodycontent .

Expected Results Example

 body { margin: 0; } div { height: 100px; width: 100px; } .parent { background-color: red; position: fixed; top: 0; } .el { background-color: blue; left: 25px; position: fixed; top: 25px; z-index: 100; } .bodycontent { background-color: green; left: 50px; position: relative; top: 50px; z-index: 1; } 
 <div class="parent"> <div class="el"></div> </div> <div class="bodycontent"></div> 

In the above code, the following results will appear in Chrome and Firefox:

Example Result in Chrome and Firefox

What is right?

It seems that Chrome does not follow the W3C specification and that this change was made to make the implementation on the desktop consistent with the implementation of mobile devices:

Mobile browsers (Mobile Safari, Android browser, Qt-based browsers) place positions: fixed elements in their own stack contexts and have some time (starting from iOS5, Android Gingerbread, etc.), because this allows certain optimizations Scrolling, making web pages much more sensitive to touch. Changes are brought to the desktop for three reasons:

1 - Different rendering behavior on mobile and desktop browsers is a stumbling block for web authors; CSS should work wherever possible.

2 - With tablets, it is not clear which of the "mobile" or "desktop" stack context algorithms is more appropriate.

3 - Optimization of scroll performance from mobile to desktop is good for both users and authors.

Firefox handles stacking correctly.

How to get the desired result

The only way to avoid this behavior is to move the .el from .parent and instead make it a brother:

 body { margin: 0; } div { height: 100px; width: 100px; } .parent { background-color: red; position: fixed; top: 0; } .el { background-color: blue; left: 25px; position: fixed; top: 25px; z-index: 100; } .bodycontent { background-color: green; left: 50px; position: relative; top: 50px; z-index: 1; } 
 <div class="parent"></div> <div class="el"></div> <div class="bodycontent"></div> 
+10
source

All Articles