Z-index below text but above background - html

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.

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.

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

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

element with higher z-index value not overlaying another

I have this code
#mtitle {
display: inline-block;
margin: 0;
background-color: #000000;
z-index: 999;
}
#tsub {
display: inline-block;
margin-left: 0;
left: 0;
position: absolute;
font-size: 85px;
z-index: 0;
}
<header>
<h1 id="mtitle">Tepid Beans</h1>
<div id="tsub"><span>- Games</span>
</div>
</header>
#tsub is appearing on top of #mtitle, and I do not know why.
z-index works on positioned elements, but with CSS3 elements which are flex items or grid items can use z-index when elements are static
From MDN
The z-index property specifies the z-order of an element and its
descendants. When elements overlap, z-order determines which one
covers the other. An element with a larger z-index generally covers an
element with a lower one.
For a positioned box, the z-index property specifies:
The stack level of the box in the current stacking context.
Whether the box establishes a local stacking context.
Applies to positioned elements
Set position:relative to parent header and position:absolute to #mtitle and change z-index value
body {
margin: 0
}
header {
position: relative
}
#mtitle {
display: inline-block;
background-color: #000000;
position: absolute;
margin:0;
z-index: 0;
color: #fff
}
#tsub {
display: inline-block;
left: 0;
position: absolute;
font-size: 85px;
z-index: -1;
background: red
}
<header>
<h1 id="mtitle">Tepid Beans</h1>
<div id="tsub">- Games</div>
</header>
Although other answers posted here solve the problem, they are not entirely correct.
The following statements are false:
z-index only works on positioned elements.
z-index only works on elements that are positioned.
z-index only works on elements which are not position:static ie the default position.
In many cases an element must be positioned for z-index to work. But this is not true for all cases.
Elements that are flex items or grid items can create stacking contexts with z-index, even when position is static (see demo).
In terms of this specific question, the reason #tsub is appearing on top of #mtitle is because:
div#tsub comes after h1#mtitle in the HTML, AND
the z-index property applied to #mtitle is being ignored since #mtitle is not positioned, nor is it a flex or grid item.
Here are two possible solutions:
change z-index: 0 on #tsub to z-index: -1, OR
add position: relative to #mtitle
#mtitle {
display: inline-block;
margin: 0;
background-color: aqua; /* changed for illustration purposes */
z-index: 999;
}
#tsub {
display: inline-block;
margin-left: 0;
left: 0;
position: absolute;
font-size: 85px;
z-index: -1; /* adjustment here */
}
<header>
<h1 id="mtitle">Tepid Beans</h1>
<div id="tsub"><span>- Games</span>
</div>
</header>
z-index only works on elements that are positioned. So if you add position: relative; to #mtitle the z-indexing will work.
concerning the last part of your question,
tsub is appearing on top of #mtitle, and I do not know why.
elements with position: absolute are "taken out" of the regular flow of elements, they don't take up any space in their parent elements (which need a position setting other than static for that to work), they are only anchored to them (= will move with them). But that way they can overlap other elements.
Among several absolutely positioned elements, the z-index will determine which one is on top of another one..

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

How do I handle independent parent and child opacities when the child element is a link?

I have a parent <div> and a child <a>. The parent has a background image set to 60% opacity, but I'd like the child link to have 100% opacity. My reason for implementing it this way is so I can fade the parent's opacity to 100% on hover, thereby eliminating the need for a hover image.
I understand that children inherit their parent's opacity. I tried the :after {} technique described here, but even with appropriate z-index values set, the child link still sits beneath the parent element and is not clickable.
My issue is that the child link cannot be clicked because the parent's :after pseudo-element sits above the child.
My code is as follows:
<div>
Load more
</div>
div {
position: relative;
height: 300px;
}
div:after {
position: absolute;
top: 0;
left: 0;
content: '';
background: url('../img/bg-load-more.png') repeat-x;
width: 100%;
height: 300px;
z-index: 10;
opacity: 0.4;
}
div a {
display: block;
z-index: 100;
}
Does anyone know of a solution to this issue, or must I create an image sprite and switch swap background images on hover?
The problem is that you aren't applying a position to the <a> itself (z-index only applies to positioned elements) only the containing div and the pseudo-element, so the pseudo-element is sitting on top of the link preventing it from being clicked.
All you need to do is give the link a stacking context, e.g. include relative positioning:
div a {
display: block;
position: relative;
z-index: 100;
}
Example