在CSS中,定位机制有3种:
1. 普通文档流(Normal flow)
2. 绝对定位(Absolute positioning)
3. 浮动(Floats)
1. Normal flow
在书籍或者视频中,Normal flow有许多种翻译,普通流、普通文档流、标准文档流、文档流等等,反正都是指的一个东西——Normal flow。
Normal flow是网页默认的布局方式,元素的位置由元素在HTML文档中出现的位置决定,比如div1写在div2上面,那么在布局上,div1就是在div2上面。
1.1 block elements
block elements(块级元素、块框)(div、p、h1)会独占一行垂直分布,垂直上元素之间间距由垂直外边距决定(这里会发生外边距坍塌),宽度默认是父元素的100%宽度。
1.2 inline elements
inline elements(内联元素、行内框)(span、a、strong)会在一行里面从左往右排列,不会另起一行。
1.3 相对定位
相对定位属于文档流,因为元素不脱离文档流。相对定位是相对于这个元素在文档流中的原始位置来做的定位。元素宽度不自适应内容。
当我们相对于原始位置做一个偏移的定位时,元素偏移了,但元素原来的位置还是被保留下来了。
//index.html
<div class="test1">
111
</div>
<div class="test2">
111
</div>
<div class="test3">
111
</div>
<div class="test4">
111
</div>
<link rel="stylesheet" type="text/css" href="test.css">
//test.css
.test1{
background-color: red;
position: relative;
top:100px;
}
.test2{
background-color: #555;
}
.test3{
background-color: #999;
}
.test4{
background-color: #ddd;
}
红色的div元素往下偏移了100px,就是距离它的top,偏移了100px。它原本应该在最上面,现在移动到了最下面,而且最上面的空间还给它留着了。如果我们只是指定一个元素是relative,但没有给它指定具体的top等方位,那么这个元素还是在原地,不同的是,这个元素被定位了。元素是否被定位会影响到绝对定位这种定位机制,下面我们就讲绝对定位。
2. 绝对定位
绝对定位是相对于离该元素最近的已定位的祖先元素来做定位的。元素脱离文档流。元素宽度自适应内容。
关于已定位,祖先元素的position属性应该取值非static之外的值,position:static;
相对于没有定位,写了跟没写一个样。如果祖先元素都没有显式的position属性,那么绝对定位就会相对于最顶部的html元素。
//index.html
<div class="test1">
111
</div>
<div class="test2">
222
</div>
<div class="test3-p">
<div class="test3">
333
</div>
</div>
<div class="test4">
444
</div>
<link rel="stylesheet" type="text/css" href="test.css">
//test.css
.test1{
background-color: red;
}
.test2{
background-color: #555;
}
.test3-p{
/*position: relative;*/
}
.test3{
position: absolute;
top:15px;
background-color: #999;
}
.test4{
background-color: #ddd;
}
可以看到test3有个祖先元素test3-p,但是祖先元素没有设置position属性,所以不属于已定位元素,test3的相对定位还是相对于html元素来说的。如果想相对于test3-p元素做定位,可以把test3-p的position设置为absolute(不保留位置)或者relative(保留位置)。
2.1 固定定位
固定定位属于绝对定位,是相对于视窗(viewport)来做定位的。元素脱离文档流。
.fixed {
position: fixed;
bottom: 0;
right: 0;
width: 200px;
background-color: white;
}
不管我们怎么上下滚动页面,右下角贴着的“狗皮膏药”会一直在那个地方,关也关不掉。
3. 浮动
浮动是相对于祖先元素来做定位的。元素不在文档流中。元素宽度自适应内容。
当一个元素有浮动属性时,它就会脱离文档流,那么它后面的元素就会补充上来。如果涉及到文字段落的话,后面补充上来的文字不是和浮动的元素重合,文字会围绕着浮动的元素,这点跟前2个定位机制有点不一样。
//index.html
<div class="test1">
111111111111
</div>
<div class="test2">
222222222222
</div>
<div class="test3">
333333333333
</div>
<div class="test4">
444444444444
<p>444444444444</p>
<p>444444444444</p>
</div>
<link rel="stylesheet" type="text/css" href="test.css">
//test.css
.test1{
background-color: red;
}
.test2{
background-color: #555;
}
.test3{
margin: auto;
background: red;
text-align: center;
float:left;
}
.test4{
background-color: #ddd;
}
尽管test3浮动,脱离了文档流,后面的test4并没有躲到test3下面去,而是围绕着test3。
3.1 清除兄弟元素间浮动影响
有时我们不希望test4由于test3的浮动而跟着上来了,那么我们就在test4的属性中加入clear属性,clear:left;
表示test4的左边不应该挨着浮动框,right和both表示不应该挨着浮动框的右边和两边。
clear之前
clear之后
.test4{
background-color: #ddd;
clear:left;//rightoth
}
我们用文字做例子来看看效果,应该用文字环绕图片的例子更加形象一点
3.2 清除父子元素间浮动影响
//index.html
<div class="test1">
111111111111
</div>
<div class="test2">
222222222222
</div>
<div class="test3wrap">
test3wrap
<div class="test3">
<p>333333333333</p>
<p>333333333333</p>
<p>333333333333</p>
<p>333333333333</p>
</div>
</div>
<div class="test4">
444444444444
</div>
//test.css
.test1{
background-color: red;
}
.test2{
background-color: #555;
}
.test3wrap{
border: 3px solid;
/*overflow: auto;*/
/*zoom: 1;*/
}
.test3{
margin: auto;
background: red;
text-align: center;
float:left;
}
.test4{
background-color: #ddd;
clear: left;
}
我们浮动了test3,test3wrap父元素并没有完全包裹住test3,test3逃出来了,我们可以用overflow属性消除这种子元素超出父元素的影响。
用应用 overflow:auto; 之前
用应用 overflow:auto; 之后。如果考虑IE6兼容性,那么还需要加一句 zoom:1;
【Reference】
1. 《精通CSS》(第2版)
2. 学习CSS布局 http://zh.learnlayout.com/