You can see in the code below that the h1
pushes down the body and the absolutely-positioned block .absolute
does not stick to the top. But you also can see that the same block is stuck to the top of its parent .wrapper
. Why?
I'm not asking how to do that trick; I know how, e.g. padding instead margin to h1, or clearfix to parent and so on.
I'm interested in only one thing: why h1
's margin pushes down the body
, but is not pushing down .wrapper
?
body {
position: relative;
margin: 0;
padding: 0;
overflow: hidden;
background-color: silver;
}
.absolute {
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
background-color: darkblue;
}
.wrapper {
position: relative;
overflow:hidden;
width: 50%;
height: 200px;
overflow: hidden;
background-color: yellow;
}
.wrapper > .absolute {
background-color: darkcyan;
}
<div class="absolute"></div>
<h1>Some title</h1>
<div class="wrapper">
<div class="absolute"></div>
<h1>Some title</h1>
</div>
OK, I'll try to be more clear. If you click on the link below, you can see my JSFiddle. There is background-color: silver
in the body
tag. When I look in the code inspector, I see that the body tag begins slightly lower due to the h1 margin. But background-color
begins at the top. This means that the code inspector is lying to me, and body begins from top. But why, then, does an absolutely-positioned element that's a direct child of body
not start at the top?
JSFiddle
Absolutely positioned elements are removed entirely from the document flow. That means they have no effect at all on their parent element or on the elements that occur after them in the source code.
position: absolute; However; if an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling. Note: Absolute positioned elements are removed from the normal flow, and can overlap elements.
Fixed positioning This can be used to create a "floating" element that stays in the same position regardless of scrolling. In the example below, box "One" is fixed at 80 pixels from the top of the page and 10 pixels from the left. Even after scrolling, it remains in the same place relative to the viewport.
top: 0; If the element is in position absolute, the element will position itself from the top of the first positioned ancestor.
As mentioned, the containing block of the top-level absolutely positioned element is body
, as body
is relatively positioned. When the margin of the h1
collapses with that of body
, this causes the margin to affect body
, and in turn the absolutely positioned element that it contains. Conversely, if body
wasn't relatively positioned, the absolutely positioned element would be anchored to the initial containing block, and stick to the top of the viewport unaffected by any effective margins on body
(because body
is no longer its containing block).
As to why the silver background bleeds beyond the body
element, that's by design:
3.11.1. The Canvas Background and the Root Element
The background of the root element becomes the background of the canvas and its background painting area extends to cover the entire canvas. However, any images are sized and positioned relative to the root element as if they were painted for that element alone. (In other words, the background positioning area is determined as for the root element.) The root element does not paint this background again, i.e., the used value of its background is transparent.
3.11.2. The Canvas Background and the HTML <body> Element
For documents whose root element is an HTML
HTML
element or an XHTMLhtml
element: if the computed value of ‘background-image’ on the root element is ‘none’ and its ‘background-color’ is ‘transparent’, user agents must instead propagate the computed values of the background properties from that element's first HTMLBODY
or XHTMLbody
child element. The used values of that BODY element's background properties are their initial values, and the propagated values are treated as if they were specified on the root element. It is recommended that authors of HTML documents specify the canvas background for theBODY
element rather than theHTML
element.
The root element's default background color is always transparent
, so setting a background color on the html
element prevents the silver background from bleeding out of the body
element (and you'll see that the inspector is in fact not lying to you):
html {
background-color: white;
}
body {
position: relative;
margin: 0;
padding: 0;
overflow: hidden;
background-color: silver;
}
.absolute {
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
background-color: darkblue;
}
.wrapper {
position: relative;
overflow:hidden;
width: 50%;
height: 200px;
overflow: hidden;
background-color: yellow;
}
.wrapper > .absolute {
background-color: darkcyan;
}
<div class="absolute"></div>
<h1>Some title</h1>
<div class="wrapper">
<div class="absolute"></div>
<h1>Some title</h1>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With