z-index and stacking; removing a child from stacking context - html

I'm trying to tweak the stacking order of some elements; here's an SSCCE.
Given this HTML snippet:
<div id="block1">
<div>Lorem ipsum dolor.</div>
<div id="widget">
<div>Widgety goodness!</div>
</div>
</div>
<div id="block2">
<div>Lorem ipsum dolor.</div>
</div>
<div id="block3">
<div>Lorem ipsum dolor.</div>
</div>
I'm trying to display #widget on top of #block2; which with the following CSS, you'll see is problematic without changing the location of #widget in the node tree.
#block1, #block2, #block3 {
position: relative;
min-height: 50px;
width: 100%;
}
#block1, #block3 {
background-color: #abc;
color: #123;
z-index: 1;
}
#block2 {
background-color: #def;
color: #456;
z-index: 2;
}
#widget {
background-color: #f00;
position: absolute;
z-index: 999;
left: 200px;
top: 40px;
}
As you can see in the fiddle, #widget is overlapped partially by #block2; which makes perfect sense as the parent #block1 is lower among siblings in the stacking order.
The obvious answer is: make #widget a child of #block2, but unfortunately that's not a solution here. Additionally, the #blockN elements cannot have their relative z-index values modified; blocks 1 and 3 must be lower than 2. (by this I mean the calculated values could be different, but #block2 will always be greater than it's siblings). The reason for this, is box-shadow layering.
Is there any reasonable (read: cross-browser, IE7+) way to remove #widget from it's stacking context, while retaining it's position, coordinate location, dimensions, etc.?
Using fixed positioning removes it as desired, however it also obtains all the visual properties of being fixed (which makes it a non-solution)
I reckon this may have been answered in a roundabout way, however I didn't find it. Also, apologies; it appears I may have missed some innocuous but key details in my initial post. I think I've covered them all now.

Your rules aren't really applying to the elements that you want them to be applied to. You need to explicitly set the z-index on the elements you want to position, in your case that element is the div child of block2. By simply modifying the first selector from:
#block1, #block2 , #block3 {
to
#block1, #block2 div, #block3 {
Your stacking order is corrected. Your z-index rules were being applied to the parents while the children continued to use the default of auto. In your case, by setting the position on #block2 div, you allow your widget to sit on top of the block2 child div.
jsFiddle example

I guess you do not need to change the location of the #widget. In my view, the answer lies in your question itself. Check this out
Edited CSS:
#block1{
background-color: #abc;
color: #123;
z-index:3;
}
#block3 {
background-color: #abc;
color: #123;
z-index:1;
}

A working solution is to make use of the position stacking order for the divs and not using z-index here. So no unwanted stacking-contexts are formed.
Block 1 & 3 get the default position: static
Block 2 gets position: relative (which is over 1 & 2)
and only the widget gets a z-index, which moves it on top of it all!
http://jsfiddle.net/4eENM/

Related

Why border and background of a negative-margin'ed <p> goes under previous <img> [duplicate]

This question already has answers here:
Why the content is not covered by the background of an overlapping element?
(8 answers)
Closed 3 years ago.
An <img>, followed by a <p> with negative margin.
The <p> border and background are under the img.
I don't understand why.
Same in Firefox and Chromium.
Thanks !
#d1 {
width:400px;
}
#d1 img {
max-width:350px;
}
.caption {
color:red;
font-size:2em;
border:3px solid red;
margin-top:-40px;
background:#eee;
padding:10px;
/*position:relative;*/
}
<div id="d1">
<img src="https://i.kym-cdn.com/entries/icons/mobile/000/018/012/this_is_fine.jpg">
<p class="caption">This is fine.</p>
</div>
Adding position:relative to .caption solves the problem, but does not answer the question.
CodePen
Why does this happen? Because one element has to be under the other...
There is something called a stacking context. Certain element have a higher stacking context than other..
Root element (the element)
Non-positioned elements in the order they are defined
Positioned elements in the order they are defined
So in this case, the p has a lower stacking context since the position is being changed.
Add z-index to image
#d1 {
width: 400px;
}
#d1 img {
position: relative;
display: block;
max-width: 350px;
z-index: 5;
}
.caption {
color: red;
font-size: 2em;
border: 3px solid red;
margin-top: -40px;
background: #eee;
padding: 10px;
/*position:relative;*/
}
<div id="d1">
<img src="https://i.kym-cdn.com/entries/icons/mobile/000/018/012/this_is_fine.jpg">
<p class="caption">This is fine.</p>
</div>
Why is the image above the padding and border but below the text?
W3C answers this question already:
Each box belongs to one stacking context. Each positioned box in a given stacking context has an integer stack level, which is its position on the z-axis relative other stack levels within the same stacking context. Boxes with greater stack levels are always formatted in front of boxes with lower stack levels. Boxes may have negative stack levels. Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
Most important is this part:
Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
So if you switch the elements you will see that your image is now above you paragraph.
body {
background-color: #a3d5d3;
}
#d1 {
width:400px;
}
#d1 img {
max-width:350px;
margin-top: -70px;
}
.caption {
color:red;
font-size:2em;
border:3px solid red;
background:#eee;
padding:10px;
/*position:relative;*/
}
<div id="d1">
<p class="caption">This is fine.</p>
<img src="https://i.kym-cdn.com/entries/icons/mobile/000/018/012/this_is_fine.jpg">
</div>
<p>Why is the text over, but border and background under ?<br>
Expected: whole "caption" over img<br>
NB: <em>position:relative</em> in .caption solves the problem, but does not answer the question
</p>
In your example the background color is also below the image. It should be obvious why. Background color has a lower stacking context.
Here is an image that shows the order:

