z-index not working properly? - html

I have the HTML:
<div class="arrow" id="link1">
<img class="bellow" src="bottom.jpg" width="305" height="229" />
</div>
And the CSS:
.arrow {
display: block;
width: 305px;
height: 229px;
z-index: 10;
position: relative;
background-image: url(top.png);
}
#link1 {
background-position: 0 458PX;
z-index: 10;
position: absolute;
}
#link1:hover {
background-position: 0 229px;
z-index: 10;
position: absolute;
}
.bellow {
z-index: 1;
position: absolute;
}
But the background-image is not showing up on top of the bottom.jpg what is wrong with the z-index?

You cannot position an element inside a parent element to be behind that parent element.
Consider an HTML structure like so:
<div class="level-1">
<div class="level-2">
<div class="level-3"></div>
<div class="level-3"></div>
</div>
<div class="level-2">
<div class="level-3"></div>
<div class="level-3"></div>
</div>
</div>
<div class="level-1">
<div class="level-2">
<div class="level-3"></div>
<div class="level-3"></div>
</div>
<div class="level-2">
<div class="level-3"></div>
<div class="level-3"></div>
</div>
</div>
I've conveniently named each division with a level-class to easier understand.
Z-indexing works by applying that z-index to other elements within each parent. So being on the root element, the z-index for each level-1 division would only apply to other level-1 divisions. Just like a level-2 index would only apply to another level-2 index, and the same with a level-3 index.
So indexing from inside out: the level-3 indices would be ordered first under each of their parents. Note that their z-index would not apply to other level-3 elements in other parents, only other elements under the same parent. Once ordering of those level-3 elements is done, they are placed into their level-2 parent. At that point, the level-2 elements get ordered based on their indices relative to their parent, and then placed into their parent the same way the level-3 elements were, and then the level-1 elements are done.
So the way your HTML structure is set up, with an image inside of a division, that image cannot appear underneath its parent. Structurally, that doesn't make sense anyways. A child is meant to be contained within a parent, it should never stack with its parent. If you really want to place the image behind the division, it should be place outside of the parent and positioned accordingly.
Having said that, there is a bit of a hackish workaround, but it requires removing the position: absolute from the parent division and using a negative z-index.

body (or any other positioned parent element) is the reference for
both the child and and parent element
source: z-index between Children and Parents
This means the z-index on your parent also applies to the child element. Where the child element(image) will also take z-index: 10;. With the parent and child both have a z-index of 10, the child will actually be rendered over the parent.
To fix this you should not even give a z-index to the parent, but only to the child(the image):
.bellow {
z-index: -1;
position:absolute;
}
Where the image will have a lower value as the default value, thus will be underneath its parent.
jsFiddle

z-index works with absolute/fixed/relative positions only.
Write:
.arrow{position:relative;}
Also,
Remove image out of div.
It should work.
Fiddle here.

Related

Why does height 100% work on absolutely positioned element?

As far as I know for the height to work as percentage the container element must have a specific height mentioned. But this doesn't hold true for absolutely positioned element with the ancestor being relatively positioned. Here is a working example of what I meant:
.container {
width: 400px;
background: cyan;
text-align: right;
position: relative;
color: white;
}
.child {
width: 90%;
height: 100%;
background: blue;
}
.absolute {
position: absolute;
}
.second {
margin-top: 30px;
}
<div class="container">
<div class="child absolute">Absolute</div>
one <br> two <br> three <br> one <br> two <br> three <br>
</div>
<div class="container second">
<div class="child">Static</div>
one <br> two <br> three <br> one <br> two <br> three <br>
</div>
As you can see the absolutely placed div applied 100% height onto it but not the statically positioned div. Why?
From MDN
relative
This keyword lays out all elements as though the element were not positioned, and then adjusts the element's position, without changing layout (and thus leaving a gap for the element where it would have been had it not been positioned). The effect of position:relative on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined.
Read more. Is very nicely described.
Here is a great read about the different position types:
Absolute is relative to the parent element and is not affected by other elements and are removed from the flow of the page i.e. you can see the list with one, two, three unaffected.
It's height is 100% as .child specifies.

