Z-Index Relative or Absolute? - css

I'm trying to find an answer to the following question:
Is an element's z-index style its absolute stack order, or its stack order relative to its parent?
For instance, suppose I have the following code:
<div style="z-index:-100">
<div id="dHello" style="z-index:200">Hello World</div>
</div>
<div id="dDomination" style="z-index:100">I Dominate!</div>
Which one will be in front - #dHello, or #dDomination?
That's just for examples. I've tried this in multiple places and results seem to vary. I'm seeing if anyone knows of an authoritative source for settling:
1) What are the actual standards regarding z-index (on this topic specifically)?
2) How do individual browsers vary in their actual implementation of this?
Thanks!

z-index is relative. See this detailed answer, which I wrote for a similar question.
If none of the other elements have a defined z-index, using
z-index: 1 will be fine.
Model: How is the z-index determined?
z-index
<div id=A> Auto 1
<div id=B> Auto 1.1
<div id=C style="z-index:1"></div> Manual 1
<div id=D></div> Auto 1.1.2
</div>
<div id=E></div> Auto 1.2
</div>
<div id=F></div> Auto 2
First, the direct
child nodes of the body are walked through. Two elements are
encountered: #A and #F. These are assigned a z-index of 1 and 2. This
step is repeated for each (child) element in the document.
Then, the manually set z-index properties are checked. If two
z-index values equal, their position in the document tree are
compared.
Your case:
<div id=X style="z-index:1"> Z-index 1
<div id=Y style="z-index:3"></div> Z-index 3
</div>
<div id=Z style="z-index:2"></div> Z-index 2
You'd expect #Y to
overlap #Z, because a z-index of 3 is clearly higher than 2. Well,
you're wrong: #Y is a child of #X, with a z-index of 1. Two is
higher than one, and thus, #Z will be shown over #X (and #Y).
Here is a plunker to visualize this a little better, or try the snippet below
,
.redbox,
.greenbox,
.bluebox {
height: 100px;
width: 100px;
position: relative;
color: #fff;
padding: 3px;
}
.redbox {
background: red;
z-index: 1;
}
.greenbox {
background: green;
top: 40px;
left: 40px;
z-index: 3;
}
.bluebox {
background: blue;
top: -20px;
left: 20px;
z-index: 2;
}
<div id=X class='redbox'>z: 1
<div id=Y class='greenbox'> z: 3</div>
</div>
<div id=Z class='bluebox'>z: 2</div>

Afaik, z-index doesn't work unless that element is set to position: relative; If that same element had a child with position: relative; and the z-index was set higher, the child would show on top of its parent.
So it has elements of both 'absolute' and 'relative' stack order as you phrased it.
All browsers pretty much handle it the same, I think.

Here is the W3C specification for z-index.
I think the most important line, based on your question is the following:
The order in which the rendering tree is painted onto the canvas is
described in terms of stacking contexts. Stacking contexts can contain
further stacking contexts. A stacking context is atomic from the point
of view of its parent stacking context; boxes in other stacking
contexts may not come between any of its boxes.
This seems to indicate that nothing can be drawn in between the div with z-index: -100 and the div with z-index: 200.

For example:
<!DOCTYPE html>
<html>
<head>
<style>
.x1 {
position:relative;
width:100%;
clear:both;
display:block;
z-index:1000;
}
.x2 {
position:fixed;
width:100%;
height:50px;
background-color:#ff0000;
}
.x3 {
position:relative;
height:250px;
width:600px;
background-color:#888;
}
.x4 {
position:relative;
height:250px;
width:600px;
background-color:#0000ff;
}
.x5 {
position:relative;
height:250px;
width:600px;
background-color:#ff00ff;
}
.x6 {
position:relative;
height:250px;
width:600px;
background-color:#0000ff;
}
</style>
</head>
<body>
<div class='x1'>this class is relative
<div class='x2'>this class is fixed</div>
</div>
<div class='x3'>x3: this class is relative</div>
<div class='x4'>x4: this class is relative</div>
<div class='x5'>x5: this class is relative</div>
<div class='x6'>x6: this class is relative</div>
<div class='x3'>x3: this class is relative</div>
</body>
</html>

Related

css z-index bug in blogger

I'm creating a new blogger template , but unfortunately I'm facing an issue.
simple example for what i am trying to do.
<div class='container'>
<div class='slider'></div>
<div class='posts'></div>
</div>
by default the second div (posts) should have z-index higher than the first one.
see this demo
and see this pic and now see what should be done here
, so what is the problem !.
here is my blog
To have an apparent higher z-index, the element must either be
After the other element or
Have a position:relative; or absolute when the previous element has a relative/absolute position.
.d1{
width: 100%;
height:50px;
background: tomato;
position: relative;
}
.d2{
width:80%;
height:200px;
background: blue;
margin: -30px auto 0 auto;
position: relative; /* Try removing this - it will be 'below' d1 because d1 has position:relative; */
}
<div class='container'>
<div class='d1 slider'></div>
<div class='d2 posts'></div>
</div>
In your case, this means adding position:relative; to .container class.

