本片来简单探讨以下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是一样的,只不过它们选取的锚点不一样,这里就不在赘述了。
其他请参考
- Shay Howe的Detailed Positioning教程(英文)
- How Browser Works #CSS2 visual model
- Learn CSS Layout
- http://htmlreference.io/
- http://cssreference.io
(完)