z-index stack doesn't work right [duplicate] - html

This question already has an answer here:
How can i make an element from a bottom stacking context stays in front of another higher stacking context? [duplicate]
(1 answer)
Closed 4 years ago.
#twitter{
width:50px;
height:50px;
position: absolute;
right: 0%;
bottom: 0%;
background-color: orange;
z-index:-2;
}
#socialButton {
position: relative;
width: 80px;
height: 80px;
background-color: green;
z-index: 2;
}
#socialButtonRoot {
width: 100px;
height: 100px;
top:20%;
left:20%;
position: absolute;
background-color: hotpink;
z-index: 5;
}
<div id="socialButtonRoot">
<div id="socialButton">
<div id="twitter"></div>
</div>
</div>
This is a simplified version.
In my react project there's component created some Dom nodes, after that I set the styles for them in the CSS file, most styles works fine, but only the z-index style doesn't work, people said we should set the position, yes I've all of them set, but it still doesn't work. So I think it maybe something to do with React or JS, but after I extracted code from React and JS and test it on jsfiddle, z-index still doesn't work. Then, I changed changed the z-index value from 2 to "2" (a string ) , it works, but I can see the value "2" is invalid in the chrome's debug console.
It should be div socialButtonRoot on the front which have highest z-index(5) and div socialButton in the middle which have the second high z-index(2) and div twitter in the back, which have the lowest z-index.
but in the result below, it shows, div twitter on the front and div socialButton in the middle and div socialButtonRoot on the back, which isn't right.
What's the problem here?

See The Stacking Context on MDN.
A stacking context is formed, anywhere in the document, by any element in the following scenarios: … Element with a position value "absolute" or "relative" and z-index value other than "auto".
…
Within a stacking context, child elements are stacked according to the same rules previously explained. Importantly, the z-index values of its child stacking contexts only have meaning in this parent. Stacking contexts are treated atomically as a single unit in the parent stacking context.
The z-index positions an element inside the stacking context it is associated with.
Giving an element position: absolute or position: relative establishes a new stacking context.
Thus #twitter is positioned inside the 3-d box represented by #socialButton.
The z-index is for that box, and not for the entire document.
(And #socialButton is inside #socialButtonRoot in the same way).
If you want A to be rendered below B then either:
Do not position A or
Do not make B a descendant of A

When you place an element inside another element, The child element will display on top of its parent element. This is the same for many nested elements and is the default CSS behaviour. Even setting a higher z-index for the parent than its child element won't change the result. In your example:
<div id="socialButtonRoot">
<div id="socialButton">
<div id="twitter"></div>
</div>
</div>
#socialButtonRoot will be displayed at the bottom. #socialButton will display on top of #socialBuuttonRoot. On top of all, #twitter will show. The z-index will be ignored as it only affects elements of the same level.
I suggest you create a parent <div> and place all three <div>s inside:
#parent {
position: relative;
width: 100px;
height: 100px;
margin-top: 20vh;
margin-left: 20vw;
}
#socialButtonRoot {
position: absolute;
width: 100px;
height: 100px;
z-index: 5;
background-color: hotpink;
}
#socialButton {
position: relative;
width: 80px;
height: 80px;
z-index: 2;
background-color: green;
}
#twitter {
position: absolute;
width: 50px;
height: 50px;
right: 20%;
bottom: 20%;
background-color: orange;
z-index: -2;
}
<div id="parent">
<div id="socialButtonRoot"></div>
<div id="socialButton"></div>
<div id="twitter"></div>
</div>
I used position:relative for the parent <div> so that I can position the children <div>s using percentages. I also used margin-top and margin-left instead of top and left respectively, since the latter don't work with relatively positioned elements.
Since #socialButtonRoot is the largest <div> and is placed in front of the other two, it is the only one that appears when you run the snippet. You can change the z-index for each <div> as you wish

Related

Display child elements constrained to parent element

Say I have a button positioned inside a div:
.parentDiv {
width: 100px;
height: 50px;
background-color: #B9DEED;
}
.childButton {
position: absolute;
left: 90px;
opacity: .5;
}
<div class="parentDiv">
<button class="childButton">Childbutton</button>
</div>
This gets rendered like so:
Is there a way to display the button so that it is constrained to the div, i.e. it gets cut off after the "C"?
That's not a button positioned inside a div, that's a button (that happens to be child of a div) positioned within the page. For the button to positioned within the div, the div needs to be positioned itself.
Once the parent has position, the overflow: hidden will start to work.
div {
outline: 1px solid blue;
width: 100px;
height: 50px;
position: relative;
overflow: hidden;
}
button {
position: absolute;
left: 90px;
}
<h3>Sample</h3>
<div>
<button>Childbutton</button>
</div>
Core take-away: position is always related to the closest ancestor (it does not have to be the direct parent) that has position. If there is none, it is related to the page. Setting position: relative on a parent establishes a frame of reference without taking the parent out of the document flow.
You can see the difference if you set top: 10px on the button. Try with and without position: relative on the div to verify the frame of reference.
You can use the style overflow: hidden to hide everything outside the parent-element.
This does, however, not apply to position: absolute elements. You would need to use position. relative for that.

How can I overlap divs inside of a parent div when parent uses auto height?

