Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override CSS Z-Index Stacking Context

Tags:

css

z-index

I'm trying to override / ignore the stacking context for an element so it can be positioned on the z-axis relative to the page root.

However, according to the article What No One Told You About Z-Index:

If an element is contained in a stacking context at the bottom of the stacking order, there is no way to get it to appear in front of another element in a different stacking context that is higher in the stacking order, even with a z-index of a billion!

New stacking contexts can be formed on an element in one of three ways:

  • When an element is the root element of a document (the element)
  • When an element has a position value other than static and a z-index value other than auto
  • When an element has an opacity value less than 1

With the following example:

.red, .green, .blue { position: absolute; } .red   { background: red; } .green { background: green; } .blue  { background: blue; }
<div><span class="red">Red</span></div> <div><span class="green">Green</span></div> <div><span class="blue">Blue</span></div>

If the first div is given opacity:.99;, (which creates a new stacking context on the first node) then even if .red has z-index:1, it will still be placed behind the other elements because it is just rendered as the highest element within that stack.

Working Demo in jsFiddle

Which looks like this:

demo

Q: Is there a way for an element to ignore the stack context of any of it's parent elements and ask to be positioned relative to the original stack context of the page?

like image 317
KyleMit Avatar asked Nov 08 '13 01:11

KyleMit


People also ask

How do you override stacking context?

Overriding the Default Stacking Order If other elements have z-index values assigned to them, then a value higher than the highest z-index value in the same stacking context will place the element at the top of the stack. A negative value will position an element below the default rendering layer.

How do I change stacking order in CSS?

We can change the stacking order by adding the position property. Any positioned elements (and their children) are displayed in front of any non-positioned elements. Positioned elements have a position value relative, absolute, sticky or fixed. Non-positioned elements are the ones with default position (static).

How do I fix Z-index in CSS?

In Summary To sum up, most issues with z-index can be solved by following these two guidelines: Check that the elements have their position set and z-index numbers in the correct order. Make sure that you don't have parent elements limiting the z-index level of their children.

How do you use Z-index without absolute positioning?

Yes: use position:relative; z-index:10 . z-index has no effect for position:static (the default).


2 Answers

Q: Is there a way for an element to ignore the stack context of any of it's parent elements and ask to be positioned relative to the original stack context of the page?

No, it's not possible to transfer a positioned element between stacking contexts without repositioning the element in the DOM. You cannot even move an element to the root stacking context by using position: fixed or position: absolute (as you have observed, .red is being positioned relative to its parent, div:first-child because it creates a new stacking context).

That being said, given your HTML and CSS it should be trivial to just reassign the classes to the div elements instead, as shown in other answers and here so all your divs and spans participate in the root stacking context:

<div class="red"><span>Red</span></div> <div class="green"><span>Green</span></div> <div class="blue"><span>Blue</span></div> 

But your situation probably isn't as simple as it seems.

like image 136
BoltClock Avatar answered Sep 23 '22 03:09

BoltClock


We can do it using 3D transformation and we will be able to bring any element to the front even if it's trapped inside a stacking context:

.red, .green, .blue {   position: absolute;   width: 100px;   color: white;   line-height: 100px;   text-align: center; }  body, div:first-child {   transform-style: preserve-3d; /* this is important for the trick to work */ } .red {   top: 20px;   left: 20px;   background: red;   /*z-index: 1; we no more need this */   transform:translateZ(1px); /* this will do the trick  */ }  .green {   top: 60px;   left: 60px;   background: green; }  .blue {   top: 100px;   left: 100px;   background: blue; }
<div><span class="red">Red</span></div> <div><span class="green">Green</span></div> <div><span class="blue">Blue</span></div>

More details and examples here: Why can't an element with a z-index value cover its child?

like image 26
Temani Afif Avatar answered Sep 24 '22 03:09

Temani Afif