Parrent element negative margin and child element seems to collabs

Greetings
I have serius problem, I need to move div in div in a div, but it doesn't work.
My question is if there couldn't be some problems with negative margins or child element of element with margin problem.
It seems negative margin is collapsing with positive margin in child element.
The margin of child element is moving parrent element.
here is fiddle
of my problem.
What I want to achieve is that:
a. Article div is overlaping main heading, I tried to avoid using absolute position, so I went for negative margin.
b. Text is margined inside of an article div. From top.
<div class="container">
<div class="main-heading"><h1>Main Heading</h1></div>
<div class="wraper">
<div class="article">
<div class="text"><p>Text</p></div>
</div>
</div>
</div>
Also here is some of problem in css:
div {
width: 100%;
}
.container {
}
.heading {
}
.wraper {
margin-top: -100px;
height: 500px;
}
.article {
margin-top: 0;
height: 200px;
}
.text {
margin-top: 120px;
height: 50px;
}
As I said, margin of text element seems to move article element from top as well. It's me or where is the problem, and what's the solution or workaraund? Preferably even without absolute position, but if you really need to use them, don't worry, but clear it somehow so it can be used as part of column and wont interact with upper/bottom content.
Thank you verry much for your time
edit: picture of what I want to achieve
That black rectangle is wrapper,
cat is article
text is text, but the margins move whole article now.
I found a related toppic on this, it happens in all mayor browsers, and there is a simple solution on that. There is a must to use overflow attribute in CSS...
I used
overflow: auto;
On parrent element, and it worked.
Based on your comment and what I think you're asking:
<div class="image">
<p>PRESTO</p>
</div>
.image {
display:block;
position:relative;
background-color:grey;
width:300px;
height:200px;
}
p {
display:none;
position:absolute;
top:0;
width:100%;
text-align:center;
color:orange;
font-size:2em;
}
.image:hover > p {
display:block;
}
FIDDLE:
https://jsfiddle.net/su5aqs3p/2/

Flexbox order, position, wrapping fallback for IE9 and IE10

I have a "backend engineering constraint" that's forcing me to order my markup in a non semantic way but visually my team needs a different order. I was successfully able to achieve this with flex box and have attempted to polyfill with flexibility.js for IE 10 and 9. Unfortunately both 10 and 9 are having issues.
Note that I can not use jQuery/DOM manipulation to move "third" section around.
Does any one else have alternate suggestions or fixes that can help achieve the following:
Markup:
<div class="first">
<div class="second">
<div class="third">
But they need to visually see the following in IE 10 and 9:
So "first" and "third" need to appear visually as apart of the same section and the "second" section needs to be underneath and go full width of container.
Please see my full working codepen (fully working in chrome): http://codepen.io/semantictissue/pen/MypRVz
Any suggestions or help to make this cross browser friendly?
The easiest solution I've found is to position .third as absolute. To visually section off .first and .third, add CSS to .first which leaves room for .third to be set in the remaining space.
body { margin: 0; position: relative; }
.first { height:50px; width: 50%; background: blue; }
.second { height:50px; width:100%; background: gray; }
.third { height:50px; width: 50%; background:green;
position: absolute; top: 0; right: 0; }
<div class="first">first</div>
<div class="second">second</div>
<div class="third">third</div>
Here is your modified CodePen
The main downside to this approach is that it doesn't reflow the content as the window gets smaller. Media queries would have to be used at certain window sizes which change the width and positioning of the elements as needed. Using a CSS table layout would be useful once the content can be wrapped onto its own line. Info here

Issue with putting div over another div

