z-index not working with fixed positioning
This question can be solved in a number of ways, but really, knowing the stacking rules allows you to find the best answer that works for you.
Solutions
The <html>
element is your only stacking context, so just follow the stacking rules inside a stacking context and you will see that elements are stacked in this order
- The stacking context’s root element (the
<html>
element in this case)- Positioned elements (and their children) with negative z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
- Non-positioned elements (ordered by appearance in the HTML)
- Positioned elements (and their children) with a z-index value of auto (ordered by appearance in the HTML)
- Positioned elements (and their children) with positive z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
So you can
- set a z-index of -1, for
#under
positioned -ve z-index appear behind non-positioned#over
element - set the position of
#over
torelative
so that rule 5 applies to it
The Real Problem
Developers should know the following before trying to change the stacking order of elements.
- When a stacking context is formed
- By default, the
<html>
element is the root element and is the first stacking context
- By default, the
- Stacking order within a stacking context
The Stacking order and stacking context rules below are from this link
When a stacking context is formed
- When an element is the root element of a document (the
<html>
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
- Several newer CSS properties also create stacking contexts. These include: transforms, filters, css-regions, paged media, and possibly others. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
- As a general rule, it seems that if a CSS property requires rendering in an offscreen context, it must create a new stacking context.
Stacking Order within a Stacking Context
The order of elements:
- The stacking context’s root element (the
<html>
element is the only stacking context by default, but any element can be a root element for a stacking context, see rules above)- You cannot put a child element behind a root stacking context element
- Positioned elements (and their children) with negative z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
- Non-positioned elements (ordered by appearance in the HTML)
- Positioned elements (and their children) with a z-index value of auto (ordered by appearance in the HTML)
- Positioned elements (and their children) with positive z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
z-index is not working with position fixed
Why the position fixed is blocking to the layer (z-index) ?
This is because of The stacking context. CSS positioning and adding a z-index
value to an element creates a new stacking context.
From MDN page:
Note: The hierarchy of stacking contexts is a subset of the hierarchy of HTML elements.
Hence in your particular case:
<div id="one">
<div id="overlay"></div>
</div>
<div id="two">
<a href="#" id="link">test</a>
</div>
The hierarchy of stacking contexts would be:
- Root
#one
#two
#link
And #link
would be placed under the #one
no matter how much its z-index
value is.
One option is increasing the z-index
value of #two
element (more than #one
).
z-index not working for fixed element
Unless you're dealing with flex items or grid items, an element must be positioned for z-index
to work.1
In other words, the position
property must have a value other than static
or z-index
will be ignored.2
Your second div is not positioned. Here are two options:
- add
position: relative
to#normal
, or - give the positioned div a negative
z-index
value
#fixed { background-color: red; width: 500px; height: 500px; position: fixed; z-index: 0; /* a negative value here will also work */}#normal { background-color: lightblue; width: 500px; height: 500px; z-index: 1; position: relative; /* new */}
<div id = 'fixed'> I'm Fixed </div><div id = 'normal'> I'm Normal </div>
Z-index not working on div on fixed position header
You have to use position: fixed
also on the instruction box, with according position settings. (relative
will put it into the document flow, thereby taking up space, and absolute
won't work since you don't have a relative parent for it.)
header { width: 100%; display: inline-block; background-color: #ef4023; position: fixed; z-index: 10;}
header #Guide { width: 100%; z-index: 15; margin-right: -1px; position: fixed; top: 110px; left: 0px; background: #eee; border: 1px solid #ccc;}
<header> <div class="col-lg-4 col-md-4 col-sm-2 col-xs-4"> <div class="logo"> <img src="images/logo.png" alt="logo" class="img-responsive" /> </div> </div> <div class="col-lg-8 col-md-8 col-sm-10 col-xs-8"> <div class="col-md-6"> <!--SearchBarStart--> <div ng-controller="MyCtrl">
<form> <h3>Search Here </h3>
<input type="text" class="form-control" id="SearchKeyword" ng-model="searchText" required="required" />
<div class="list-group" id="Guide" ng-show="showLinks">
<a class="list-group-item" href="" ng-click="SearchType(0,true,'KeyWord', 1)"> <div class="input-group"> <span class="fa fa-suitcase"></span><span style="padding-left: 20px">instruction goes here</span> </div> </a> </div>
</form> </div> </div> </div></header>`
z-index not working with position absolute
The second div is position: static
(the default) so the z-index does not apply to it.
You need to position (set the position property to anything other than static
, you probably want relative
in this case) anything you want to give a z-index
to.
z-index not working with elements whose parents are in fixed position
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/
Z-Index is not working
You need to make the .inner
div position relative
.inner {
z-index: 9999;
position: relative;
}
z-index only works on positioned elements (position:absolute, position:relative, or position:fixed).
https://www.w3schools.com/cssref/pr_pos_z-index.asp
z-index not working inside position fixed element
I do not think you need the z-index. How about this?
.wrap {
position: fixed;
width: 80%;
height: 200px;
background-color: #a157df;
}
.content {
position: relative;
width: 30%;
height: 100px;
background-color: #a1a7af;
left: 70%;
}
This is how the z-index works if you need it. http://www.w3schools.com/cssref/pr_pos_z-index.asp
Related Topics
How to Combine :Nth-Child() or :Nth-Of-Type() With an Arbitrary Selector
Bootstrap Align Navbar Items to the Right
Why Aren't My Grid-Template-Areas With Ascii Art Not Working
When to Use Margin VS Padding in Css
Opacity of Background-Color, But Not the Text
Css Triangle Custom Border Color
Use of Xsl-Fo, Css3 Instead of Css2 to Create Paginated Documents Like Pdf
What's the Difference Between Display:Inline-Flex and Display:Flex
:First-Child Not Working as Expected
Align Inline-Block Divs to Top of Container Element
How to Disable Margin-Collapsing
Stretch and Scale a CSS Image in the Background - With CSS Only
Is There a CSS Hack to Affect Safari Only Not Chrome
How to Set Background Image and Opacity in the Same Property
Css :After Not Adding Content to Certain Elements