Issue
Seems like I just found a bug or something. Usually when an element has a pseudo-element and I want it to show behind its parent I use z-index:-1. This works fine if the element has position relative or absolute but on position fixed something weird happens: the pseudo-element comes between the background and the text of the element like this:
div {width:200px;height:100px;position:fixed;background:black;display:block;}
div::after {content:"";position:absolute;top:0;width:100%;height:100%;background:red;z-index:-1;display:block;}
<div>
example
</div>
Can this be fixed so the pseudo-element goes completely behind the parent as it does with the other positions?
Thank you.
Solution
The behavior your are experiencing is due to stacking contexts in CSS:
A stacking context is formed, anywhere in the document, by any element in the following scenarios:
- […]
- Element with a
position
valueabsolute
orrelative
andz-index
value other thanauto
.- Element with a
position
valuefixed
[…]
So when you use position: fixed
on the parent, it becomes a new stacking context, whereas when you use position: absolute
or position: relative
without a z-index
, it is not a new stacking context, which is why you see this discrepancy in behavior.
When the parent element is a stacking context it becomes a "container" for position stacking. The text or other elements inside it are by default at the stacking position 0
but the pseudo element in your example has z-index
of -1
so it goes behind the text. It does not go behind the parent because the parent itself is the container. It is like you have all these elements in a box and elements can't go outside the box.
So to have the pseudo element be behind its stacking context parent, we can use a 3D transform
to translate the pseudo element behind the plane of the parent. We add transform-style: preserve-3d
so "that the children of the element should be positioned in the 3D-space" and then we can add transform: translateZ(-1px)
to push the child element behind:
div {
width:200px;
height:100px;
position:fixed;
background:black;
display:block;
transform-style: preserve-3d;
}
div::after {
content:"";
position:absolute;
top:0;
width:100%;
height:100%;
background:red;
z-index: -1;
display:block;
transform: translateZ(-1px);
}
<div>
example
</div>
Answered By - Wongjn
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.