I have an element which contains two children, one of which is positioned absolutely. I would like this absolutely positioned element to be behind its sibling. It seems z-index does not have much of an effect. How do I accomplish this?
JSFiddle here: http://jsfiddle.net/03c3qq6w/ I want the green box to be behind the red one.
Putting position: relative to #two div fix the problem: http://jsfiddle.net/03c3qq6w/1/
#two {
position: relative;
}
In order to use z-index you have to add position to your element.
From Css-Tricks:
The z-index property in CSS controls the vertical stacking order of
elements that overlap. As in, which one appears as if it is physically
closer to you. z-index only effects elements that have a position
value other than static (the default).
http://css-tricks.com/almanac/properties/z/z-index/
Related
I am a little confused about absolute positioning right now. I have always thought that if I position an element absolutely it would be positioned relative to it's parent element (in contrast to relative to it's usual position like relative positioning). During homework I now came across this situation and I'm confused:
<body>
<div> <!-- This is colored red in my example -->
...
</div>
<div style="position: absolute;"> <!-- This is colored green in my example -->
...
</div>
</body>
What I would expect:
What I got:
Of course when I set an actual position with left/right/top/bottom I get what I would expect from an absolutely positioned element. So is position: absolute just set to take the exact position it would be at without position: absolute when not specified otherwise?
To clarify:
"I have always thought that if I position an element absolutely it would
be positioned relative to it's parent element"
Nope. If an element has position: absolute;, it is positioned relative to the nearest parent in the DOM chain that has position: relative; or position: absolute; specified on it. If no parents have it (ie. they are all position: static, which is the default), then it is positioned relative to the document (page).
When using position: absolute, always:
Be aware of what parent you want it positioned relative to, and make sure that parent has position: relative; on it.
Specify one or more of the top/right/bottom/left attributes on the absolutely positioned object.
You are confused with the difference between position and display.
Position will change which element your element will be positioned relative to. In your case, your child div is now positioned to the body element. That's why it's on top.
Also you need to be aware that div is displayed as block, which means it will take all the width. If you want to align 2 divs left and right, the modern way is to use flexbox. The old way is float left/right.
I have made an article to explain CSS position in details:
https://www.youtube.com/watch?v=nGN5CohGVTI
I have two elements: one with relative positioning that defines most of my header, and a smaller one that I'd like to "float" on top of it.
<div id=floater style="float:right">
Floater!
</div>
<div id=header style="width: 100%; position: relative; background-color: lightgreen">
This is the header
</div>
As shown in this fiddle, the floated component is invisible. But if you remove the position: relative, the floated element pops right up. Futzing with the z-index hasn't yielded anything of interest.
The header component isn't "mine"; it's inherited through React-Bootstrap. I could override, but right now I'm mostly looking to understand the interaction of float and relative positioning.
Elements without a position property set will default to "position:static" which ignores all positioning properties such as z-index. By setting relative positioning to the header element you have introduced the z-index positioning property to that element bringing it in front of the floater element which does not have a z-index property.
Since z-index will be ignored with a static floater element you will have to give that element a position property (absolute, relative or fixed) so it can have z-index as well.
For your example "position: relative;" would work. Once you have set the position property on the floater element you would need to add a z-index value to it that's higher then the header element. Which in this case z-index:1 would be a higher value since z-index is set to default.
Example:
<div id=floater style="float:right; position: relative; z-index: 1;">
Floater!
</div>
<div id=header style="width: 100%; position: relative; background-color: lightgreen">
This is the header
</div>
When elements are positioned, they can overlap other elements. If two positioned elements overlap without a z-index specified, the element positioned last in the HTML code will be shown on top.
This is a function of the painting order
In-flow, non-positioned, block-level elements are painted in step 4
Floated items are painted at step 5. So the floated element is painted "on top" of the static div and you see it displayed.
But positioned descendants with 'z-index: auto' or 'z-index: 0' are painted in step 8. So adding position:relative to the div means that it is now painted "on top" of the floated element, hiding it.
My actual issue is more complicated, but it boils down to this. How can I use CSS to disallow a relative positioned div to stack on an absolute positioned div.
Example of issue:
<div id="absolute"></div>
<div id="relative"></div>
div{
width: 100px;
height: 100px;
opacity: .5;
}
#absolute{
position: absolute;
background-color: red;
}
#relative{
position: relative;
background-color: blue;
}
Codepen
Is this possible with css? So the relative positioned div would be pushed down or to the side until it is not longer covering the other absolute positioned div. Basically the relative div would act as if the absolute div is relative.
To add a little detail of the nature do the issue:
I have a webpage with an absolutely positioned menu on the top and left. I then have a div in which I am injecting templates (Angular). The issue is that the templates end up under the menus. I have tried to apply a margin or padding, but is is messing up my bootstrap grid. So I was hoping the menu could be treated Iike it was relative in regards to the main div, but still stay in place.
When you use position:absolute, you're telling the browser layout engine that this element is removed from the layout of the page. You are specifying a manual position that will not impact the layout of the page in any way. Thus, you cannot both position it manually and have things layout around it.
You must pick one of the other, either don't use position: absolute so that it will participate in the layout of the page or make everything absolute and manually position things not to overlap.
There are some hybrid approaches where a item can be positioned absolutely in a container and the container itself is relative (not absolute) so that the container participates in the layout of the page and things will lay out around the container (and thus around the absolute positioned element if the container is set to be the right size), but this is really just a technicality as it puts the absolute positioned item into a non-absolute positioned container so it isn't really absolute positioned on the overall page any more.
It sounds like your problem would be solved by separating the elements and applying a float property. However, per your question, when your use the relative property, it allows you to set the position relative to it's parent. If the absolute positioned element is the parent, then your code is incorrect and keeping them separated would be a matter of hard-coding them to maintain a minimum distance from one another. However, it is not the parent then the elements have no relation to each other and you must explicitly define their position in order for them to not interact with each other. But again, it sounds like a situation to apply the float property.
I am building a small web application.
I have two divs. One is absolute and the other is static.
I am trying to position my static div on top of my absolute one, so that it remains the top most item.
Very simple Code Sample:
http://jsbin.com/efuxe3/edit
How can this be done?
Edit:
I have been using z-index. It seems to have no effect.
z-index doesn't apply to static elements.
According to this page:
This property specifies the stack
level of a box whose position value is
one of absolute, fixed, or relative.
If you make your div relative instead, you can use z-index to determine the order.
position: relative positions the element relative to its default (static) position, so if you don't specify a top, bottom, left or right then there'll be no difference between static and relative other than that relative allows you to use z-index to move your element up the stack.
Edit: based on your code sample, here's a working demo.
Edit 2: based on Nathan D. Ryan's suggestion in the comments below, you could also apply a negative z-index to your absolutely-positioned div. This would move it behind everything else on the page that didn't have a lower z-index defined.
Rather than placing the statically positioned element over the absolutely positioned element, you can place the absolutely positioned element behind the statically positioned element. You can do this by setting the z-index of the absolutely positioned element to a negative value. However, as #Town mentioned, this will also place the absolutely positioned element behind everything else in the normal flow.
You can apply a negative z-index to the other elements placing them behind the static div. This can be applied directly to the other elements or you can use
*:not(connectedObjects){
z-index:-1000000000000000000000000000;
}
But this does not work in internet explorer
You could have a second absolutely positioned div to contain your statically positioned elements:
<div id="container">
<div class="underlay">
I want this to appear under my static items.
</div>
<div class="item_container">
<div class="item">blah</div>
<div class="item">yada</div>
<div class="item">foo</div>
<div class="item">bar</div>
</div>
</div>
And your css is
.underlay {
position: absolute;
z-index: 0;
}
.item_container {
position:absolute;
z-index:10;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.item {
position: static;
}
if by top you mean z-Index, you can set the style of that div with a higher z-index
div.divClassName {
z-Index:100;
}
edit:
you can change the z-index of your div, with absolute positioning to a negative, but then you will have to do so for every other element.
Unless you really have a really good reason to using positioning to static you can change it
to relative, and the z-index will have an effect.io have tried it in your code sample and it works fine;
Work with z-index attribute. The z-index of the object which should be at front must be higher than the other ones.
I have 3 div elements.
1st div is bigger (wrap) and has position:relative;
2nd div is positioned absolute to the 1st div relative positioning (and is included in the 1st div)
3rd div is contained in the 2nd div and also has absolute positioning.
<div id="1st">
<div id="2nd">
<div id="3rd"></div>
</div>
</div>
Why is the 3rd div position absolute to the 2nd div (which is also absolute position to the 1st div) and not to 1st div that has relative position ?
Because the 3rd div is absolute positioning to the absolute positioned 2nd div.
Because position: absolute resets the relative position for children just as position: relative does.
There is no way around this - if you want the third div to be absolutely positioned relatively to the first one, you will have to make it a child of the first one.
Both position:relative and position:absolute establish containing elements as positioning ascestors.
If you need div 3 to be positioned based on div 1 then make it a direct child of div 1.
Note that position: relative means the element is positioned relative to its natural position and position: absolute means the element is positioned relative to its first position:relative or position:absolute ancestor.
Position static: the static position is the default way an element
will appear in the normal flow of your
HTML file if no position is specified at all.
Important: top, right, bottom and left properties HAVE NO EFFECT ON A STATICALLY
POSITIONED ELEMENT.
Position relative: positioning an element with the relative value keeps the element (and the space it occupies) in the normal flow of your HTML file.
You can then move the element by some amount using the properties left, right, top and bottom. However, this may cause the element to overlap other elements that are on the
page—which may or may not be the effect that you want.
A relatively positioned element can move from its spot, but the space it occupied remains.
Position absolute: applying the absolute position value to an element removes it from the normal flow. When you move the absolute positioned element, its reference point is the top/left of its nearest containing element that has a position declared other than static—also called its nearest positioning context. So, if no containing element with a position other than static exists, then it will be positioned from the top-left corner of
the body element.
In your case 3rd's nearest containing container is 2nd.
Yet another clarifying answer.
Your current scenario is this:
#my-parent {position: absolute}
#my-parent .my_child {position: absolute}
And you're kind of struggling with it.
If you can change the HTML, simply do this:
#my-parent {position: absolute}
#my-parent .my-wrapper {position: relative} /* Since you've added the wrapper in HTML */
#my-parent .my-wrapper .my-child {position: absolute} /* Now you can play with it */
The reason why the 3rd div element is absolutely positioned to the 2nd div element is because as the CSS spec explains here, is because the "parent" element (better said: containing block) of an absolutely positioned element is not necessarily its immediate parent element, but rather its immediate positioned element i.e. any element whose position is set to anything but static for example position: relative/absolute/fixed/sticky;
Hence, whenever possible in your code, if you want the 3rd div element be absolutely positioned in regards to the 1st div you should make your 2nd div element as position: static; which is its default value (or just simply remove any position: ... declaration in the rule set of your 2nd div element).
The above will make the 1st div the containing block of the 3rd absolutely positioned div, ignoring the 2nd div for this positioning purpose.
Hope it helps.
In case anyone is still looking for an answer to this.
I was able to achieve this result by adding a clear: both; style to the first absolutely positioned div which reset the child and allowed it to use it's own absolute positioning.