I was working on my code when I stumbled upon this fun fact:
z-index doesn't work for a fixed element and, therefore, fixed elements will always be in front.
Is there a way to place a non-fixed element in front of a fixed element?
Thanks.
#fixed {
background-color: red;
width: 500px;
height: 500px;
position: fixed;
z-index: 0;
}
#normal {
background-color: blue;
width: 500px;
height: 500px;
z-index: 1;
}
<div id = 'fixed'> I'm Fixed </div>
<div id = 'normal'> I'm Normal </div>
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>
See also: Basics of the CSS z-index property
1 Although z-index, as defined in CSS 2.1, applies only to positioned elements, CSS 3 allows z-index to work with grid items and flex items, even when position is static.
2 z-index property page at MDN
Use negative z-index for the fixed element.
<div id = 'fixed'> I'm Fixed </div>
<div id = 'normal'> I'm Normal </div>
#fixed {
background-color: red;
width: 500px;
height: 500px;
position: fixed;
z-index: -1;
}
#normal {
background-color: blue;
width: 500px;
height: 500px;
z-index: 1;
}
#fixed {
background-color: red;
width: 500px;
height: 500px;
position: fixed;
z-index: 0;
}
#normal {
background-color: blue;
width: 500px;
height: 500px;
z-index: 1;
position:relative;
}
<div id = 'fixed'> I'm Fixed </div>
<div id = 'normal'> I'm Normal </div>
#fixed {
background-color: red;
width: 500px;
height: 500px;
position: fixed;
z-index: 0;
}
#normal {
background-color: blue;
width: 500px;
height: 500px;
z-index: 1;
position:relative;
}
<div id = 'fixed'> I'm Fixed </div>
<div id = 'normal'> I'm Normal </div>
Related
This question already has answers here:
Why can't an element with a z-index value cover its child?
(5 answers)
Closed 3 years ago.
I have a constraint: these 2 parent divs cannot be "one is higher than the other", they are both equal in importance.
I have 2 main divs, they're both z-index: 2. Inside the first div, I have a child whose z-index is 99999, now, because both relative and static are treated by the browser in a first-come-last-important fashion, that is to say, div2 has a higher order than div1, my absolute child inside div1 will be behind div2. Watch:
#item1 {
width: 100%;
height: 200px;
background-color: gray;
position: relative;
z-index: 2;
}
#child {
position: absolute;
bottom: -15px;
width: 50px;
height: 50px;
border-radius: 50%;
background: white;
z-index: 15;
}
#item2 {
width: 100%;
height: 200px;
background-color: green;
position: relative;
z-index: 2;
}
<div id="item1">
<div id="child">
</div>
</div>
<div id="item2">
</div>
What am I missing here? The web is supposedly full of divs that are relative and come one after another and they have absolute divs inside of them.
Increase z-index of parent item (#item1) or remove z-index from both parent. It will work.
Actually you don't need to use z-index in parent elements, if you need to use z-index then give first parent higher, Browser give higher priority(z-index) on second element than first because browsers need to show 2nd element over first element.
#item1 {
width: 100%;
height: 200px;
background-color: gray;
position: relative;
}
#child {
position: absolute;
bottom: -15px;
width: 50px;
height: 50px;
border-radius: 50%;
background: white;
z-index: 15;
}
#item2 {
width: 100%;
height: 200px;
background-color: green;
position: relative;
}
<div id="item1">
<div id="child">
</div>
</div>
<div id="item2">
</div>
enter code here
#item1 {
width: 100%;
height: 200px;
background-color: gray;
position: relative;
z-index: 2;
}
#child {
position: absolute;
top: -15px;
width: 50px;
height: 50px;
border-radius: 50%;
background: white;
z-index: 9999;
}
#item2 {
width: 100%;
height: 200px;
background-color: green;
position: relative;
z-index: 2;
}
<div id="item1">
</div>
<div id="item2">
<div id="child">
</div>
</div>
I'm trying to stack two elements to both show on the screen.
Element A and Element B has the same z-index: 2000 and also same top:0 and position:fixed.
When it rendered on the browser, I can only see the element A. The element B is hide behind element A because they has the same css styles.
What I want, is to both render them stack one after another. On the browser I should see element A at the top and element B after element A.
Here's the style
position: 'fixed', top:0, width: '100%', 'z-index': '2000'
Position fixed is relative to the viewport.
You should set element a height and element b top: {element a height}.
.a {
position: fixed;
top:0;
width: 100%;
height: 10px;
z-index: 2000;
background: violet;
}
.b {
position: fixed;
top: 100px;
width: 100%;
height: 10px;
background: purple;
}
<div class="a">
<div class="b">
But actually it sounds that sticky position will be a better fit:
.wrapper {
position: sticky;
top: 0;
}
.c {
width: 100%;
background: blue;
min-height: 10px;
}
.d {
background: yellow;
min-height: 10px;
width: 100%;
}
.e {
height: 10000px;
background: red;
}
<div class="wrapper">
<div class="c"></div>
<div class="d"></div>
</div>
<div class="e"></div>
Is there a way to manipulate the stacking context this way? I want the text to be on the top of the blue element.
div{
width: 200px;
height: 200px;
position: absolute;
}
#a{
z-index: 0;
background-color: red;
left: 150px;
top: 150px;
}
#b{
z-index: 1;
background-color: blue;
left: 0;
top: 0;
}
p{
z-index: 2;
}
<div id="a">
<p>verylongtext</p>
</div>
<div id="b"></div>
Is there any wild card or something like !important which can override the stacking context? The only way to do this is make the text an independent element?
Yes you can, the trick is to keep the red element with z-index:auto so that p will not belong to its stacking context and can be placed above the blue element.
auto
The box does not establish a new local stacking context. The
stack level of the generated box in the current stacking context is
the same as its parent's box.ref
Don't forget to make the p positioned in order to be able to use z-index:
div {
width: 200px;
height: 200px;
position: absolute;
}
#a {
background-color: red;
left: 150px;
top: 150px;
}
#b {
z-index: 1;
background-color: blue;
left: 0;
top: 0;
}
p {
z-index: 2;
position: relative;
}
<div id="a">
<p>verylongtext</p>
</div>
<div id="b"></div>
You can also remove everything and play only with margin:
div {
width: 200px;
height: 200px;
}
#a {
background-color: red;
margin-left: 150px;
margin-top: 150px;
overflow:hidden; /*remove margin-collapsing*/
}
#b {
background-color: blue;
margin-top: -350px;
}
<div id="a">
<p>verylongtext</p>
</div>
<div id="b"></div>
You can refer to this question ( Strange behavior of background when elements are overlapping) to understand how it works.
It is unfortunately impossible to break the stacking context in this way, as a child's z-index is set to the same stacking index as its parent. You will need to make the text a sibling element, and additionally make sure it has a position other than static in order for the z-index to apply.
From here, it's a simple matter of positioning it as desired (in this case with top: 150px and left: 150px.
This can be seen in the following:
div {
width: 200px;
height: 200px;
position: absolute;
}
#a {
z-index: 0;
background-color: red;
left: 150px;
top: 150px;
}
#b {
z-index: 1;
background-color: blue;
left: 0;
top: 0;
}
p {
position: absolute;
z-index: 2;
top: 150px;
left: 150px;
}
<div id="a"></div>
<div id="b"></div>
<p>verylongtext</p>
Is this possible to have element with class .myelement always on top in my HTML structure?
<div class="zindex1">
<div class="myelement">
want THIS element always be on top
</div>
</div>
<div class="zindex2">
</div>
and with for example this CSS
.zindex1 {
z-index: 1;
background-color: blue;
height: 100px;
position: relative;
}
.zindex2 {
z-index: 2;
background-color: green;
height: 300px;
position: relative;
}
.myelement {
background-color: yellow;
height: 500px;
width: 100px;
position: relative;
}
NOTE: I can't change values of my z-indexes and HTML structure.
Here is full example: https://jsfiddle.net/wLzej01f/
EDIT What if all my classes will have to have position: relative? I forget to mention about it
https://jsfiddle.net/wLzej01f/6/
The z-index CSS property won't apply to static elements:
For a positioned box (that is, one with any position other than
static), the z-index property specifies:
The stack level of the box in the current stacking context.
Whether the box establishes a local stacking context.
More about it here.
So, you need to add:
.myelement {
position: relative;
}
Updated JSFiddle.
Position: relative
.zindex1 {
z-index: 1;
background-color: blue;
height: 100px;
}
.zindex2 {
z-index: 2;
background-color: green;
height: 300px;
}
.myelement {
z-index: 3;
background-color: yellow;
height: 500px;
width: 100px;
position: relative;
}
<div class="zindex1">
<div class="myelement">
want THIS element always be on top
</div>
</div>
<div class="zindex2">
</div>
You forgot to add
position: absolute;
or
position: relative;
as you wish.
Just add position:relative to .myelement:
.myelement {
z-index: 3;
background-color: yellow;
height: 500px;
width: 100px;
position: relative;
}
DEMO
In case someone is trying to keep an element in a fixed position on the rest of the elements or does not know why one element is below another, keep in mind the sticky element.
https://www.w3schools.com/howto/howto_css_sticky_element.asp
.zindex1 {
z-index: 1;
background-color: blue;
height: 100px;
position: relative;
}
.zindex2 {
z-index: 0;
background-color: green;
height: 300px;
position: relative;
}
.myelement {
background-color: yellow;
height: 500px;
width: 100px;
position: absolute;
z-index: 2 !important;
}
**This code works**
Why is the red div in front of the green div when I remove z-index from .wrapperRed?
It feels like z-index is inherited up the chain.
If I change the z-index of the green div to 6, it stays in front of the red one even after removing the line described in the first sentence.
.wrapperRed {
height: 200px;
width: 200px;
position: absolute;
z-index: 1; /* Why is the red div in front of the green one, if this z-index is deleted? */
}
.red {
position: absolute;
height: 100%;
width: 100%;
background-color: red;
z-index: 5;
}
.green {
height: 200px;
width: 200px;
background-color: green;
position: absolute;
top: 100px;
left: 100px;
z-index: 1;
}
<div class="wrapperRed">
<div class="red"></div>
</div>
<div class="green"></div>
When you remove z-index from .wrapperRed, the element defaults to z-index: auto.
In this case, both .red and .green participate in the same stacking context because positioned elements do not create a stacking context when z-index is auto (reference).
Learn more about z-index and stacking contexts here: Basics of the CSS z-index property
Why is the .red div in front of the green div when I remove z-index
from .wrapperRed?
Because .red no longer has a parental z-index to constrain it.
ie.
Before: .red has a z-index of 5 within a parental z-index of 1.
After: .red has a global z-index of 5.
N.B. In both Before and After cases, .wrapperRed is always behind .green. But, when it is unconstrained, .red (which is 100% the width and height of .wrapperRed) appears in front of .green.
You can see this more easily if you give the parent and child divs different background colours and make the child div smaller than the parent.
Compare:
.wrapperRed {
height: 200px;
width: 200px;
position: absolute;
background-color: red;
z-index: 1;
}
.yellow {
position: absolute;
height: 75%;
width: 75%;
background-color: yellow;
z-index: 5;
}
.green {
height: 200px;
width: 200px;
background-color: green;
position: absolute;
top: 100px;
left: 100px;
z-index: 1;
}
<div class="wrapperRed">
<div class="yellow">
</div>
</div>
<div class="green"></div>
with:
.wrapperRed {
height: 200px;
width: 200px;
position: absolute;
background-color: red;
}
.yellow {
position: absolute;
height: 75%;
width: 75%;
background-color: yellow;
z-index: 5;
}
.green {
height: 200px;
width: 200px;
background-color: green;
position: absolute;
top: 100px;
left: 100px;
z-index: 1;
}
<div class="wrapperRed">
<div class="yellow">
</div>
</div>
<div class="green"></div>