Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't top: 0 work on absolutely-positioned elements relative to body?

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

like image 238
CroaToa Avatar asked Nov 08 '15 14:11

CroaToa


People also ask

What happens when an element is positioned absolutely?

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.

What does an absolute positioned element use if it has no positioned ancestors?

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.

When using position fixed What will the element always be positioned relative to?

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.

What does top 0 do in CSS?

top: 0; If the element is in position absolute, the element will position itself from the top of the first positioned ancestor.


1 Answers

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 XHTML html 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 HTML BODY or XHTML body 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 the BODY element rather than the HTML 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>
like image 139
BoltClock Avatar answered Sep 20 '22 05:09

BoltClock