定位
定位部分包含了两个模型:视觉格式化模型和定位模型。理解这两个模型的细微差异是非常重要的,因为它们一起控制着如何在页面上布置每个元素。
/**********视觉格式化模型***************/
p、h1、div等元素常常被称为块级元素,与此相反,strong和span等元素称为行内元素。块级元素显示为一块内容,即“块框”,它们显示为一块内容。行内元素显示在一行上。
display属性可以改变元素的显示类型,通过将display设置为block,可以让行内元素表现的像块级元素一样,然而将display设置为none,让生成的元素根本没有框,这样,这个框及其内容就不再显示,不占用文档中的空间。
CSS中有三种基本的定位机制:普通流、浮动和绝对定位。除非专门制定,否则所有框都在普通流中定位。
块级框从上到下一个接一个的排列,框之间的垂直距离由框的垂直空白边计算出来。
行内框在一行中水平布置。可以使用水平填充、边框和空白边调整它们的水平间距(如下图)。但是垂直填充、边框和空白边不会影响行内框的高度。由一行形成的水平框称为行框,行框的高度总是足以容纳它包含的所有行内框。但是,设置行高可以增加这个框的高度。

框可以按照(X)HTML元素的嵌套方式包含其他框。大多数框由显示定义的元素组成。但是,在一中情况下,即使没有进行显示定义,也会创建块级元素。这种情况就是把一些文本添加到一个块级框(比如div)的开头。即使没有把这些文本定义为段落,它也会被当做段落对待:
1 <div> 2 some text 3 <p>Some more text</p> 4 </div>
这种情况下,这个框称为无名块框,因为它不与专门定义的元素相关联。
块级元素内的文本行也会发生类似的情况,假设有一个包含三行文本的段落。每行文本形成一个无名行框。
/**********视觉格式化模型***************/
/**********相对定位***************/
相对定位是一个非常容易掌握的概念,如果对一个元素进行相对定位,它将出现在它所出现的位置上。然后,可以通过设置垂直或水平位置,让这个元素“相对于”它的起点开始移动。如果将top设成20像素,那么框将出现在原位置顶部的下面20像素的地方。如果将left设成20像素,那么会在元素左边创建20像素的空间,也就是将元素向右移动。如图

在使用相对定位时,无论是否进行移动,元素仍然占据原来的空间。因此,移动元素会导致它覆盖其他框。
/**********相对定位***************/
/**********绝对定位***************/
相对定位实际上被看做普通流定位模型的一部分,因为元素的位置相对于它在普通流中的位置。与之相反,绝对定位使元素的位置与文档流无关,因此不占据空间。普通文档流中的其他元素的布局就好像绝对定位的元素不存在一样。如下图:

绝对定位元素的位置相对于最近的已定位的祖先元素,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块。根据用户代理的不同,最初的包含块可能是画布或HTML元素。
与相对定位一样,绝对定位的框可以从它的包含块向上、下、左、右移动,可以直接将元素定位在页面的任何位置,这提供了很大的灵活性。
因为绝对定位的框与文档流无关,所以它们可以覆盖页面上的任何元素。可以通过设置z-index属性来控制这些元素的堆放次序。z-index值越高,框在堆中的位置就越高。
ps:相对于相对定位的祖先元素对绝对定位的元素进行定位,这在大多数浏览器中都实现的很好,但是,windows上的IE 5.5 和 IE 6 有一个BUG。如果试图相对于相对定位的框的右边或底边设置绝对定位的框的位置,那么需要确保相对定位的框已经设置了尺寸。如果没有,那么IE会相对于画布定位这个框。简单的解决方案是为外面相对定位的框设置宽度和高度,从而避免这一问题。
/**********绝对定位***************/
/**********固定定位***************/
固定定位是绝对定位的一个子类别。差异在于固定定位的元素的包含块是视口。这使我们可以创建出总是出现在窗口相同位置的浮动元素。不幸的是IE 6和更低版本不支持固定定位。可以使用Javascript修复这个问题。
/**********固定定位***************/
/**********浮动***************/
最后一种定位模型是浮动模型。浮动的框可以左右移动,直到它的边缘碰到包含框或另一个浮动框的边缘。因为浮动框不在文档的普通流中,所以文档流中的普通块框表现的就像浮动框不存在一样。
如图所示,当把框1向右浮动时,它脱离文档流并且向右移动,直到它的右边缘碰到包含框的右边缘。

当把框1向左浮动时,它脱离文档流并且向左移动,直到它的左边缘碰到包含框的左边缘,因为它不再处于文档流中,所以它不占据空间,实际上覆盖了框2,使框2从视图中消失。如果把三个框都向左浮动,那么框1向左浮动直到碰到包含框,其他框向左移动直到碰到前一个浮动框。

