How to set relative position with Grandfather! element? - html

I have a layout like this:
<div class='one'>
<div class='two'>
<div class='three'>some text</div>
</div>
</div>
Is possible to set relative position for three according to grandfather element (one) in CSS?
Look this:
http://jsfiddle.net/chalist/H48Je/

When an element has position: relative and you move it (say left: 20px) it moves in relation to its natural position in the flow of the page, leaving a gap where it was before (which no other element will grab, as it were). So in a way, the simple answer is yes: if you give .three a relative position and move it, it will move in relation to all its ancestors.
Generally, though, if you want to move an element in relation to an ancestor, you'd normally give the ancestor position: relative and the element that's being moved position: absolute. Then any positioning (e.g. top: 20px) will be in relation to the positioned ancestor, and the element being moved won't leave a gap behind.
The one thing to note is that this positioning will be in relation to the nearest positioned ancestor. So if .two has positioning, you won't be able to position .three in relation to .one ... (not directly, anyway).
BTW, if an element is set to position: absolute and no ancestor has any positioning set, any co-ordinates set on the absolute element will be in relation to the viewport.

Related

CSS absolute position orients on sibling rather than parent

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

Why do absolute elements stack up on each other instead of stacking one after the other?

How can get both #row1 and #row2 in the following code to be visible, one after the other vertically, as if there wasn't any absolute/relative positioning involved (though without removing the positioning properties)? I.e. having the two .row <div> to appear as "normal" block elements.
body { position:relative; min-height: 2em; width: 100%; }
.container {position:absolute;}
.row {position:relative;}
.col1, .col2 {position: absolute;}
<body>
<div class="container">
<div id="row1" class="row">
<div class="col1">Hello</div>
<div class="col2">World</div>
</div>
<div id="row2" class="row">
<div class="col1">Salut</div>
<div class="col2">le monde</div>
</div>
</div>
</body>
(Sample also available as a fiddle.)
I need the elements to have the positioning provided in the CSS rules, for reasons excluded here.
The content is programmatically dynamic; I don't know the elements' heights beforehand, so a solution can't be based on specifying an absolute length (e.g. 'px') anywhere.
Well you have some weird wishes here so let me explain you what those positions really mean in CSS and how they work, using position: relative; is just like using static position, the difference is making an element position: relative;, you will be able to use top, right, bottom and left properties, though the element will move, but physically it will be in the document flow..
Coming to position: absolute;, when you make any element position: absolute;, it gets out of the document flow, hence, it has nothing to do with any other element, so in your example
you have .col1, .col2 {position: absolute;} which are positioned absolute and since both are out of the document flow, they will overlap... Because they are already nested under position: absolute; parent i.e .container and since no width is assigned, it will take the minimal width and hence, your elements overlap, if you cannot change your CSS(which according to me doesn't make any sense why you can't change) still if you want, than you can do is this..
Demo (Without removing any of your position property) And this is really dirty
For the s characters, it will be at the top as your container element is out of the flow, and hence, no height will be considered in the document flow, unless and until you wrap that s in some element, and bring it down with, margin padding or CSS Positioning.
CSS Positions Explained
As I commented, here are few examples of how CSS Positioning actually works, to start with, there are 4 values for position property i.e static which is the default one, relative, absolute and fixed, so starting with static, nothing to learn much here, elements just stackup one below the other unless they are floated or made display: inline-block. With static positioning, top, right, bottom and left won't work.
Demo
Coming to position: relative; I've already explained you in general, it's nothing but same as static, it stacks up on other element, it is in the document flow, but you can tweak the elements position using top, right, bottom and left, physically, the element stays in the flow, only position of the element is changed.
Demo 2
Now comes absolute which generally many fails to understand, when making an element absolute it gets out of the document flow, and hence it stays independent, it has nothing to do with other elements positioning unless it's overlapped by other position: absolute element which can be fixed using z-index to change the stack level. The main thing to remember here is to have a position: relative; container so that your absolute positioned element is relative to that relative positioned element, else your element will fly out in the wild.
It's worth noting that position: absolute; element when positioned absolute; inside an absolute positioned parent element, than it is relative to that element and not relative to the grand parent element which may be positioned relative
Demo 3 (Without position: relative; container)
Demo 4 (With position: relative; container)
Last is position fixed, this is same as absolute but it flows along when you scroll, it's out of the document flow, but it scrolls, also, position: fixed; element cannot be relative to any container element having any type of position, not even relative, position fixed element is always relative to the viewport, so designers use position: absolute; when they want to have a fixed position behavior but relative to parent and tweak the top property onScroll.
Demo 5
What you want, is not possible without modifying the CSS position property. However, what you can do without touching the existing CSS, is overriding it with a more specific selector
.row .col1, .row .col2 {
position: relative;
}
See JSFiddle
when position:relative is used, the page layout will occur normally before being offset by top, left values, however position:absolute will ignore the document flow. The relative ones will work with no changes but absolute must be changed
.col1, .col2 {display:inline-block;}
http://jsfiddle.net/C4bQN/
EDIT: Depending on your circumstances, maybe you can wrap your table in an absolute positioned div then use normal document flow within the table?
<div class="absolute-wrap">
<div class="row">
<div class="col"> </div>
</div>
</div>