Absolute positioned div expands the relative positioned parent div

I have searched various questions, which all seem to be able to extend absolute children beyond their relative parent. I am trying to avoid this.
I have a div with position: relative; that contains a div with position: absolute; that i want to always sit at the bottom of the div. When I set bottom:0px; the absolute child extends beyond the parent div with 4 px. It can be solved by setting bottom:4px; but when I begin making the site responsive such absolute numbers won't do the trick.
html:
<a href="her.html">
<div class="next_movie">
<img src="img/her_header.jpg" alt="Picture from the movie 'Her'">
<div class="movie_info">
<h2>Her (2013) March 6th in AUD1</h2>
</div>
</div>
</a>
css:
.movies {
width: 616.6px;
height:663px;
background-color: #e3e3e3;
margin-top: 75px;
position: absolute;
left:233.3px;;
}
.movie_info, .poster_info {
color:white;
}
.next_movie {
position:relative;
margin:16.6px;
}
.movie_info{
position:absolute;
left:0px;
bottom:0px;
width:582.5px;
height:56.6px;
background:rgba(0,0,0,0.5);
color:white;
font-size:25px;
line-height: 2.3;
}
.movie_info h2 {
margin-left:15.8px;
}
Test version of the site sits here:
http://jhalland.dk/test/
You should try removing height from your movie_info styles. Or you can change it to min-height. You have conflicting rules since you've defined line-height as 2.3

CSS: center element between floating elements

Pretty simple question, but can't seem to find the solution. I have 5 elements: 2 floating left, 2 floating right. The fifth element is supposed to be in the perfect center of the div (#infographic), no matter what the screen width is.
example:
1,2 -- 3 -- 4,5 OR 1,2 ----- 3 ----- 4,5
HTML code:
<div id="infographic">
<div class="icon-one"></div>
<p>me</p>
<div class="arrows"></div>
<p>customer</p>
<div class="icon-two"></div>
</div>
Any suggestions to get the element in the center?
I guess this is the output you are looking for :
DEMO
html, body,p{
margin:0;
padding:0;
}
#infographic * {
width:10%;
height:30px;
background:teal;
padding:0;
margin:0 1%;
}
#infographic .icon-one, #infographic .icon-one + p {
float:left;
}
#infographic .icon-two, #infographic .icon-two + p {
float:right;
}
#infographic .arrows{
margin:0 auto;
text-align:center;
}
<div id="infographic">
<div class="icon-one"></div>
<p>me</p>
<div class="icon-two"></div>
<p>customer</p>
<div class="arrows">arrows</div>
</div>
If 12 and 45 have fixed width you can not achieve this using css float, you must use something like absolute positionning instead.
For more information qive a link to your page in its current state, or some more code.
Try this:
If you have two floated divs, then you know the margins. The problem
is that the float:right div should be put before the middle div. So
basically you will have:
left-floated | right-floated | centered
Now, about the margins: usually you can just use margin:0 auto, right?
The problem is that right now you know the values of the margins:
floated divs! So you just need to use:
margin:0 right-floated-width 0 left-floated-width
That should work...
See: this answer
Add position: relative to the container to allow the .arrows to be positioned absolutely relative to the container. Position the .arrows at the center of the container by using top: 50% and left: 50% (the percentages are relative to the container) and then move the .arrows a bit to the top left by using transform: translate(-50%, -50%) (percentages are relative to the .arrows)
.arrows {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
See http://codepen.io/ckuijjer/pen/rhEgy for an example or http://css-tricks.com/centering-css-complete-guide/ for a complete tutorial on horizonal/vertical centering.
If it's only about horizontal centering you might even be able to use
.arrows {
margin: 0 auto;
}
as floating elements are taken outside of the normal document flow
First, it should be possible to group the left and right floated elements together. What we can then do is create a 'fake' wrapper that fills up the entire container. If we know the width of the element to be centered, this can then be centered using a margin.
<div id="infographic">
<div class='leftcol left'>
<div class="icon-one left">1</div>
<p class='left'>me</p>
<div class='clear'></div>
</div>
<div class='rightcol right'>
<p class='right'>customer</p>
<div class="icon-two right">2</div>
<div class='clear'></div>
</div>
<div class='center'>
<div class="arrows">A</div>
</div>
</div>
CSS:
.left {
float: left; }
.right {
float: right;}
.center {
overflow: hidden;
position: absolute;
width: 100%;
}
.arrows {
margin: 0 auto;
display: block;
width: 30px;
}
.clear {
clear: both;
}
#infographic {
position: relative;
}
If we do not know the width of the centered element, take a look at the question Centering a div block without the width and apply the solution there.
Note that the solution presented assumes that the center width is never so wide that it will become wider than the two columns on the left and the right. If you want to have safeguards for that you should set a maximum width percentage like so (the example restricts each column to one-third of the total width):
.leftcol .rightcol .arrows {
max-width: 33.3%
}

