CSS布局之谜

时间:2010-05-16 00:09:47

标签: css layout

在众多两(或三)列布局技术中,我有时会使用以下方法:

<div class="left1">
  <div class="left2">
    left main content
  </div>
</div>
<div class="right1">
  <div class="right2">
    right sidebar
  </div>
</div>

与:

.variant1 .left1 {
  float: left;
  margin-right: -200px;
  width: 100%;
}
.variant1 .left1 .left2 {
  margin-right: 200px;
}
.variant1 .right1 {
  float: right;
  width: 200px;
}

这适用于所有主流浏览器。但是由于一些非常奇怪的原因,相同的技术但反转不起作用

.variant2 .left1 {
  float: left;
  width: 200px;
}
.variant2 .right1 {
  float: right;
  margin-left: -200px;
  width: 100%;
}
.variant2 .right1 .right2 {
  margin-left: 200px;
}

在第二个版本中,无法选择侧边栏中的所有文字,并且无法点击所有链接。对于Firefox和Chrome,这至少是正确的。在IE7中,链接至少可以被点击,Opera似乎完全正常。

有谁知道这种奇怪行为的原因?这是一个浏览器错误吗?

请注意:我正在寻找一个工作的两列CSS布局技术,我知道它们有很多。而且我不一定需要这种技术才能工作。我只想理解为什么第二个变体的行为与它一样。

以下是指向应该说明问题的小型测试页的链接:http://selfthinker.org/stuff/css_layout_mystery.html

1 个答案:

答案 0 :(得分:1)

这是一个基本的分层问题。让我们解析visual formatting上的CSS规范,找出原因。

  

渲染树在画布上绘制的顺序是根据堆叠上下文来描述的。

好的,让我们看看我们所处的“堆叠上下文”。为此,我们需要知道何时创建新的堆叠上下文。

  

[一个z的索引值] ...整数是当前堆叠上下文中生成的框的堆栈级别。该框还建立了一个本地堆栈上下文,其堆栈级别为“0”。

好吧,我们没有任何z-index值 - 所以它们都是自动的。

  

根元素形成根堆叠上下文。其他堆叠上下文由任何定位元素(包括相对定位的元素)生成,其计算值为'z-index'而不是'auto'。

不,也没有定位元素。看起来我们都处于“根堆叠环境”中。

  

堆叠上下文中具有相同堆栈级别的框根据文档树顺序从前到后堆叠。

这肯定解释了为什么.right1描绘了.left1 - 它是在源顺序之后。 (请注意,如果您从margin-left: 200px删除了.right2,则会更好地看到修补过滤问题。

所以,现在我们知道了问题(并且它是根据规范) - 我们如何解决它?最简单的方法是让.left1的z-index高于.right1。由于它们处于相同的堆叠上下文中,因此较高的z-index将覆盖源顺序:

.variant2 .left1 { position: relative; z-index: 1; }

或者,如果我们继续阅读规范 - 我们会注意到:

  

每个堆叠上下文包含以下堆叠级别(从后到前):

     
      
  • 构成堆叠背景的元素的背景和边框。
  •   
  • 具有负堆栈级别的后代的堆叠上下文。
  •   
  • 堆叠级别包含流入的非内联级别的非定位后代。
  •   
  • 非定位浮标及其内容的堆叠级别。
  •   
  • 流入式内联级非定位后代的堆叠级别。
  •   
  • 具有'z-index:auto'的已定位后代的堆叠级别,以及具有'z-index:0'的任何后代堆叠上下文。
  •   
  • 具有正堆栈级别的后代的堆叠上下文。
  •   

这意味着我们实际上可以这样做:

.variant2 .left1 { position: relative; }

这将使.left1的“堆叠级别”为6 - 这将覆盖.right1的堆叠级别为4。