I want to fully grasp the concept of a 'position: relative' containing div

Please bear with me... and excuse my (probably) incorrect terminology:
In the following code I don't grasp why you set the containing (parent) div to 'position:relative' in order for the divs inside to be positioned in relation to the parent div (using 'position:absolute). I thought in order for this to happen the children divs would be set 'relative' to the parent. Am I to understand that essentially the parent div is saying to the other divs inside "hey, you can all be positioned 'relative' to me now!" I sort of expected it to work the other way around.
E.g. I expected the text would have been positioned "relative" to the containing div. Can someone explain why it works the way it does here? Thanks.
<div id="backgroundImage">
<h2 class="titleBox">I AM A TITLE</h2>
<p class="textBox">I am a description box</p>
</div>
#backgroundImage {
position: relative;
height: 225px;
width: 300px;
background-image: url (#);
}
.titleBox {
position: absolute;
top: 15px;
left: 0;
}
.textBox {
position: absolute;
bottom: 10px;
left: 0;
}
The documentation explains this very well, but I'll summarize.
An element with position:relative is first laid out just like any static element ... shifted according to the top, bottom, left and right properties
The position: relative box can be adjusted relative to its parent (even if its parent is static).
For position: absolute,
the containing block is the nearest positioned ancestor. By “positioned” I mean an element whose position property is set to relative, absolute or fixed
That is, the top, bottom, etc. properties on a position: absolute element are relative to the nearest containing element of a position other than static (including relative).
That is to say that position: absolute elements can still be positioned relatively.
You position the child elements absolutely, i.e you are specifying x/y co-ordinates for them (using left and top properties).
By default these will be positioned absolutely to the document, but by setting a parent container as position:relative, they will be positioned relative to that div, in an absolute manner.
If you set your element as position 'absolute' it will be out of the DOM.So you can set where ever you want unless or until your absoluted element parent or parents of parent... does not having any position relative.why we use position relative actually is if u want to style the the element irrespectively with other elements inside container, u can set position relative to the parent(means container). If #backgroundImage does not have position relative , your child elements will go initial position of your screen but if u want some where in the middle of ur page u have to styled the "backgroundImage" element as position :relative .. then the child element wil fly inside your "backgroundImage" container.

Absolute positioning inside absolute position

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.

Do we need to use absolute positioning for z-indexed divs?

I'd like to position a div on top of another div, but absolutely, something like:
<div id='parent'>
<div id='under' z-index='1' width='100' height='100'></div>
<div id='over' z-index='2' width='100' height='100'></div>
</div>
I know the width and height I need the two divs to be, but I don't know what absolute position they should be (if I read correctly, we need to specify absolute positioning for divs using z-index. Since they're both in a parent div, can I just set the x/y positions to both be 0,0, so that they're just absolutely positioned relative to their parent? Ehh, probably not - what can I do here?
Thanks
You just need to swap the order, so the absolute one comes first, like this:
<div id='parent'>
<div id='over' style='position: absolute; width: 100px; height: 100px'></div>
<div id='under' style='width: 100px; height: 100px'></div>
</div>
You can try a demo here, notice the result is red (the #over style).
This is over-top because the first one starts at the same position in the flow as the second, but takes up no room in the flow because of it being absolute. This means the under div also starts at the exact same position.
Well, the key words are 'relative to their parent', meaning that the parent should have relative positioning (position: relative;) in order to contain the absolutely positioned child divs, otherwise they'll be absolutely positioned relative to the document window.
After, you've set the parent's position to relative, set the child divs' position to absolute and by default, they should overlap at (0,0) relative the parent's position. You can then specify even more by adjusting the values for the properties: top, right, bottom, left.