Relative parent DIV to inherit the width of absolute child DIV

I am trying to position a child DIV at the bottom of a parent DIV, but I would also like the contents of the child DIV to help dictate the dimensions of the parent DIV. As I have it right now, the child DIV doesn't affect the width/height of the parent DIV.
Here is a sample of my HTML/CSS code:
//HTML code:
<div id="parent">
<h3>Top Aligned Title</h3>
<div id="child"></div>
</div>
//CSS code:
#parent {
background-color:#222;
position: relative;
height: 500px;
}
#child {
background-color:#444;
position: absolute;
bottom: 0px;
width: 100px;
height: 200px;
}
What do I need to do it achieve what I am trying to do? I could forgo the absolute/relative CSS rules and simply create a table within the parent DIV which would allow me to achieve both bottom alignment and content that dictates the parent's dimensions.
However, I'd like to know if there a way to do this in CSS and without having to set the width of the parent DIV.
thanks in advance!
The short answer is that what you are asking basically can't be done with pure CSS / HTML. (at least without tables) You'd need Javascript that would read #child's width/height and then do the calculation you want to do (I don't know) and set a new height/width to #parent.
Otherwise, if you mean that you want #child's height/width to change according to its content, of course this is native CSS, just set it's height/width to auto and then start adding text inside it you'll see it will start growing to fit your content inside.
As the #child is positioned absolute, then it is taken OUT of the normal flow of the document, therefore it will not affect the #parent.
With modern CSS, this is doable.
HTML:
<div id="parent">
<h3>Top Aligned Title</h3>
<div id="child">
<p>CHILD ELEMENT</p>
</div>
</div>
CSS:
#parent {
background:red;
height: 500px;
position:relative;
}
#child {
background:green;
position: absolute;
top:100%;
-webkit-transform: translateY(-100%);
-ms-transform: translateY(-100%);
transform: translateY(-100%);
width: 100px;
}
http://jsfiddle.net/Bushwazi/bpe5s6x3/
transform:translateY(-100%); is the trick. It's math is based on the element's box-model.
You could also combine top:50%; with transform:translateY(-50%); to center it.
You can swap top for left and translateY for translateX to position the element horizontally.
Here you go
HTML:
<main id="parent">
<div class="popup">Top Aligned Title
<div class="content">
Content
</div>
</div>
</main>
CSS:
#parent {
width: 120px;
}
.popup {
position: relative;
margin-top: 48px;
}
.content {
left: 0;
position: absolute;
background: green;
width: 100%;
}
http://jsfiddle.net/8L9votay/
You can play around with flex and zero-width/height.
I've recently come up with the following solution (for width):
#parent {
display: inline-flex;
flex-direction: column;
background: #518cff;
color: #fff;
}
#child-wrapper {
height: 0; /* This can also be max-height, but height is just enough */
}
#child {
transform: translateY(-100%); /* If you need to align child to the bottom */
background: #b40000;
color: #fff;
}
<div id="parent">
<h3>Top Aligned Title</h3>
<div id="child-wrapper"> <!-- This is the solution -->
<div id="child">
Child's content that is longer than parent's
</div>
</div>
</div>

how to position two divs above each over

Is there any way to start drawing divs from the same point? That means if I add new div and then I add another div, they will appear above each other. Because I want to move them all together depending on the same point.
CSS:
#num1,#num2{
display : inline
position:relative;
left:50px;
}
HTML:
<div id='container'>
<div id='num1'></div>
<div id='num2'></div>
</div>
So what should I add to this code so when the browser render this code the 2 divs will be on the same place?
All statements regarding absolute positioning are correct. People failed to mention, however, that you need position: relative on the parent container.
#container {
position: relative;
}
#num1,
#num2 {
position: absolute;
left: 50px;
}
<div id='container'>
<div id='num1'>1</div>
<div id='num2'>2</div>
</div>
Depending on which element you want on top, you can apply z-indexes to your absolutely positioned divs. A higher z-index gives the element more importance, placing it on the top of the other elements:
#container {
position: relative;
}
#num1,
#num2 {
position: absolute;
left: 50px;
}
/* num2 will be on top of num1 */
#num1 {
z-index: 1;
}
#num2 {
z-index: 2;
}
<div id='container'>
<div id='num1'>1</div>
<div id='num2'>2</div>
</div>
Use z-index to position divs on top of one another:
[http://www.w3schools.com/Css/pr_pos_z-index.asp][1]
So, you'll position the divs with absolute/relative positioning and then use z-index to layer them:
http://www.w3schools.com/cssref/pr_pos_z-index.asp
Make the first one position:absolute, which should take it out of the normal flow of the page.
some help.
I believe the only way to do this is to use absolute positioning
You can use absolute positioning.
#num1,#num2{ display : inline position:absolute; left:50px;top:10px; }

Resources