This question already has answers here:
Z-index with before pseudo-element
(2 answers)
Is it possible to set the stacking order of pseudo-elements below their parent element? [duplicate]
(9 answers)
Why can't an element with a z-index value cover its child?
(5 answers)
Closed 3 years ago.
I have a box I want to show, and I want a background to appear behind the box to cover what remains on the screen. The Box and the Background are bot position fixed, and the z-index for each is set as you might expect, but the background always covers the box ?
.box {
position: fixed;
width: 100px;
height: 100px;
top: 100px;
left: 100px;
background-color: yellow;
border: 10px solid green;
z-index: 1;
}
.box:before {
content: '';
position: fixed;
width: 300px;
height: 300px;
top: 150px;
left: 150px;
background-color: tomato;
z-index: -1;
}
<div class="box"></div>
You are using position:fixed, and then placing your :before at 150px from the top and 150px from the left, so it is normal that it is 'after' your .box that is 100px wide and 100px tall and positioned 100px from the left and 100px from the top, also in position fixed.
If you use position:absolute on your :after instead, it will be positioned relative to it's parent div. For example:
.box {
position: fixed;
width: 100px;
height: 100px;
top: 100px;
left: 100px;
background-color: yellow;
border: 10px solid green;
z-index: 1;
}
.box:before {
content: '';
position: absolute;
width: 100px;
height: 100px;
top: 0px;
left: -110px;
background-color: tomato;
z-index: -1;
}
<div class="box"></div>
Edit: After getting the comment from Amaury Hanser, I'm adding a second snippet (since I don't know if it was the original poster that upvoted).
To place the :before "below" the .box, in terms of z-index, you could make use of the :before in conjunction with :after:
.box:before {
content: '';
position: fixed;
width: 100px;
height: 100px;
top: 100px;
left: 100px;
background-color: yellow;
border: 10px solid green;
z-index: 1;
}
.box:after {
content: '';
position: absolute;
width: 300px;
height: 300px;
top: 150px;
left: 150px;
background-color: tomato;
z-index: 0;
}
<div class="box"></div>
In simple terms, think of pseudo-elements much like child/parent elements. A child element cannot have a z-index lower than the parent element unless the parent element has no z-index assigned. Also, some position CSS rules give a "default" z-index, and no child can "break out" of it to go behind.
Related
My goal is to have a div with any background, which then uses a pseudo element to create a transparent white overlay, thus "lightening" the background of the div. The "overlay" must be UNDER the contents of the div, though. So, in the following example:
<div class="container">
<div class="content">
<h1>Hello, World</h1>
</div>
</div>
.container {
background-color: red;
width: 500px;
height: 500px;
position: relative;
}
.content {
background-color: blue;
width: 250px;
}
.container::before {
content:"";
display: block;
height: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 1;
background-color: rgba(255, 255, 255, .8);
}
The .content div should not be "underneath" the white overlay, aka .container::before.
I would prefer not having to use z-index on .content, but I can if that is the only solution.
End goal: The red should be covered while the text and blue are not.
JS fiddle: http://jsfiddle.net/1c5j9n4x/
If the pseudo element has a z-index, then you would need to position the .content element and add a z-index value to establish a stacking context.
Updated Example
.content {
background-color: blue;
width: 250px;
position: relative;
z-index: 1;
}
..you could also remove the z-index from the pseudo element and then merely position the .content element. In doing so, none of the elements need a z-index. The reason this works is because the :before pseudo element is essentially a previous sibling element. Thus, the succeeding .content element is positioned on top.
Alternative Example
.content {
background-color: blue;
width: 250px;
position: relative;
}
.container::before {
content:"";
display: block;
height: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: rgba(255, 255, 255, .8);
}
I have some html elements: basically a container div and a child div. So when I give child div the CSS property left: 100%, it goes out of the parent div. The property right: 0 or CALC will do the trick but I want get this done only with left: 100%, and no Javascript. So is there any way to get this done?
.parent{
border: 1px solid #000;
height: 500px;
position: relative;
width: 500px;
}
.child{
background: #FF0;
height: 100px;
left: 100%;
position: absolute;
width: 100px;
}
https://jsfiddle.net/evoSL/yd48v14m/4/
This is the right behavior. If you set left:100% in this setup, it will take the width of the parent and pushes the child 100% of that width to the right, which is 500px. You can, as already mentioned, set a negative margin width fixed pixel values, but i wouldn't recommend it. What if you have a fluid width layout? It won't work.
What's wrong with right: 0, it provides exactly what you are looking for.
Otherwise, if you still want to work with left: 100%; you can add transform: translateX(-100%) to the child. this will move the child on the X-axis by it's width.
Well, if you have a fixed with, you can do this with a negative margin on your child:
.parent{
border: 1px solid #000;
height: 500px;
position: relative;
width: 500px;
}
.child{
background: #FF0;
height: 100px;
left: 100%;
position: absolute;
width: 100px;
margin-left: -100px;
}
https://jsfiddle.net/yd48v14m/5/
You can also do this with floats. I don't know what you want to achieve eventually but this is something you could use too:
.parent {
border: 1px solid #000;
height: 500px;
width: 500px;
}
.child {
background: #FF0;
height: 100px;
width: 100px;
float: right;
}
<div class="parent">
<div class="child"></div>
</div>
With left:100%, you make the first border of your child stays just at the end of their container
If your target is to get the yellow box align to the right, here you have options:
.parent{
border: 1px solid #000;
height: 500px;
position: relative;
width: 500px;
}
.child{
background: #FF0;
height: 100px;
left: calc(100% - 100px);
position: absolute;
width: 100px;
}
.child{
background: #FF0;
height: 100px;
right: 0;
position: absolute;
width: 100px;
}
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 ran into this challenge: fiddle. The short story is, I want to have the green block in the middle of the z-order, without having to change the HTML. So yellow on the bottom, green in the middle, and red on top.
.parent {
background-color: yellow;
position: absolute;
top: 0;
left: 0;
height: 200px;
width: 200px;
z-index: 1;
}
.child {
background-color: red;
position: relative;
top: 10px;
left: 20px;
height: 50px;
width: 150px;
z-index: 100;
}
.other-guy {
background-color: green;
position: absolute;
top: 40px;
left: 100px;
height: 200px;
width: 200px;
z-index: 50;
}
<div class="parent">
Chillin in the background
<div class="child">
I really want to be on top.
</div>
</div>
<div class="other-guy"> I want to be in the middle! </div>
The longer story is, in my solution I'm using bootstraps grid system to position the child element so the whole thing is responsive. The middle layer is a Google Maps element that needs to be manipulated by the user. My previous solution had an absolutely positioned child element on the map, which works, but I don't know how to make that responsive.
My new solution works great from a responsive angle, but then I found out that the parent is blocking interaction with the maps.
So I now need a solution have some responsive elements on top of Google Maps.
I removed the position absolute from the yellow div and removed the z-index from the green div. Maybe this is something as you said.
.parent {
background-color: yellow;
top: 0;
left: 0;
height: 200px;
width: 200px;
z-index: 1;
}
.child {
background-color: red;
position: relative;
top: 10px;
left: 20px;
height: 50px;
width: 150px;
z-index: 2;
}
.other-guy {
background-color: green;
position: absolute;
top: 40px;
left: 100px;
height: 200px;
width: 200px;
}
<div class="parent">Chillin in the background
<div class="child">I really want to be on top.</div>
</div>
<div class="other-guy">I want to be in the middle!</div>
Check out this article:
http://philipwalton.com/articles/what-no-one-told-you-about-z-index/
If this article is right and I understood it correctly, then it's not possible, because yellow and red are part of the same stacking context.
I did accomplish your goal by adding jquery to your fiddle and adding this line of code to actually move the green element into the yellow one:
$(".other-guy").insertAfter(".child");
http://jsfiddle.net/qzLykrba/1/
Red box is the parent div. Blue box is the child div.
Purple box is the parent pseudo:before, that has to be behind the parent red box.
Green box is the child pseudo:before, that has to be behind the child blue box, but above the parent red box.
I can't get the parent pseudo element behind the parent div.
I know that I have to remove the parent z-index to get the parent pseudo element behind the parent, but if I do, then the childs pseudo element goes behind the parent div too.
.parent {
width: 400px;
height: 400px;
background-color: red;
position: relative;
margin-left: 50px;
}
.parent:before {
z-index: -1;
position: absolute;
content: "";
bottom: -50px;
left: -30px;
width: 100px;
height: 100px;
background: purple;
}
.child {
width: 400px;
height: 100px;
background-color: blue;
position: relative;
top: 50px;
}
.child:before {
z-index: -1;
position: absolute;
content: "";
bottom: -50px;
left: -30px;
width: 100px;
height: 100px;
background: green;
}
Unfortunately that is not possible, since the pseudo elements act like children of the element they are assigned to.
<div class="parent"> z: 5
:before z: 4 // still above the parent, since it's a child of it
<div class="child"> z: 3 // below parent:before, above parent
:before z: 2 // above child
"Some text"
:after z: 1 // below child:before, above child
</div>
:after z: 2 // below child, parent:before
</div>
Another note:
Negative values for z-indexes are not overall supported, or don't produce the same behavior.
If I understand you correctly you want this (http://jsfiddle.net/qzLykrba/2/):
.parent {
width: 400px;
height: 400px;
background-color: red;
position: absoulte;
z-index:0;
margin-left: 50px;
}
.parent:before {
z-index: -1000;
position: absolute;
content: "";
bottom: -50px;
left: -30px;
width: 100px;
height: 100px;
background: purple;
}
.child {
width: 400px;
height: 100px;
background-color: blue;
position: relative;
top: 50px;
}
.child:before {
z-index: 2000;
position: absolute;
content: "";
bottom: -50px;
left: -30px;
width: 100px;
height: 100px;
background: green;
}