如果包含框太窄,无法容纳水平排列的三个浮动元素,那么其他浮动框向下移动,直到有足够空间的地方。如果浮动元素的高度不同,那么当它们向左浮动时可能会被其他浮动元素“卡住”。

/**********浮动***************/
/**********行框和清理***************/
浮动框旁边的行框被缩短,从而给浮动框留出空间,行框围绕浮动框。实际上,创建浮动框使文本可以围绕图像。

要想阻止行框围绕在浮动框的外边,需要对这个行框应用clear,clear属性的值可以使left,right,both 和 none,它表示框的哪边不应该挨着浮动框。为了实现这种效果,在被清理元素的顶空白边上增加足够的空间,使元素的顶边缘垂直下降到浮动框的下面,如下图:

浮动元素脱离了文档流,不影响周围的元素,但是,对元素进行清理实际上是为前面的浮动元素流出了足够的垂直空间。
这是一个有用的布局工具,它让周围的元素为浮动元素留出空间。这解决了前面看到的绝对定位的问题,也就是垂直高度的改变不影响周围的元素,从而破坏了设计。
例子:假设有一个图片,希望它浮动到一个文本块的左边,希望将这个图片和文本包含在另一个具有背景颜色和边框的元素中。你可能会编写以下代码:
.news { background: gray; border: solid 1px black; } .news img { float: left; } .news p { float: right; } <div class="news"> <img src="new-pic.jpg" /> <p>Some text</p> </div>
但是由于浮动元素脱离了文档流,所以包含图片和文本的div不占据空间,如何让div在视觉上包围浮动元素呢?需要在这个div的内部某个地方应用clear。

因为浮动元素不占据空间,所以容器元素不包围它们。添加一个进行清理的空元素可以迫使容器元素包围浮动元素。清理元素可以使用一个空的div元素实现,为它添加clear:both样式。
.news { background: gray; border: solid 1px black; } .news img { float: left; } .news p { float: right; } .clear { clear: both; } <div class="news"> <img src="new-pic.jpg" /> <p>Some text</p> <div class="clear"></div> </div>
这会实现我们需要的效果,但是要添加不必要的代码。常常有元素可以应用clear,但是有时候不得不为了进行布局而添加无意义的标记。
还可以不对浮动的图像和文本进行清理,而是对容器div进行浮动。
.news { background: gray; border: solid 1px black; float: left; } .news img { float: left; } .news p { float: right; } <div class="news"> <img src="new-pic.jpg" /> <p>Some text</p> </div>
这也会产生我们想要的效果,但是下一个元素会受到这个浮动元素的影响,为了解决这个问题,有些人选择对布局中的几乎所有东西进行浮动,然后使用适当的有意义的元素(通常是站点的页脚)对这些浮动元素进行清理。这有助于减少和消除不必要的标记。但是,浮动会变得复杂,而且一些浏览器在处理一些有许多浮动元素的布局时有困难。因此,许多人喜欢添加额外的标记。
应用值为hidden或auto的overflow属性会自动的清理包含的任何浮动元素,而不需要添加额外的标记。这个方法并不适合所有情况,因为设置框的overflow属性会影响它的表现。
最后,有一些人使用CSS生成的内容或者javascript对浮动元素进行清理,这两种方法的基本概念是相同的。并不直接向标记中添加清理的元素,而是将它动态的添加到页面中。对于这两种方法,需要指定清理的元素应该出现在哪里,而且常常要添加一个类名:
<div class="news clear"> <img src="new-pic.jpg" /> <p>some text</p> </div>
在使用CSS方法时,结合使用:after伪类和内容声明在指定的现有内容的末尾添加新的内容。比如一个句点,它是非常小的不引人注意的字符。而且不希望这个新生成的内容占据页面上的垂直空间,也不想让它在页面上显示,所以把它的高度设为0,visibility设置为hidden。因为被清理元素需要在它的顶空白边上添加空间,所以生成的内容需要将它的display设置为block。这样设置后,就可以对生成的内容进行清理:
.clear:after {
content: ".";
heigth: 0;
visibility: hidden;
display : block;
clear: both;
}
ps: 这个方法在大多数浏览器中时有效地,但是在IE 6和更低版本中不起作用。有各种解决方案。最常用的解决方案就是应用Holly招数,迫使IE 5 - IE 6使用“布局”和不正确的清理浮动元素。
.clear {
display: inline-block;
}
/* Holly Hack Targets IE Win only \*/
* html .clear {height: 1%;}
.clear {display: block;}
/*End Holly Hack */
javascript方法在所有主流浏览器中都是有效的(在打开脚本功能的情况下),但是,如果采用这种方法,就要确保在关闭脚本功能的情况下页面内容仍然是可读的。
/**********行框和清理***************/

浙公网安备 33010602011771号