Two CSS absolute positioned items in one page

I have a design that requires an absolute positioned object on the top of the page. (menu inside of a circle)
Then about 5 row later (using foundation) I have a second absolute positioned element. But its position is based on the previous element because once you apply position: absolute to one element, you’ll usually find yourself applying it to everything else. So even if the rows are positioned relative by default, it doesn't reset the absolute position, so the element is floating to the beginning of the page.
I can position it but if I add an element I have to touch up the CSS so this is not good.
So how do you reset absolute position, I tried to have elements before my second element static and the other absolute but it does not work.
The first element is based on this Gist, then later the code is:
.or {
position: absolute;
background-image: url(../assets/img/OR.svg);
top: 50%;
left: 50%;
margin: -42px;
width: 84px;
height: 84px;
background-size: 84px 84px;
z-index: 50;
}
That's it for the HTML
<div class="row" data-equalizer>
<div class="small-6 columns text-center">
<div class="panel " data-equalizer-watch>
this is the content
</div>
</div>
<div class="or" > OR</div>
<div class="small-6 columns text-center">
<div class="panel" data-equalizer-watch>
this is the content
</div>
</div>
</div>
This is the Or part that need to be centered no matter the content on the side here it is regular but not on all the page
The solution was simple (like always) is is to put relative to the parent div

Will {position: absolute;} always position my element with respect to its first parent?

There are many div elements on my page
<div class="first">
<div class="second">
<div class="third">
<div class="important_div"></div>
</div>
</div>
</div>
I want to position ".important_div" with respect to .first. and in order to do this, I use the position: absolute; property:
.important_div {
position: absolute;
bottom: 0px;
}
Now here are my questions:
1)When I use absolute positioning, it positions my .important_div in respect to .third (father of .important_div). I want to position it in respect to .first div (great-grandfather of .important_div). What should I do?
2)Does {position: absolute} position my element always in respect to its parent?
3)Is there another way to position .important_div at the bottom of .first div, maybe using absolute or something similar?
It's relative to the first nearest positioned ancestor. So, if .third has positioning, it gets positioned relative to that element. Likewise, if .second has positioning (but not .third), it is positioned relative to that. If no elements have positioning, it's relative to the document container.
Here's a fiddle with an example: http://jsfiddle.net/mnKpu/1/
Apply:
position: relative;
to your .first div. And do not apply position: relative; to your .third div if you want to position your .important div relative to your .first div.
SEE THE DEMO here:

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

Positioning Elements in Tableless Layout

I am trying to do a tableless
layout, and I have the following
HTML snippet:
<div class="slider-inner">
<div class="slider-pane">
<div class="container">
<p>...</p>
<div class="did-you-knoow">
<div class="facts">
</div>
<div class="marquee-container">
</div>
</div>
</div>
</div>
</div>
Which is styled w/ this CSS:
div.slider-pane {
width: 1024px;
}
div.container {
display: block;
}
div.facts {
margin-right: 60%;
}
div.marquee-container {
position: absolute;
top: 0;
right: 0;
margin-left: 0;
margin-right: 0;
padding: 10px;
width: 60%;
}
I want the div.facts to occupy the left-40% , and the div.marquee-container
to occupy the right-60% of the div.did-you-know (their immediate parent). I
expect the div.marquee-container to be positioned relative to its parent, and
its width to be 60% of its parent, but its positioning and width are relative
to div.slider-inner, which is 2 levels above its parent.
How do I set the position and width of div.marquee-container relative to
its parent, and not the div three levels above it?
add position:relative to div.container
#locrizak's answer is correct, I needed to add 'position:relative' to the div.container, but I needed to add it to the div.did-you-know as well. In other words, I needed to set all of the containing div's to position:relative in order for the elements in question to be positioned relative to the immediate parent.
I found this was also answered in the MDN page for css position under the 'absolute' definition:
[The browser will] position [the element] at a specified position relative to its closest positioned ancestor or to the containing block
However the W3C reference was not as helpful.