CSS position:fixed 没有顶部会给出意想不到的布局?

CSS position:fixed without top gives unexpected layout?

给定:

   <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>

并且:

* { 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;
}     

注意 position:static,这给出了预期的结果 (fiddle):

但是,将 position:static 更改为 fixed,您会得到这个 (fiddle)

即使 #fixed div 不在 #nonfixed 内,它也占据了 #nonfixed 的上边距。 Chrome 和 Firefox 都会发生这种情况。奇怪的是,两个浏览器中的开发工具都没有显示 #fixed div 有任何边距,所以很明显它的位置就像固定在 里面 #nonfixed div.

如果我将 top:0 添加到 #fixed 规则集,div 会回到 window 的顶部,但这不应该出现在顶部 (即在没有 top 规范的情况下它在正常流程中的位置,但不影响其他元素?

为了完整性:position:relative 产生与 static 相同的结果,absolute 看起来与 fixed 相同。

我在规范中找不到任何内容直接说明为什么绝对定位元素应该相对于后续兄弟元素定位。事实上,阅读我发现的规范(强调我的):

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.

...

  1. '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'

这似乎表明 #fixed 框确实应该位于视口的顶部。

因为 FF 和 Chrome 做同样的事情我猜它应该以这种方式工作,但我想知道为什么。谁能根据规范解释这种行为?

您会注意到 "fixed" div 实际上位于 body 的顶部,其位置和大小与 "nonfixed" div.

这肯定是由于 bodydiv#nonfixed 的顶部边距坍塌所致。参见 http://www.w3.org/TR/CSS21/box.html#collapsing-margins

8.3.1 Collapsing margins

In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

(...)

Two margins are adjoining if and only if:

  • both belong to in-flow block-level boxes that participate in the same block formatting context
  • no line boxes, no clearance, no padding and no border separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
  • both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
    • top margin of a box and top margin of its first in-flow
    • (...)

top是相对于包含块的,显然不是body而是html(根元素)。