CSS 定位机制
CSS 有三种基本的定位机制:普通流、浮动和绝对定位。
除非专门指定,否则所有框都在普通流中定位。也就是说,普通流中的元素的位置由元素在 X(HTML) 中的位置决定。
块级框从上到下一个接一个地排列,框之间的垂直距离是由框的垂直外边距计算出来。
行内框在一行中水平布置。可以使用水平内边距、边框和外边距调整它们的间距。但是,垂直内边距、边框和外边距不影响行内框的高度。由一行形成的水平框称为行框(Line Box),行框的高度总是足以容纳它包含的所有行内框。不过,设置行高可以增加这个框的高度。
我们通过浏览器所看到得页面是当浏览器在接收到服务器的响应后,即收到一个HTML文件后,浏览器对该HTML文件进行解析渲染后所呈现的页面,而该页面默认是流布局的,为什么呢,因为浏览器解析这个HTML文件时是由上而下进行的,依次解析响应的内容,然后根据解析到的元素类型由上而下,从左至右的填充浏览器页面。
HTML页面中的元素大概可以分类为两种:块元素(或DISPLAY:BLOCK)和行内元素(或DISPLAY:INLINE)。
块元素默认会占满父元素的一行宽(即使自身不够一行宽)然后前后加换行,如div、h1 或 p 。
行内元素则紧跟在前一元素的后面,如span 和 strong 。
(假设AX为行内元素,BX为块元素)
A1,A2,B1,B2,A3为浏览器接收到得服务器端的响应,这时会有在页面中产生以下布局:
-----------------
A1 A2
B1
B2
A3
----------------
可以想象,AX和BX是一个一个的盒子,那么浏览器在解析服务器端的响应(或说是在渲染页面)时,就可以看做是在不断地摆弄着一堆盒子的过程(块元素由块框装载,而行内元素由行内框装载,一行的中的行内框又被行框装载。)。
当然,一个BODY也是一个盒子,而且是一个顶级盒子,装载着页面中的所有盒子。
何以想象,浏览器是一名搬运工,它的职责是把盒子搬到特定的地方,如果没有特别的指示,那么它就会以默认的方式来放置这些盒子(这个默认根据浏览器的不同有所差异哦),如果我想控制它摆放的位置,那么显然的,我就需要一名监工,去告诉浏览器如何搬,这就是CSS了。当然CSS不仅仅用于控制布局。
元素不是块元素就是行内元素,但他们是可以相互转换的(通过将 display 属性设置为 block,可以让行内元素(比如 <a> 元素)表现得像块级元素一样。还可以通过把 display 设置为 none,让生成的元素根本没有框。这样的话,该框及其所有内容就不再显示,不占用文档中的空间。display属性设置为设置为inline则转换为行内元素)。这使得设计具有很大的灵活性,如A标签是行内元素,点击这个标签中的文字才能激活这个标签,当文字比较小的时候,会增加浏览者的访问难度,这时可以把它设置为块元素,再设置它的相关CSS属性(width和height)就可以增大点击的有效区域,从而改善用户体验。
上面提到块元素默认会占满父元素的一行宽(实际上,默认块框的宽度和行宽一致),这时通过设置设置WIDTH和HEIGHT你会发现块框发生了变化(通过DREAMWEARVER观察得到)。这种变化可以说是为CSS的一个很重要布局埋下伏笔---------POSITION。
下图是该属性的说明:
-
static
-
元素框正常生成。块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。
-
relative
-
在使用相对定位时,无论是否进行移动,元素仍然占据原来的空间。因此,移动元素会导致它覆盖其它框。
-
相对定位是一个非常容易掌握的概念。如果对一个元素进行相对定位,它将出现在它所在的位置上。然后,可以通过设置垂直或水平位置,让这个元素“相对于”它的起点进行移动。
如果将 top 设置为 20px,那么框将在原位置顶部下面 20 像素的地方。如果 left 设置为 30 像素,那么会在元素左边创建 30 像素的空间,也就是将元素向右移动。
#box_relative {
position: relative;
left: 30px;
top: 20px;
}
-
absolute
-
元素框从文档流完全删除,并相对于其包含块定位。包含块可能是文档中的另一个元素或者是初始包含块。元素原先在正常文档流中所占的空间会关闭,就好像元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。
-
绝对定位的元素的位置相对于最近的已定位祖先元素,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块。
-
-
fixed
-
元素框的表现类似于将 position 设置为 absolute,不过其包含块是视窗本身。
提示:相对定位实际上被看作普通流定位模型的一部分,因为元素的位置相对于它在普通流中的位置。
有一点要注意:如果父元素是相对定位,而子元素是绝对定位的,那么子元素的LEFT,TOP是相对于父元素的PADDING的左上角产生位移(或者以border的内边线为参考),而不是html页面。
接下来看一个例子吧:
Code
<html>
<head>
<style type="text/css">
*{
margin:0;}
#waimian{
position:relative;
margin:20px;
border:20px #0000FF solid;
padding:20px;
}
.noab{
margin:20px;
border:20px #FF0000 solid;
padding:20px;}
.limian{
position:absolute;
margin:20px;
border:20px #00FF00 solid;
padding:20px;
left:15PX;
}
</style>
<script type="text/javascript">
function setTopEdge()
{
var bb=document.getElementById("kan").offsetParent;
alert(bb.id);
}
</script>
</head>
<body>
<div id="waimian">
<div class="noab">
world
</div>
<div class="limian" id="kan">
<input type="button" id="b1" onClick="setTopEdge()" value="Set top edge to 100 px" />
</div>
</div>
<a style="border:1px #659836 solid; display:block;" href="http://www.baidu.com">baidu</a>
<a href="#">dsfdfsdfds</a>
</body>
</html>
另外一个例子(一个简陋的导航):
css部分:
Code
<style>
*{margin:0;padding:0}
body{background-color:#CCCCCC;}
ul li{text-align:center; vertical-align:middle;float:left;width:100px;height:40px; list-style:none;background-color:#FF9900;
border-width:0px 1px;border-style:solid;border-color:#FF0000;}
#content1,#content2,#content3,#content4{width:408px;height:150px;position:absolute;top:40px;left:0}
/*宽度为408px是考虑到有4个LI(每个宽度为100px)和Border的宽度,绝度定位很重要,如果不是会出现奇特的效果(去掉试试看哈),top40px刚好是LI的HEIGHT*/
.dis{display:none;}/*默认隐藏层*/
ul li:hover{
background-color:#FFFFCC;}
ul li:hover div{display:block}/*显示层*/
#content1{
background-color:#33FF99}
#content2{
background-color:#33CC66}
#content3{
background-color:#006600}
#content4{
background-color:#003300}
</style>
body部分:
Code
<body>
<div class="meau">
<ul>
<li id="one"><a href="#">首页</a><div id="content1" class="dis">index</div></li>
<li id="two"><a href="">服装</a><div id="content2" class="dis">clothes</div></li>
<li id="three"><a href="">手机</a><div id="content3" class="dis">telephone</div></li>
<li id="fourt"><a href="">电脑</a><div id="content4" class="dis">pc</div></li>
</ul>
</div>
</body>