How position absolute and fixed block elements get their dimension?
Here is the Specification detailing how you can find the width/height of any element: https://www.w3.org/TR/CSS21/visudet.html
From there you can read for absolute element that:
The constraint that determines the used values for these elements is:
'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block
Then
If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
And the rule number three:
'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
The rule number one is also similar
And if you continue reading you will find how to calculate the shrink-to-fit width. You will also notice that the same shrink-to-fit algorithm apply to float
and inline-block
element
Also note that fixed element is a particular case of absolute so the same rule applies. The only difference is the containing block
Fixed positioning is a subcategory of absolute positioning. The only difference is that for a fixed positioned box, the containing block is established by the viewport. ref
You can also see that block elements follow almost the same constraint (without left/right) but the rules are different:
The following constraints must hold among the used values of the other properties:
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
Then
If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
This will make width = width of containing block
An important difference between inline-block element is that absolute element will not take the width of their content like we may think. This happen in most of the case due to the constraint explained above but check the below example:
.container {
clear:left;
margin:5px;
}
<div class="container" style="float:left;position:relative;">
<div style="display:inline-block; background: red;"> 1 1 1 1 1 1 </div>
</div>
<div class="container" style="float:left;position:relative;">
<div style="position: absolute; background: red;"> 1 1 1 1 1 1 </div>
</div>
Do fixed and absolutely positioned elements not take the full width of their container like block elements? If yes then why?
This question could have different possible answers depending on what kind of block
behavior you're expecting or referring to.
As per your comment above, the following answer refers to the width
behaviour of such element.
Normally, block
-level elements per default take up the full available width of their container element. However, when you set position: fixed
or absolute
the element isn't displayed in the same sense as with the rest of the elements.
As per MDN:
A block-level element occupies the entire space of its parent element (container), thereby creating a "block."
As such, the meaning of the container for a block
-level element makes alters when refering to absolute
or fixed
positioned elements. It makes more sense to rather call it the parent.
Since there is no container element to inherit its width, you're seeing it behave more like an inline-block
-type element.
Here's what the W3C says for calculating the width of an absolutely positioned, non-replaced element:
The constraint that determines the used values for these elements is:
left
+margin-left
+border-left-width
+padding-left
+width
+padding-right
+border-right-width
+margin-right
+right
= width of containing block.If all three of
left
,width
, andright
areauto
: First set anyauto
values formargin-left
andmargin-right
to 0. Then, if thedirection
property of the element establishing the static-position containing block isltr
setleft
to the static position and apply rule number three below;
This is true. You have not defined any values for width
, left
nor right
nor do they inherit such values. As such they take the default auto
. The direction
property is indeed ltr
as well, so we continue on to rule number three as suggested, which says:
width
andright
areauto
andleft
is notauto
, then the width is shrink-to-fit . Then solve forright
.
The shrink-to-fit width rule applies, and goes as follows:
Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, calculate the available width: this is found by solving for
width
after settingleft
(in case 1) orright
(in case 3) to 0.Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
Why are fixed and absolute positioned elements considered block formatting context, but not a relatively positioned elements?
I would say because position:relative
doesn't change the behavior of the element like absolute
and fixed
will do. When setting an element with absolute
and fixed
, it will get removed from the flow. It's like you remove a fragment of the page to make it independent thus it need to establish a new block formatting contexts.
Whith position:relative
it's different.
Once a box has been laid out according to the normal flow or floated, it may be shifted relative to this position. This is called relative positioning.
then
A relatively positioned box keeps its normal flow size, including line breaks and the space originally reserved for it.ref
Basically, position:relative
will keep the behavior of the element and will simply allow you to shift its position after being placed in the normal flow. You need to check the other properpties to see if the element will establish a BFC or not.
You may also note that positon:relative
apply to inline element and inline element should not establish a BFC.
Does position absolute make that element a containing block?
We establish that #strong1
is a non-positioned inline box. Therefore, from the spec,
[...] if the element's position is 'relative' or 'static', the containing block is formed by the content edge of the nearest block container ancestor box.
When #em1
is not absolutely positioned, it remains an inline box. The nearest block container ancestor box to #strong1
is #p2
, therefore #p2
is its containing block.
When #em1
is absolutely positioned, it turns into a block box as shown in section 9.7. This makes it the nearest block container ancestor box to #strong1
, therefore #em1
becomes its containing block. A block box is defined as a block-level block container box.
So does absolute positioning cause an element to establish a containing block for relatively positioned or non-positioned boxes? Yes, but only when absolute positioning results in the element's box becoming the nearest block container ancestor of those boxes.
Note that this is a rather simplified case, since the only boxes in #em1
are inline boxes (including the two anonymous inlines surrounding #strong1
). Besides the fact that not all block-level boxes are block containers (tables being a common example of a block-level box that's not a block container box), even if absolute positioning does result in an element generating a block box, since we're talking about an inline box here, it may very well be that the inline box's block container is an anonymous block box within the absolutely positioned element, if that element happens to contain a mix of both block-level and inline-level boxes. This complicated case is detailed in section 9.2.1.1.
But the complications don't stop there. The reason I say "it may very well be" is because whether or not an anonymous block box is capable of establishing a containing block isn't defined in CSS2.1.
Related Topics
Embed Youtube Code Is Not Working in HTML
Insert HTML with Scripts That Should Run
Where Is The Default Size of a Div Element Defined or Calculated
Word Wrap a Link So It Doesn't Overflow Its Parent Div Width
Default Width/Height of an Iframe
How to Change Border Color of Textarea on: Focus
Changing Image Src Depending on Screen Size
CSS Selector for No-Children-But-Not-Empty
How to Remove X and Y on Submit in HTML Form with Image Type Button
Click Link Below a Higher Z-Index Div
Bootstrap 3 Grid, Does It *Really* Matter How Many Columns Are in a Row
Is The Marquee HTML Element Supported by All Browsers Yet
How to Set The Background Color of <Option> in a <Select> Element
How to Avoid Ie8 Compatibility Button
How to Check If The Browser Can Play Mp4 via HTML5 Video Tag
What Are All The Differences Between Src and Data-Src Attributes