Given:
<body>
<div id="fixed">
Fixed div
</div>
<div id="nonfixed">
<p>Non-fixed div</p>
<p>Non-fixed div</p>
<p>Non-fixed div</p>
</div>
</body>
And:
* { box-sizing: border-box; }
body {
margin: 0;
padding: 0;
}
#fixed {
position: static;
width: 100%;
border: 3px solid #f00;
}
#nonfixed {
margin-top: 50px;
border: 3px solid #00f;
}
Note that position:static
, this gives the expected result (fiddle):
However, change position:static
to fixed
, and you get this (fiddle)
Even though the #fixed
div is not inside #nonfixed
, it has taken on the top margin of #nonfixed
. This happens in both Chrome and Firefox. Curiously, the dev tools in both browsers do not show the #fixed
div having any margins, so clearly it's being positioned as if it was fixed inside the #nonfixed
div.
If I add top:0
to the #fixed
ruleset the div goes back to the top of the window, but shouldn't this appear at the top (i.e. where it would in normal flow, but without affecting other elements) in the absence of a top
specification?
For completeness: position:relative
produces the same result as static
and absolute
looks the same as fixed
.
I cannot find anything in the spec that directly addresses why an absolutely positioned element should be positioned relative to a subsequent sibling. In fact, reading the spec I find (emphasis mine):
10.6.4 Absolutely positioned, non-replaced elements
...
If all three of 'top', 'height', and 'bottom' are auto, set 'top' to the static position and apply rule number three below.
...
- 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
This seems to indicate the #fixed
box should indeed be at the top of the viewport.
Since both FF and Chrome do the same thing I'm guessing it's supposed to work this way, but I'd like to know why. Can anyone explain this behavior in terms of the spec?