一个相对定位的div覆盖在一个浮动的div上。

5

我不理解为什么float right或left的div在最后一个div被声明且具有相对位置或定义了背景颜色时,不会在其上方。

以下是HTML代码:

<html>
<body>
    <div class="container">
        Main container <br/><br/>

        <div class="header">This is the header</div>
        <div class="text-right">Right text</div>
        <div class="footer">This is the footer</div>
    </div>
</body>

以下是CSS代码:

.header {
    background-color:blue;
    border: solid;
    color: white;
    border-color:black;
    height: 100px;
}

.text-right{
    float: right;   
    border: solid;
    background-color: green;
}

.container{
    padding: 10px;  
    border: solid;
}

.footer{
    padding-top: 50px;
    border: solid;
    background-color: yellow;
    position: relative;
}

我知道我可以使用.clear: both规则来解决这个问题,但我的主要观点是:为什么当我在 .footer 规则中设置背景颜色或位置或两者都设置时,浮动div会在页脚下面呢?
非常感谢!

这里有一个极简的JSFiddle示例,展示了同样的问题:http://jsfiddle.net/5Kefa/5/ - KajMagnus
3个回答

6
在阅读这篇非常好的文章时,在文章结尾处,作者谈到了z-order内部工作原理,但也说如果想了解更多,下一篇文章将是一个更详细的文章
关键点在于元素放置在z轴中的顺序。
以下是作者的话:

If we do not specify any z-index values, the default stacking order from closest to the user to furthest back is as follows:

1. Positioned elements, in order of appearance in source code
2. Inline elements
3. Non-positioned floating elements, in order of appearance in source code
4. All non-positioned, non-floating, block elements in order of source code
5. Root element backgrounds and borders
正如我们所看到的,定位元素(1)始终位于未定位元素(3-4)之上。如果我只是给一个带有float属性的div,这个元素将不会"定位"到表面。
在这种情况下,使用相对属性值定位的第二个元素,即页脚div,将位于前一个元素的顶部,不仅因为我没有在float div属性后添加clear: both属性,也不仅因为最后一个元素是在浮动元素之后添加的,而是因为它是定位的!
像powerbuoy说的那样,你必须为浮动元素设置相对位置,才能使其置于浮动元素堆栈的顶部。但这还不够。因为这两个元素现在处于同一级别,并且它们都彼此交叉,所以你必须告诉引擎哪个元素将是第一个,这就是为什么你必须再次将z-order设置为1以浮动元素,就像powerbuoy所说的那样。
我不是一个很好的作家,因此我强烈建议你阅读我之前提到的参考文章。我认为你将会得到一个非常深入的解释。

很抱歉要接受自己的问题,但我认为这是正确的答案,没有人提出反对意见。 - Samuel
考虑http://jsfiddle.net/wxMhx/。如果您将`id = text-right添加position:relative;,则id = footer仍会出现在text-right上方。尽管浮动元素现在具有position:relative,因此浮动元素和id = footer都被定位。所以规则1应该适用?-- **但是**浮动元素首先出现在源中,因此根据您的示例,它应该被堆叠在id = footer之上(根据规则1),为什么id = text-right仍然被footer`隐藏,很奇怪。(这是在删除z-index规则的情况下)(Google Chrome 19) - KajMagnus
也许在1、2、3、4、5列表中应该再加入另一个条目,指定浮动和定位元素应该放置在哪里。我认为规则1实际上并不适用于它们。 - KajMagnus
我认为这篇博客文章的作者(http://timkadlec.com/2008/01/detailed-look-at-stacking-in-css/)可能犯了一个错误,或者至少表述不够清晰。如果你阅读W3C规范,http://www.w3.org/TR/CSS21/zindex.html,你会注意到对应于规则1的实际上是:“*所有定位后代元素,其z-index属性值为auto或0,按树形顺序排列*”。但这是物品应该被*绘制*的顺序,也就是说,在源代码中出现较晚的东西应该被绘制在比先前出现的东西*上面*--而在源代码中,“text-right”出现在“footer”之前。 - KajMagnus
然而,如果您按原样阅读规则1(“按源代码中出现的顺序排列的定位元素”),这会让我觉得在源代码中首先出现的东西应该堆叠在稍后出现的东西之上。但根据W3C规范,情况应该相反,即在源代码中稍后出现的东西会被绘制在早期兄弟元素之上。 - KajMagnus
显示剩余4条评论

1

由于页脚在 text-right 之后,因此它将呈现在 text-right 的顶部。为避免这种情况,您可以给 text-right 设置一个 z-index(和非 static 的位置):

http://jsfiddle.net/wxMhx/

编辑:嗯...不完全正确。如果从页脚中删除position: relative;,text-right将被渲染在其上方。说实话,我不确定为什么会发生这种情况。但无论哪种情况,解决方案都是从页脚中删除position: relative;或者将其添加(以及z-index)到text-right。


谢谢您的时间...我在网上阅读了很多内容,发现了这句话:“因此,行为旨在首先将其浮动,并影响该位置中的其他元素,然后再将其移动到新的移位位置,而不再次影响其他元素的位置。”根据您所说的,我的理解是当您放置一个带有相对位置的浮动div,后面跟着另一个div时,如果设置了背景颜色,则后者将隐藏前者。这是常见情况还是我弄错了什么? - Samuel
即使没有背景图片,text-right 仍然在 footer 后面,但它仍然可见,因为它顶部没有渲染的内容。我认为 position: relative 触发了分层。但是我不知道为什么,我很想知道。 - powerbuoy

0

因为 position: relative。如果删除此行,您将看到带有 text-right 类的 div。您可以将 z-index:-1; 设置为 footer 类,这也应该有效。


谢谢,但是正如我在问题中所说的那样,我想知道为什么会发生这种情况,而不是如何纠正问题。 - Samuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接