Understanding absolute behavior of positioned element [duplicate] - html

I'm just learning the positioning in CSS. Based on the article that I've found useful, I'd started to playing around.
With the following code, I cannot understand why the absolute grey-box div is outside of it's relative parent. I expected that the grey-box will be on the top-left corner of the container.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Also can't understand in the following case why the grey-box not in the top-left corner, but moved after the empty space left by the orange-box there. I've just moved the grey-box to the second place inside the container div.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-grey"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
All the detailed documentation (e.g. MDN) and tutorials that I've found just demonstrating very simple examples with 2-3 boxes.

To correctly understand this, you need to refer to the official specification where you find the equation the element must satisfy:
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block
We don't have any border and padding so in your case it will simply be:
'top' + 'margin-top' + 'height' + 'margin-bottom' + 'bottom' = height of containing block
And if you read under you will find this:
'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'.
So in your case, you have set a height and kept top/bottom to auto thus top will be set to static position
..More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'..
To make it easy, it's the position of the element if you didn't set position:absolute.
Here is an easy illustration to better understand
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey">I am absolute</div>
</div>
Note the static position of the first element that is kept if we add position:absolute. We didn't specify any top value so the browser will use a default one that is the one of the position:static (default position) of the element.
If you don't want this, simply set the top value and you fall into this rule:
'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
top:0;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Same logic apply to the left property
You may also notice the use of the word containing block which very important here and explained in the same specification
The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:
...
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
...
And it's not enough as there is other properties (listed below) that also establish a containing block so you can have an element positionned relatively to an ancestor that is not positionned!
Related: Why does applying a CSS-Filter on the parent break the child positioning?

You must always set top:0; left:0; on absolutely-positioned elements (or whatever values you want for top, right, bottom, left).