I have two divs that I would like to place one on top of the other, so I can create a tab system in an applet I am making. These two divs reside within a parent div, that uses auto height because I do not know the exact height of the other two divs (both children will be of same height). I can position the two divs one on top of the other with absolute positioning when the parent uses relative positioning, but the auto height doesn't respond (most likely because of absolute positioned children) creating a border line of an empty div instead of a wrapper with elements inside.
See problem here: http://jsfiddle.net/h5bjt69s/
<div id = "parent">
<div id = "redDiv"></div>
<div class = "clearfix"></div>
<div id = "blueDiv"></div>
</div>
I tried modeling a solution from this, but I believe the auto height throws things off.
Position absolute but relative to parent
How can I wrap the two divs with the parent div and still maintain the overlaying of the two children?
This:
both children will be of same height
Actually solves your problem:
Position one div using position: static; it will determine the height of the parent
Position the other div(s) using position: absolute (it will appear on top)
Updated Fiddle
Here are the changes
#blueDiv {
background-color: blue;
width: 100%;
height: 50px;
position: relative;/*changed*/
top: 0px;
left: 0px;
z-index:2;/*added*/
opacity:0.7;
}
DEMO
Another Style
#blueDiv {
background-color: blue;
width: 100%;
height: 50px;
/*position: relative;removed*/
opacity:0.7;
}
#redDiv {
background-color: red;
width: 100%;
height: 50px;
visibility: visible;
position: absolute;
top: 0px;
left: 0px;
z-index: 0;/*added*/
}
Updated

Detect height on position:relative div with position:absolute children

I've got a div that contains a photo tiling style I've been working on. The parent div over all the photos is position:relative while the divs inside holding the photos are position:absolute
I have to use 'position:absolute` for the children to get the layout I want but the problem arises when the parent div (either .daddy or .floatcont) doesn't register with a height and appears empty.
How can I make the parent register a height so I can put content below it on the page?
Code here: http://codepen.io/jeremypbeasley/pen/iBgsp
.floatcont {
position: relative;
background: pink;
width: 90%;
margin: 5%;
}
.floatpic {
position: absolute;
width: 40%;
margin-bottom: 10vh;
}
Absolute positioned elements are removed from the flow, thus ignored by other elements. So you can't set the parents height according to an absolutely positioned element.
In your case, I have come up with one solution. Update your .sixth class like below.
.floatpic.sixth {
top: 270vh;
width: 50%;
z-index: 6;
position:relative;
}
Updated CodePen

Why div default value for position is static but not relative? [duplicate]

This question already has answers here:
Is there anything wrong with positioning all elements relatively?
(5 answers)
Difference between static and relative positioning
(7 answers)
Closed 8 years ago.
Just like the title, why div (or p or any other elements in html) have 'position: static' as the default value? Why not 'position: relative'?
I don't see any benefit using 'position: static' in my css.
Is it safe to define all div elements in html using 'position: relative'?
EDIT:
I'm quite aware the difference between static, relative, absolute, and fixed positioning. But the main problem is why the default positioning for div or any other html elements is static? This example:
HTML
<div class="div1">
<div class="div2">
<div class="div3">
<div class="div-last"></div>
</div>
</div>
</div>
CSS
.div1 {
width: 700px;
height: 700px;
background-color: #000;
position: relative;
}
.div2 {
width: 600px;
height: 600px;
background-color: #333;
position: relative;
top: 20px;
left: 20px;
}
.div3 {
width: 500px;
height: 500px;
background-color: #777;
position: absolute;
right: 0;
top: 30px;
}
.div-last {
width: 400px;
height: 400px;
background-color: #AAA;
position: absolute;
bottom: 20px;
left: 20px;
}
shows that I don't need a single static positioning to arrange my divs as I want.
Here's a jsfiddle of the code above.
And sorry for my potato English. :D
EDIT #2:
The answer from the related question is:
"Yes, it is. If you try to position one element absolute it is positioned relatively to the closest ancestor, which has a CSS position other than static.
If every element has position:relative, this would be the direct parent.
But you might want to position the absolute element relatively to an element further up in the DOM tree or maybe absolutely on the page body."
So, I don't want/need to "position the absolute element relatively to an element further up in the DOM tree or maybe absolutely on the page body.", is there any other technical precautions that I need to know before I make all divs relative?
If position: relative was the default value, position: absolute; would no longer work as expected. That is, because position: absolute uses the closest non-static positioned element in the hierarchy as the reference. If there were no static positioned elements, all would be non-static, so position: absolute would use the parent element as the reference, and thus no longer positioning absolute, but relative to the parent element.

Z-index below text but above background

I'm trying to get a div to show as a partial background below the inline content of is containing div but above the background of its container. If I set the z-index of just the partial background to -1 it appears behind the background. But if i set the containing divs z-index to 1 while the contained div's z-index is -1 it displays as desired.
Can someone explain to me why this is and if this is a reliable method or not?
.container {
position: relative;
width: 80%;
height: 18px;
padding: 6px 10px;
background: #666;
z-index: 1;
}
.partialbg {
position: absolute;
left: 0px;
top: 0px;
height: 30px;
width: 80%;
background: #0CC;
z-index: -1;
}
<div class="container">Text here
<div class="partialbg"></div>
</div>
The reason this is occurring, is because there is a child and a parent. If you set a z-index on the parent, the child is going to be the same, since the z-index is stacked.
Thus, by setting a z-index of 1 on the parent, the child is now also 1.
It is systematically impossible for the child to be behind the parent, as that doesn't make any sense. However, the text is a sibling of the child. By setting a z-index of -1 on the child, there is essentially no effect between the child and the parent, however since the sibling is effected, the child now goes behind the sibling.