Set parent over child depth in CSS - html

I need for parent div to be over its children.
I've tried z-index set to -1 and it works for first level, but I need for two or more children depth.
div {
width: 200px;
height: 300px;
overflow: visible;
}
.one {
position: relative;
background: green;
}
.two {
position: absolute;
background: red;
top: 0;
left: 100px;
z-index: -1;
}
.three {
position: absolute;
background: blue;
top: 0;
left: 150px;
z-index: -1;
}
<div class="one">
<div class="two">
<div class="three">
</div>
</div>
</div>
So, class One should be over Two, and Two over Three
thanks

Without any z-index value, elements stack in the order that they appear in the DOM (the lowest one down at the same hierarchy level appears on top). Elements with non-static positioning will always appear on top of elements with default static positioning.
Also note that nesting plays a big role. If an element B sits on top of element A, a child element of element A can never be higher than element B.
Try like this
div {
width: 200px;
height: 300px;
overflow: visible;
}
.one {
position: absolute;
background: green;
z-index:2;
}
.two {
position: absolute;
background: red;
top: 50px;
left: 100px;
z-index: 1;
}
.three {
position: absolute;
background: blue;
top: 100px;
left: 150px;
}
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>

Related

Higher z-index of a child when parent is equal z-index with another div hides the absolute child [duplicate]

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>

Isolation with CSS Mix-Blend-Modes: how to prevent elements from blending with parent

I have tried this a lot of different ways, and cannot make it so that the .pink and .green divs blend with one another, but not the background color of the parent element, .wrapper.
.wrapper {
background-color: blue;
height: 100vh;
width: 100%;
isolation: isolate;
}
.pink {
background: hotpink;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
left: 10%;
mix-blend-mode: multiply;
}
.green {
background: limegreen;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
right: 10%;
mix-blend-mode: multiply;
}
<div class="wrapper">
<div class="pink"></div>
<div class="green"></div>
</div>
Or, see the fiddle: https://jsfiddle.net/grettynebraska/9dr6vspy/5/#&togetherjs=breFHFSfEd
My goal is simply to have a pink and green div that blend with eachother, and live atop a black background, with whom they do not blend.
I tried using absolute position, and sitting the pink/green divs and the wrapper next to one another, as siblings. However, all elements still blended.
I would consdier an extra wrapper where you set a z-index in order to create a staking context thus the element will no more blend with the blue element:
.wrapper {
background-color: blue;
height: 100vh;
width: 100%;
}
.wrapper > div {
position:absolute;
height: 100vh;
left:0;
right:0;
z-index:0;
top:0;
}
.pink {
background: hotpink;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
left: 10%;
mix-blend-mode: multiply;
}
.green {
background: limegreen;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
right: 10%;
mix-blend-mode: multiply;
}
<div class="wrapper">
<div>
<div class="pink"></div>
<div class="green"></div>
</div>
</div>
Everything in CSS that creates a stacking context must be considered an ‘isolated’ group. HTML elements themselves should not create groups.
An element that has blending applied, must blend with all the underlying content of the stacking context [CSS21] that that element belongs to. ref
So the main trick is to have the elements in a stacking context where the blue element doesn't belong. If the wrapper element is their direct parent element it won't be trivial to make them in different stacking context thus the need of an extra wrapper.
Isolation won't help you, because it will simply make the wrapper creating a stacking context, so it won't isolate the wrapper from its child but from all the elements outside. if you apply it to the extra wrapper it will work exactly like setting z-index or any other property that create a stacking context.
.wrapper {
background-color: blue;
height: 100vh;
width: 100%;
}
.wrapper > div {
position:absolute;
height: 100vh;
left:0;
right:0;
isolation:isolate;
top:0;
}
.pink {
background: hotpink;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
left: 10%;
mix-blend-mode: multiply;
}
.green {
background: limegreen;
height: 80%;
width: 50%;
position: absolute;
z-index: 1;
top: 0;
right: 10%;
mix-blend-mode: multiply;
}
<div class="wrapper">
<div>
<div class="pink"></div>
<div class="green"></div>
</div>
</div>

Lower z-indexed parent's child upon higher z-indexed element?

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>

CSS element always on top

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**

Understanding z-index: How does this element appear in front of its parent's sibling?

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>