Before giving negative vote or placing the question as duplicate, please read the issue first.
I'm having some issue with putting one div under another. I know that make people have asked this question here and I've read all of them and also tried everything out, but none of them worked for me.
Everyone days to give position: relative to to div and then give one higher z-index and another lower. None of them worked for me. So, I'm here for help.
In my project (http://loadtest.isaumya.com/) I have 2 divs i.e.
<body>
<div class="conteiner">blah blah blah</div>
<div id="particle-js"></div>
</body>
I want to put the <div id="particle-js"></div> behind of container, but nothing is working out. So please help.
You have ordered them badly:
<div class="container">...</div>
<div id="particles-js">...</div>
invert positions:
<div id="particles-js">...</div>
<div class="container">...</div>
makes sense since you want your full-screen canvas particles to be naturally z-index lower than the latter #container. Precedence rule.
also add this styles to your particle-js element:
#particles-js{
position:absolute;
top:0;
width:100%;
height:100%;
}
If the above still does not helps (it should) add:
.container {
position: relative;
z-index: 1;
}
Make your canvas element display:block;
Result image:
its just a very simple concept you need to remember about position in css
A relative positioned element is positioned relative to its normal
position
An absolute position element is positioned relative to the first
parent element that has a position other than static.
JSFiddle
this is how you may solve this problem:
<body>
<div class="container">blah blah blah</div>
<div id="particle-js"></div>
</body>
and the css
div {
width: 100px;
height: 100px;
}
.container {
position: absolute;
background-color: blue;
z-index: 1;
}
#particle-js {
position: absolute;
background-color: red;
}
make the z-index higher to wichever element you want a be displayed at the top

Difference between auto, 0, and no z-index?

What is the difference between:
z-index: auto
z-index: 0
no z-index at all
All the above scenarios are for a div that encloses two divs, div1 and div2 each having a z-index which is 9 and 10 respectively.
The enclosing div is in the stacking context of HTML.
Not specifying z-index is the same as z-index: auto; that is its initial value.
auto and 0 mean the same thing if your element doesn't create its own stacking context; e.g. it is not positioned as relative, absolute or fixed.
If your enclosing div isn't positioned, then whatever you set its z-index to doesn't matter; it and all its contents will participate in the stacking context of html, and its descendants will always be positioned in front of it.
What #BoltClock said is right.
Not specifying z-index is the same as z-index: auto; that is its initial value.
About z-index: 0 it's important to note the following:
z-index: 0 creates a stacking context while z-index: auto do not. You can check MDN for more information about this.
In most cases this won't affect the rendered elements.
The following fiddle is an example where it matters: https://jsfiddle.net/ramcdvns/3/
Code and explanation below:
<style>
.box {
position: relative;
width: 64px;
height: 64px;
top: 32px;
left: 32px;
}
.red {
background: red;
}
.green {
background: green;
}
.blue {
background: blue;
}
#example-0 {
margin-top: 32px;
}
</style>
<div id="example-auto">
<div class="box red">
<div class="box green" style="z-index: 1"></div>
</div>
<div class="box blue"></div>
</div>
<div id="example-0">
<div class="box red" style="z-index: 0">
<div class="box green" style="z-index: 1"></div>
</div>
<div class="box blue"></div>
</div>
In both examples, red and blue are siblings with a position: relative and green is a child of red with position: relative and z-index: 1:
Root
Red: position: relative
Green: position: relative; z-index: 1
Blue: position: relative
In the first example, green will be positioned above red and blue. This is because it has a z-index: 1, so a stacking context is created and put above the root context.
In the second example, green will be positioned above red, but below blue. This is because red has z-index: 0, so it creates a stacking context at the same level of blue. So green will be above red (because green also creates a stacking context), but below blue because it's trapped in the context of red.
Hopefully the fiddle is clear enough as it's hard to explain this in words.
z-index:0 is always the "default layer" (the layer in which all elements without an explicit z-index reside), and z-index:auto means: "Sets the stack order equal to its parent".
Since all the children of a parent by default start in the "z-layer 0" - relative to their parent, then, in-affect, z-index:auto and z-index:0 means the same thing: they will both be in the same "layer", and their stacking order will be according to the default stacking rules, which you can see here.
z-index: auto
Sets the stack order equal to its parents. This is default.
z-index:0
does nothing
z-index:not
Sets the stack order equal to its parents same as auto.
z-index:inherit
Specifies that the z-index should be inherited from the parent element
Reference for further reading and testing:
Link
n CSS, you can position 2 or more objects to overlap each other. Their z-indexes determine which objects are "in front of" or "behind" other objects that they overlap. The higher an object's z-index, the "higher in the stack" of objects it will display