First of all, the element is positioned relative to its first positioned (not static) ancestor element.
In this case, the position absolute works with the sibling, not with the ancestor.
About the ancestors and siblings, there are a godd documentation about it : Ancestors and siblings
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
If i put the element after the div container all works without problem
Documentation of postion
About the second part, that box appears there because the box-gery doesnt matter about the top and right of box-green, got it? Ill put an example:
.container {
background: lightblue;
position: relative;
}
.box-orange2 {
background: orange;
height: 100px;
width: 100px;
position: relative;
z-index: 2;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-yellow {
background: yellow;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange2"></div>
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-yellow"></div>
</div>
You can see that the grey and yellow boxes do not change the behavior even if the top and right are in the sibling or not.

Related

whats the difference between these two divs [duplicate]

I'm just learning the positioning in CSS. Based on the article that I've found useful, I'd started to playing around.
With the following code, I cannot understand why the absolute grey-box div is outside of it's relative parent. I expected that the grey-box will be on the top-left corner of the container.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Also can't understand in the following case why the grey-box not in the top-left corner, but moved after the empty space left by the orange-box there. I've just moved the grey-box to the second place inside the container div.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-grey"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
All the detailed documentation (e.g. MDN) and tutorials that I've found just demonstrating very simple examples with 2-3 boxes.
To correctly understand this, you need to refer to the official specification where you find the equation the element must satisfy:
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block
We don't have any border and padding so in your case it will simply be:
'top' + 'margin-top' + 'height' + 'margin-bottom' + 'bottom' = height of containing block
And if you read under you will find this:
'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'.
So in your case, you have set a height and kept top/bottom to auto thus top will be set to static position
..More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'..
To make it easy, it's the position of the element if you didn't set position:absolute.
Here is an easy illustration to better understand
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey">I am absolute</div>
</div>
Note the static position of the first element that is kept if we add position:absolute. We didn't specify any top value so the browser will use a default one that is the one of the position:static (default position) of the element.
If you don't want this, simply set the top value and you fall into this rule:
'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
top:0;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Same logic apply to the left property
You may also notice the use of the word containing block which very important here and explained in the same specification
The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:
...
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
...
And it's not enough as there is other properties (listed below) that also establish a containing block so you can have an element positionned relatively to an ancestor that is not positionned!
Related: Why does applying a CSS-Filter on the parent break the child positioning?
You must always set top:0; left:0; on absolutely-positioned elements (or whatever values you want for top, right, bottom, left).
First of all, the element is positioned relative to its first positioned (not static) ancestor element.
In this case, the position absolute works with the sibling, not with the ancestor.
About the ancestors and siblings, there are a godd documentation about it : Ancestors and siblings
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
If i put the element after the div container all works without problem
Documentation of postion
About the second part, that box appears there because the box-gery doesnt matter about the top and right of box-green, got it? Ill put an example:
.container {
background: lightblue;
position: relative;
}
.box-orange2 {
background: orange;
height: 100px;
width: 100px;
position: relative;
z-index: 2;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-yellow {
background: yellow;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange2"></div>
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-yellow"></div>
</div>
You can see that the grey and yellow boxes do not change the behavior even if the top and right are in the sibling or not.

How Position absolute removes element out of the natural flow of the document [duplicate]

I'm just learning the positioning in CSS. Based on the article that I've found useful, I'd started to playing around.
With the following code, I cannot understand why the absolute grey-box div is outside of it's relative parent. I expected that the grey-box will be on the top-left corner of the container.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Also can't understand in the following case why the grey-box not in the top-left corner, but moved after the empty space left by the orange-box there. I've just moved the grey-box to the second place inside the container div.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-grey"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
All the detailed documentation (e.g. MDN) and tutorials that I've found just demonstrating very simple examples with 2-3 boxes.
To correctly understand this, you need to refer to the official specification where you find the equation the element must satisfy:
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block
We don't have any border and padding so in your case it will simply be:
'top' + 'margin-top' + 'height' + 'margin-bottom' + 'bottom' = height of containing block
And if you read under you will find this:
'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'.
So in your case, you have set a height and kept top/bottom to auto thus top will be set to static position
..More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'..
To make it easy, it's the position of the element if you didn't set position:absolute.
Here is an easy illustration to better understand
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey">I am absolute</div>
</div>
Note the static position of the first element that is kept if we add position:absolute. We didn't specify any top value so the browser will use a default one that is the one of the position:static (default position) of the element.
If you don't want this, simply set the top value and you fall into this rule:
'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
top:0;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Same logic apply to the left property
You may also notice the use of the word containing block which very important here and explained in the same specification
The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:
...
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
...
And it's not enough as there is other properties (listed below) that also establish a containing block so you can have an element positionned relatively to an ancestor that is not positionned!
Related: Why does applying a CSS-Filter on the parent break the child positioning?
You must always set top:0; left:0; on absolutely-positioned elements (or whatever values you want for top, right, bottom, left).
First of all, the element is positioned relative to its first positioned (not static) ancestor element.
In this case, the position absolute works with the sibling, not with the ancestor.
About the ancestors and siblings, there are a godd documentation about it : Ancestors and siblings
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
If i put the element after the div container all works without problem
Documentation of postion
About the second part, that box appears there because the box-gery doesnt matter about the top and right of box-green, got it? Ill put an example:
.container {
background: lightblue;
position: relative;
}
.box-orange2 {
background: orange;
height: 100px;
width: 100px;
position: relative;
z-index: 2;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-yellow {
background: yellow;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange2"></div>
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-yellow"></div>
</div>
You can see that the grey and yellow boxes do not change the behavior even if the top and right are in the sibling or not.

Why position: absolute does not take my div out from the content flow? [duplicate]

I'm just learning the positioning in CSS. Based on the article that I've found useful, I'd started to playing around.
With the following code, I cannot understand why the absolute grey-box div is outside of it's relative parent. I expected that the grey-box will be on the top-left corner of the container.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Also can't understand in the following case why the grey-box not in the top-left corner, but moved after the empty space left by the orange-box there. I've just moved the grey-box to the second place inside the container div.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-grey"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
All the detailed documentation (e.g. MDN) and tutorials that I've found just demonstrating very simple examples with 2-3 boxes.
To correctly understand this, you need to refer to the official specification where you find the equation the element must satisfy:
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block
We don't have any border and padding so in your case it will simply be:
'top' + 'margin-top' + 'height' + 'margin-bottom' + 'bottom' = height of containing block
And if you read under you will find this:
'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'.
So in your case, you have set a height and kept top/bottom to auto thus top will be set to static position
..More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'..
To make it easy, it's the position of the element if you didn't set position:absolute.
Here is an easy illustration to better understand
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey">I am absolute</div>
</div>
Note the static position of the first element that is kept if we add position:absolute. We didn't specify any top value so the browser will use a default one that is the one of the position:static (default position) of the element.
If you don't want this, simply set the top value and you fall into this rule:
'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
top:0;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Same logic apply to the left property
You may also notice the use of the word containing block which very important here and explained in the same specification
The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:
...
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
...
And it's not enough as there is other properties (listed below) that also establish a containing block so you can have an element positionned relatively to an ancestor that is not positionned!
Related: Why does applying a CSS-Filter on the parent break the child positioning?
You must always set top:0; left:0; on absolutely-positioned elements (or whatever values you want for top, right, bottom, left).
First of all, the element is positioned relative to its first positioned (not static) ancestor element.
In this case, the position absolute works with the sibling, not with the ancestor.
About the ancestors and siblings, there are a godd documentation about it : Ancestors and siblings
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
If i put the element after the div container all works without problem
Documentation of postion
About the second part, that box appears there because the box-gery doesnt matter about the top and right of box-green, got it? Ill put an example:
.container {
background: lightblue;
position: relative;
}
.box-orange2 {
background: orange;
height: 100px;
width: 100px;
position: relative;
z-index: 2;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-yellow {
background: yellow;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange2"></div>
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-yellow"></div>
</div>
You can see that the grey and yellow boxes do not change the behavior even if the top and right are in the sibling or not.

position: fixed behaving like position: absolute [duplicate]

I'm just learning the positioning in CSS. Based on the article that I've found useful, I'd started to playing around.
With the following code, I cannot understand why the absolute grey-box div is outside of it's relative parent. I expected that the grey-box will be on the top-left corner of the container.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Also can't understand in the following case why the grey-box not in the top-left corner, but moved after the empty space left by the orange-box there. I've just moved the grey-box to the second place inside the container div.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-grey"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
All the detailed documentation (e.g. MDN) and tutorials that I've found just demonstrating very simple examples with 2-3 boxes.
To correctly understand this, you need to refer to the official specification where you find the equation the element must satisfy:
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block
We don't have any border and padding so in your case it will simply be:
'top' + 'margin-top' + 'height' + 'margin-bottom' + 'bottom' = height of containing block
And if you read under you will find this:
'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'.
So in your case, you have set a height and kept top/bottom to auto thus top will be set to static position
..More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'..
To make it easy, it's the position of the element if you didn't set position:absolute.
Here is an easy illustration to better understand
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey">I am absolute</div>
</div>
Note the static position of the first element that is kept if we add position:absolute. We didn't specify any top value so the browser will use a default one that is the one of the position:static (default position) of the element.
If you don't want this, simply set the top value and you fall into this rule:
'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
top:0;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Same logic apply to the left property
You may also notice the use of the word containing block which very important here and explained in the same specification
The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:
...
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
...
And it's not enough as there is other properties (listed below) that also establish a containing block so you can have an element positionned relatively to an ancestor that is not positionned!
Related: Why does applying a CSS-Filter on the parent break the child positioning?
You must always set top:0; left:0; on absolutely-positioned elements (or whatever values you want for top, right, bottom, left).
First of all, the element is positioned relative to its first positioned (not static) ancestor element.
In this case, the position absolute works with the sibling, not with the ancestor.
About the ancestors and siblings, there are a godd documentation about it : Ancestors and siblings
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
If i put the element after the div container all works without problem
Documentation of postion
About the second part, that box appears there because the box-gery doesnt matter about the top and right of box-green, got it? Ill put an example:
.container {
background: lightblue;
position: relative;
}
.box-orange2 {
background: orange;
height: 100px;
width: 100px;
position: relative;
z-index: 2;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-yellow {
background: yellow;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange2"></div>
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-yellow"></div>
</div>
You can see that the grey and yellow boxes do not change the behavior even if the top and right are in the sibling or not.

Why aren't my absolutely/fixed-positioned elements located where I expect?

I'm just learning the positioning in CSS. Based on the article that I've found useful, I'd started to playing around.
With the following code, I cannot understand why the absolute grey-box div is outside of it's relative parent. I expected that the grey-box will be on the top-left corner of the container.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Also can't understand in the following case why the grey-box not in the top-left corner, but moved after the empty space left by the orange-box there. I've just moved the grey-box to the second place inside the container div.
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange"></div>
<div class="box-grey"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
All the detailed documentation (e.g. MDN) and tutorials that I've found just demonstrating very simple examples with 2-3 boxes.
To correctly understand this, you need to refer to the official specification where you find the equation the element must satisfy:
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block
We don't have any border and padding so in your case it will simply be:
'top' + 'margin-top' + 'height' + 'margin-bottom' + 'bottom' = height of containing block
And if you read under you will find this:
'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'.
So in your case, you have set a height and kept top/bottom to auto thus top will be set to static position
..More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'..
To make it easy, it's the position of the element if you didn't set position:absolute.
Here is an easy illustration to better understand
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey">I am absolute</div>
</div>
Note the static position of the first element that is kept if we add position:absolute. We didn't specify any top value so the browser will use a default one that is the one of the position:static (default position) of the element.
If you don't want this, simply set the top value and you fall into this rule:
'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
.container {
background: lightblue;
position: relative;
padding:40px 20px;
display:inline-block;
vertical-align:top;
width: 250px;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
top:0;
}
.box-green {
height:20px;
background:green;
}
<div class="container">
<div class="box-green"></div>
<div class="box-grey" style="position:static;">I am static</div>
</div>
<div class="container">
<div class="box-green"></div>
<div class="box-grey"></div>
</div>
Same logic apply to the left property
You may also notice the use of the word containing block which very important here and explained in the same specification
The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:
...
If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
...
And it's not enough as there is other properties (listed below) that also establish a containing block so you can have an element positionned relatively to an ancestor that is not positionned!
Related: Why does applying a CSS-Filter on the parent break the child positioning?
You must always set top:0; left:0; on absolutely-positioned elements (or whatever values you want for top, right, bottom, left).
First of all, the element is positioned relative to its first positioned (not static) ancestor element.
In this case, the position absolute works with the sibling, not with the ancestor.
About the ancestors and siblings, there are a godd documentation about it : Ancestors and siblings
.container {
background: lightblue;
position: relative;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-blue"></div>
<div class="box-green"></div>
</div>
If i put the element after the div container all works without problem
Documentation of postion
About the second part, that box appears there because the box-gery doesnt matter about the top and right of box-green, got it? Ill put an example:
.container {
background: lightblue;
position: relative;
}
.box-orange2 {
background: orange;
height: 100px;
width: 100px;
position: relative;
z-index: 2;
}
.box-orange {
background: orange;
height: 100px;
width: 100px;
position: relative;
top: 100px;
left: 100px;
z-index: 2;
}
.box-blue {
background: lightskyblue;
height: 100px;
width: 100px;
/*position: static;*/
}
.box-green {
background: lightgreen;
height: 100px;
width: 100px;
position: relative;
top: -105px;
left: 105px;
z-index: 2;
}
.box-grey {
background: grey;
height: 100px;
width: 100px;
position: absolute;
}
.box-yellow {
background: yellow;
height: 100px;
width: 100px;
position: absolute;
}
<div class="container">
<div class="box-orange2"></div>
<div class="box-grey"></div>
<div class="box-orange"></div>
<div class="box-yellow"></div>
</div>
You can see that the grey and yellow boxes do not change the behavior even if the top and right are in the sibling or not.