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.
...
- '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.
这肯定是由于 body
和 div#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
(根元素)。
给定:
<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.
...
- '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.
这肯定是由于 body
和 div#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
(根元素)。