Reputation: 3771
So if I understand z-index
correctly, it would be perfect in this situation:
I want to place the bottom image (the tag/card) below the div above it. So you can't see the sharp edges. How do I do this?
z-index:-1 // on the image tag/card
or
z-index:100 // on the div above
doesn't work either. Neither does a combination of anything like this. How come?
Upvotes: 335
Views: 574836
Reputation: 2783
For z-index
to work as expected, ensure the following:
position: relative
, absolute
, fixed
, etc.overflow: hidden
, as this can clip the element and prevent proper layering.Upvotes: 20
Reputation: 11
Moving up the DOM tree and checking the z-index of the parent can also help in cases where a child of that parent is not responding to the z-index prop
https://www.joshwcomeau.com/css/stacking-contexts/
Upvotes: 0
Reputation: 8589
I had a select element inside a "card"
My card had this class applied:
.card {
border: 1px solid var(--gray-200);
filter: drop-shadow(0 1px 1px rgb(0 0 0/0.05));
box-shadow: rgba(0, 0, 0, 0.15) 0px 4px 5px;
border-radius: 0.375rem;
}
I removed the filter property and that fixed it.
Upvotes: 2
Reputation: 907
Just in case if you have set legit z-index
and position
(absolute
, relative
, fixed
, sticky
), and it still doesn't work as expected, the problem might be with transform
or opacity
rules on one of the element's parents, that could make them behave as if they had zero z-index
. A solution is to set z-index
explicitly on the parent block with such rules (along with position
).
Here's the specs for the reference:
https://www.w3.org/TR/css-transforms-1/#transform-rendering
3. The Transform Rendering Model
For elements whose layout is governed by the CSS box model, any value other than none for the transform property results in the creation of a stacking context. Implementations must paint the layer it creates, within its parent stacking context, at the same stacking order that would be used if it were a positioned element with z-index: 0. If an element with a transform is positioned, the z-index property applies as described in [CSS2], except that auto is treated as 0 since a new stacking context is always created.
https://www.w3.org/TR/css-color-3/#transparency
3.2. Transparency: the ‘opacity’ property
Since an element with opacity less than 1 is composited from a single offscreen image, content outside of it cannot be layered in z-order between pieces of content inside of it. For the same reason, implementations must create a new stacking context for any element with opacity less than 1. If an element with opacity less than 1 is not positioned, then it is painted on the same layer, within its parent stacking context, as positioned elements with stack level 0. If an element with opacity less than 1 is positioned, the '
z-index
' property applies as described in [CSS21], except that if the used value is 'auto
' then the element behaves exactly as if it were '0
'. See section 9.9 and Appendix E of [CSS21] for more information on stacking contexts. The rules in this paragraph do not apply to SVG elements, since SVG has its own rendering model ([SVG11], Chapter 3).
Upvotes: 0
Reputation: 8541
The z-index
property only works on elements with a position
value other than static
(e.g. position: absolute;
, position: relative;
, position: fixed
or position: sticky
).
Note that position: sticky;
is prefixed in Safari 7.1-12 and not available on many browsers before 2016.
Upvotes: 694
Reputation: 10892
In addition to transform interfering with z-index working, I'd also like to add that using the 'perspective' property can also stop z-index from working correctly.
Upvotes: 0
Reputation: 41
I had the same problem with z-index
and fixed it by setting the background color like this:
background-color: white;
Upvotes: 4
Reputation: 127
I got my answer from codercoder.com: In my code I have set my Navbar's opacity to 0.9.
Once you remove the opacity
property from the Navbar's CSS, the z-index
works as expected.
Upvotes: 0
Reputation: 1179
If all else fails, look for syntax errors in your HTML. It's not intuitive, but I've seen it be the reason why z-index
doesn't work.
The following code has invalid HTML syntax:
<div class="over"/>
<div class="under"/>
...(it's is invalid syntax because a div isn't a self closing tag).
CSS properties that were applied to these rogue HTML elements, such as background-color: black
, position: fixed
, width: 150px
, and top:150px
, were all working as expected. However, the z-index: 2
property wasn't working under the exact same conditions.
Only when the invalid HTML was fixed did the z-index
work correctly.
I'm not sure why z-index
was pickier than the other CSS attributes, but maybe this answer can help someone.
Upvotes: 0
Reputation: 1501
Make sure that this element you would like to control with z-index does not have a parent with z-index property, because element is in a lower stacking context due to its parent’s z-index level.
Here's an example:
<section class="content">
<div class="modal"></div>
</section>
<div class="side-tab"></div>
// CSS //
.content {
position: relative;
z-index: 1;
}
.modal {
position: fixed;
z-index: 100;
}
.side-tab {
position: fixed;
z-index: 5;
}
In the example above, the modal has a higher z-index than the content, although the content will appear on top of the modal because "content" is the parent with a z-index property.
Here's an article that explains 4 reasons why z-index might not work: https://coder-coder.com/z-index-isnt-working/
Upvotes: 16
Reputation: 3366
Your elements need to have a position
attribute. (e.g. absolute
, relative
, fixed
) or z-index
won't work.
Upvotes: 47
Reputation: 12236
If you set position to other value than static
but your element's z-index
still doesn't seem to work, it may be that some parent element has z-index
set.
The stacking contexts have hierarchy, and each stacking context is considered in the stacking order of the parent's stacking context.
So with following html
div { border: 2px solid #000; width: 100px; height: 30px; margin: 10px; position: relative; background-color: #FFF; }
#el3 { background-color: #F0F; width: 100px; height: 60px; top: -50px; }
<div id="el1" style="z-index: 5"></div>
<div id="el2" style="z-index: 3">
<div id="el3" style="z-index: 8"></div>
</div>
no matter how big the z-index
of el3
will be set, it will always be under el1
because it's parent has lower stacking context. You can imagine stacking order as levels where stacking order of el3
is actually 3.8 which is lower than 5.
If you want to check stacking contexts of parent elements, you can use this:
var el = document.getElementById("#yourElement"); // or use $0 in chrome;
do {
var styles = window.getComputedStyle(el);
console.log(styles.zIndex, el);
} while(el.parentElement && (el = el.parentElement));
There is a great article about stacking contexts on MDN
Upvotes: 167
Reputation: 371739
In many cases an element must be positioned for z-index
to work.
Indeed, applying position: relative
to the elements in the question would likely solve the problem (but there's not enough code provided to know for sure).
Actually, position: fixed
, position: absolute
and position: sticky
will also enable z-index
, but those values also change the layout. With position: relative
the layout isn't disturbed.
Essentially, as long as the element isn't position: static
(the default setting) it is considered positioned and z-index
will work.
Many answers to "Why isn't z-index working?" questions assert that z-index
only works on positioned elements. As of CSS3, this is no longer true.
Elements that are flex items or grid items can use z-index
even when position
is static
.
From the specs:
Flex items paint exactly the same as inline blocks, except that order-modified document order is used in place of raw document order, and
z-index
values other thanauto
create a stacking context even ifposition
isstatic
.5.4. Z-axis Ordering: the
z-index
propertyThe painting order of grid items is exactly the same as inline blocks, except that order-modified document order is used in place of raw document order, and
z-index
values other thanauto
create a stacking context even ifposition
isstatic
.
Here's a demonstration of z-index
working on non-positioned flex items: https://jsfiddle.net/m0wddwxs/
Upvotes: 32