本片来简单探讨以下CSS的布局。

所谓布局,是一个过程。简单的说,就是决定HTML元素在浏览器的视界(viewport)内的排列位置。浏览器解析完一个HTML页面之后,按层级以及出现的先后次数,HTML页面中的元素被组织称一个树状结构。当需要在视界中显示这些HTML元素时,浏览器会对树形结构中的元素进行深度优先遍历,先遍历到的元素会被先排布到视界中,占据一块矩形空间(box)。由于是深度遍历,子元素优先于父元素被访问,所以父节点的大小通常是由子元素决定出来的。

下面是一个示例:

<style type="text/css">
.container {
  background: #808080;
}
.bluebox {
  padding: 5px;
  border: 5px solid blue;
}
.greenbox {
  border: 5px solid green;
}
.yellowbox {
    border: 5px solid yellow;
}
.redbox {
  border: 5px solid red;
}
.maroonbox {
  border: 5px solid maroon;
}
.blackbox {
  border: 5px solid black;
}
.container span {
  color: white;
}
</style>
<div class="container">
  <div class="bluebox">
    <span class="greenbox">  greenbox </span>
    <span class="yellowbox"> yellowbox </span>
  </div>
  <div class="maroonbox">
    <span class="redbox"> redbox </span>
  </div>
</div>

上面的例子的渲染结果是:

在布局的时候,HTML元素基本上被分为两类,一类是块(block)元素,另一类是行内(inline)元素。块元素和行内元素的区别是,块元素需要单独占据一整行,而行内元素则可以和其他行内元素在同一行上。<div>是一个最常见的块元素,所以上面例子中<div class="bluebox"><div class="maroonbox">在上下行显示。<span>则是行内元素,所以<span class="greenbox"><span class="yellowbox">在同一行显示。

我们把以上通过遍历HTML树而产生布局的过程叫做正常排布(normal fow)。在正常排布中,元素的排布取决于它在HTML树中出现的位置,有时候这不是我们想要的结果。幸好我们有CSS,可以在这正常排布之外做一点手脚。

浮动排布(float)

首先要谈到的是CSS的浮动排布。简单的说,浮动排布的意思是把需要排布的元素预先排除在正常排布之外。看个例子:

<div class="container">
  <div class="bluebox">
    <span class="greenbox">  greenbox </span>
    <span class="yellowbox" style="float:right"> yellowbox </span>
  </div>
  <div class="maroonbox">
    <span class="redbox"> redbox </span>
  </div>
</div>

我们通过设置CSS的float属性:<span class="yellowbox" style="float:right">,把yellowbox浮动到了右边。

float属性的值可以设为左(left)或者右(right)。当一个HTML元素的float属性被设置之后,可以看成这个元素被排除在正常排布之外了。可以这么解读上面的例子:把yellowbox浮动到右边,并把扣掉yellowbox所占的区域,在剩下的区域中继续进行正常排布

浮动排布的一个经典应用是:

上面的Lorem Ipsum被设为左浮动,其他文字能够环绕Lorem Ipsum进行排布。如果Lorem Ipsum不是左浮动,则效果是这样的:

浮动排布大有用处,Shay Howe的Detailed Positioning教程提到的第一个示例就是和浮动排布(float)的。

清除浮动排布(clear)

有例外,就有反例外。浮动元素是一种正常排布的例外,那有些正常排布的元素不想和浮动元素在同一行的话,就得使用清除(clear)属性。对于上面的文字环绕的例子,我们可以把Lorem Ipsum之后的文字封在一个<p style="clear:both">标签之中。因为<p>是块元素,所以整体的效果是Lorem Ipsum之后的文字另起一行单独显示。

处理溢出的浮动元素

因为浮动元素在正常排布之前铺设,所以浮动元素的大小不算在其父元素的大小内。这就会导致一种情况的发生,如果浮动元素的高度比包含它的父元素的高,那么浮动元素就会溢出到包含它的父元素之外。一个解决的办法是把父元素的overflow设置为auto,这样浏览器会自动改变父元素的大小来适应浮动元素。

position属性

在进行完正常排布或者浮动排布之后,就该position属性登场了。它有以下可设置值:

  • static
  • relative
  • absolute
  • fixed

默认是static,也就是不改动正常排布或者浮动排布的结果。如果把值改为relative,那么在正常排布或者浮动排布之后,根据top、right、bottom、left这四个属性的值,可以对元素可以进行移位。

<div class="container">
  <div class="bluebox">
    <span class="greenbox" style="position:relative;top:20px">  greenbox </span>
    <span class="yellowbox" style="float:right;position:relative;top:-20px"> yellowbox </span>
  </div>
</div>

上面的例子中,greenbox和yellowbox的position都设成relative,并且greenbox的top属性设为20px,所以它跟原来的位置相比,向下偏移了20px;而yellowbox的top属性设为-20px,所以它向上移位了20px。

position的absolute值和fixed值的移位原理和relative是一样的,只不过它们选取的锚点不一样,这里就不在赘述了。

其他请参考

(完)