Gil Epshtain
Gil Epshtain

Reputation: 9801

z-index not working with elements whose parents are in fixed position

I have a web app, with upper and lower elements (div), both of them have position: fixed. Each one of these elements has child elements (popups) which also have position: fixed.

I want to place the popup above to parent elements. However since I'm using position: fixed, the z-index property isn't working, because it's inherited from the parents.

I saw that similar question was asked in Stack-overflow, however none of them provide solution to this issue.

See the html/css at: https://jsfiddle.net/pLsdspon/

<html>
<head></head>
<body style="height: 100%;">

  <div style="
        background-color: red;
    	position: fixed;
    	display: block;
    	width: 100%;
    	height: 50%;
    	top: 0%;			
    	z-index: 2; ">
Top
    <div style="			
    		background-color: pink;
    		position: fixed;
    		display: block;
    		width: 80px;
    		height: 200px;
    		top: 40%;
    		left: 100px;
    		z-index: 20; ">
      PopUp-Top - Need to be on top!
    </div>
  </div>

  <div style="
    	background-color: green;
    	position: fixed;
    	display: block;
    	width: 100%;
    	height: 50%;
    	top: 50%;
    	z-index: 2; ">
Bottom
    <div style="		
    		background-color: lightgreen;
    		position: fixed;
    		display: block;
    		width: 80px;
    		height: 200px;
    		top: 40%;
    		left: 200px;
    		z-index: 20; ">
      PopUp-Bottom - Need to be on top!
    </div>
  </div>
</body>
</html>

Upvotes: 2

Views: 2746

Answers (2)

Gil Epshtain
Gil Epshtain

Reputation: 9801

The simple solution is that what I'm trying to do is simply impassible.

The answer by #Krypton indeed solve this issue by altering the html, however in my situation altering the html order isn't possible.

The order of elements is called the Stacking Order, the stacking order is:
1. If no z-index or position then the stacking order is as the html markup order.
2. All positioned elements (relative, absolute and fixed) appear on top of all none positioned elements (static).
3. z-index works only on positioned elements, and it will create Stacking Context.

Stacking Context
Group of elements with common parent create Stacking Context if one of the next conditions are meet:
1. The root document element (the <html> element).
2. Positioned element with z-index
3. Element with opacity less the 1 (this isn't known by most of web developers)
All the elements in Stacking Context move together in the stacking order, meaning that if element a inside staking context A, can't be above element b inside staking context B, if the stacking order of B is higher the A, even if the element 'a' has z-index of a million.

Update: new css roles that create Stacking context: transform, filter, css-region and pages_media.

The order inside the Stacking Context:
1. root element
2. positioned element with negative z-index.
3. none positioned elements in the order of the html markup
4. positioned elements
5. positioned elements with z-index according to the z-index.

  • Now back to the question, in this example both the red and the green div create stacking context since they are positioned (fixed) and have z-index.
  • Both of them have the same z-index (value of 2), therefor there stacking order is the red below the green since this is the order of the html markup.
  • Now lets look at the pink and the lightgreen elements, the pink is nested inside the red elements and the lightgreen inside the green elements, since the red element has lower staking order than the green, all the nested elements inside the red elements appear below all the elements inside the green elements.

To fix this issue we need to create a new element that will create a new stacking context with higher stacking order than the red and the green div and place our popups inside of that elements.

Reference: What No One Told You About Z-Index by Philip Walton: https://philipwalton.com/articles/what-no-one-told-you-about-z-index/

Upvotes: 2

Krypton
Krypton

Reputation: 114

The z-index isn't working the way you would like because you're nesting a div within a div not because you have the position set to fixed. Why not just place the popup div's outside(ontop) of the others? https://jsfiddle.net/7efx38um/1/

<html>
<head></head>
<body style="height: 100%;">

	<div style="
			background-color: red;
			position: fixed;
			display: block;
			width: 100%;
			height: 50%;
			top: 0%;			
			z-index: 1;
			">
			Top
	</div>
		<div style="			
			background-color: pink;
			position: fixed;
			display: block;
			width: 80px;
			height: 200px;
			top: 40%;
			left: 100px;
			z-index: 20;
			">
			PopUp-Top - Need to be on top!
		</div>
		

	
	<div style="
			background-color: green;
			position: fixed;
			display: block;
			width: 100%;
			height: 50%;
			top: 50%;
			z-index: 1;
			">
			Bottom
				</div>
		<div style="		
			background-color: lightgreen;
			position: fixed;
			display: block;
			width: 80px;
			height: 200px;
			top: 40%;
			left: 200px;
			z-index: 20;
			">
			PopUp-Bottom - Need to be on top!
		</div>

	

</body>
</html>

Also alternatively if you'd like both the banner and popup div's inside one another you could create dummy div's around both, that way the popups won't use the same style as the banners ;)

'

Upvotes: 1

Related Questions