首先
我们先来看看CSS3 Api中对position属性的相关定义:
static:无特殊定位,对象遵循正常文档流。top,right,bottom,left等属性不会被应用。
relative:对象遵循正常文档流,但将依据top,right,bottom,left等属性在正常文档流中偏移位置。而其层叠通过z-index属性定义。
absolute:对象脱离正常文档流,相对于最近的postion非static的父元素使用top,right,bottom,left等属性进行绝对定位。而其层叠通过z-index属性定义。
fixed:对象脱离正常文档流,使用top,right,bottom,left等属性以窗口为参考点进行定位,当出现滚动条时,对象不会随着滚动。而其层叠通过z-index属性定义。
怎么样,是不是还是很迷糊~~ 没关系,下面就从几个基础概念一一给大家详述:
什么是文档流?
将窗体自上而下分成一行行, 并在每行中按从左至右的顺序排放元素,即为文档流。每个非浮动块级元素都独占一行, 浮动元素则按规定浮在行的一端。 若当前行容不下, 则另起新行再浮动。
内联元素也不会独占一行。 几乎所有元素(包括块级,内联和列表元素)均可生成子行, 用于摆放子元素。
只有三种情况会使得元素脱离文档流,分别是:浮动、绝对定位和固定定位。
静态定位(static) :
static,无特殊定位,它是html元素默认的定位方式,即我们不设定元素的position属性时默认的position值就是static,它遵循正常的文档流对象,对象占用文档空间,该定位方式下,top、right、bottom、left、z-index等属性是无效的。
相对定位(relative) :
relative定位,又称为相对定位,从字面上来解析,我们就可以看出该属性的主要特性:相对。但是它相对的又是相对于什么地方而言的呢?这个是个重点,也是最让我迷糊的一个地方。让我们来简单实现以下:
<style>
#first{
border: 1px solid red;
width: 100px;
height: 100px;
}
#second{
border: 1px solid green;
width: 100px;
height: 100px;
}
</style>
<body>
<div id="first"></div>
<div id="second"></div>
</body>
上面代码实现的效果
如果加上position:relative,并且设置一个偏移量,让我们来看看发生了什么?
<style>
#first{
border: 1px solid red;
width: 100px;
height: 100px;
position: relative;
top: 20px;
left: 20px;
}
#second{
border: 1px solid green;
width: 100px;
height: 100px;
}
</style>
<body>
<div id="first"></div>
<div id="second"></div>
</body>
是的,没错,相对自己原先的位置发生了偏移,并且覆盖住了下面的元素。
相对定位相对的是它原本在文档流中的位置而进行的偏移,而我们也知道relative定位也是遵循正常的文档流,它没有脱离文档流,但是它的top/left/right/bottom属性是生效的,可以说它是static到absolute的一个中间过渡属性,最重要的是它还占有文档空间,而且占据的文档空间不会随 top / right / left / bottom 等属性的偏移而发生变动,也就是说它后面的元素是依据虚线位置( top / left / right / bottom 等属性生效之前)进行的定位,这点一定要理解。
我们知道了top / right / left / bottom 属性是不会对relative定位的元素所占据的文档空间产生偏移,那么margin / padding会让该文档空间产生偏移吗?做个试验呀~
<style>
#total{
border: 1px solid blue;
width: 300px;
height: 400px;
}
#first{
border: 1px solid red;
width: 100px;
height: 100px;
position: relative;
top: 20px;
left: 20px;
margin: 20px;
}
#second{
border: 1px solid green;
width: 100px;
height: 100px;
}
#disable{
float: left;
width: 100px;
height: 100px;
border: 1px dotted gray;
}
</style>
<body>
<div id="total">
<div id="disable"></div>
<div id="first"></div>
<div id="second"></div>
</div>
</body>
当然,我们这里将原始的位置用虚线给画出来了,红色线是偏移后的位置。
对比一下,是不是就很清晰了,我们先将first元素外边距设为20px,那么second元素就得向下偏移40px,所以margin是占据文档空间。
同理,padding也是一样的道理。
绝对定位(absoulte) :
absoulte定位,也称为绝对定位,虽然它的名字号曰“绝对”,但是它的功能却更接近于”相对”一词,为什么这么讲呢?原来,使用absoult定位的元素脱离文档流后,就只能根据祖先类元素(父类以上)进行定位,而这个祖先类还必须是以postion非static方式定位的, 举个例子,a元素使用absoulte定位,它会从父类开始找起,寻找以position非static方式定位的祖先类元素(注意,一定要是直系祖先才算哦~),直到标签为止,这里还需要注意的是,relative和static方式在最外层时是以标签为定位原点的,而absoulte方式在无父级是position非static定位时是以文档作为原点定位。和元素相差9px左右。我们来看下效果:
相对于文档,就是相对于整个页面来进行布局,而相对于窗口,则是相对于浏览器的可视区域进行定位
<style>
html{border: 1px dashed green;}
body{border: 1px dashed purple;}
#first{
width: 200px;
height: 100px;
border: 1px solid red;
position: relative;
}
#second{
width: 200px;
height: 100px;
border: 1px solid blue;
position: absolute;
top: 0;
left: 0;
}
</style>
<body>
<div id="first">relative</div>
<div id="second">absolute</div>
</body>
为什么absoulte定位要加 top:0; left:0; 属性?
其实加上这两个属性是完全必要的,因为我们如果使用absoulte或fixed定位的话,必须指定 left、right、 top、 bottom 属性中的至少一个,否则left/right/top/bottom属性会使用它们的默认值 auto ,这将导致对象遵从正常的HTML布局规则,在前一个对象之后立即被呈递。即定位在它原本在文档流中的位置,只不过它是脱离文档流,不占据空间的。简单讲就是变成不占据空间的relative定位。
看懂了,祖先类的margin会让子类的absoulte跟着偏移,而padding却不会让子类的absoulte发生偏移。总结一下,就是absoulte是根据祖先类的border进行的定位。
Note : 绝对(absolute)定位对象在可视区域之外会导致滚动条出现。而放置相对(relative)定位对象在可视区域之外,滚动条不会出现。
总结一下:
相对定位是“相对于“元素在文档流中初始位置的,而绝对定位是”相对于“最近的已经定位的祖先元素。
相对定位相对的是它原本在文档流中的位置而进行的偏移,而我们也知道relative定位也是遵循正常的文档流,它没有脱离文档流,但是它的top/left/right/bottom属性是生效的,可以说它是static到absolute的一个中间过渡属性,最重要的是它还占有文档空间,而且占据的文档空间不会随 top / right / left / bottom 等属性的偏移而发生变动。
绝对定位:
absoulte是根据祖先类中的position非static元素的左上角为原始点进行定位,relative则是遵循正常文档流进行定位。
没有TRLB值的absolute定位相当于不占据空间的relative定位。如果使用absoulte或fixed定位的话,必须指定 TRLB属性中的至少一个,否则left/right/top/bottom属性会使用它们的默认值 auto ,这将导致对象“相对于“元素在文档流中初始位置定位的,只不过由于他本质上还是脱离文档流的,所以不占据空间。简单讲就是变成类似于不占据空间的relative定位。
absolute 定位如果top和bottom一同存在的话,那么只有top生效。如果left和right一同存在的话,那么只有left生效。
absolute 定位的祖先类的margin会让子类的absoulte跟着偏移,而padding却不会让子类的absoulte发生偏移。总结一下,就是absoulte是根据祖先类的border进行的定位。
固定定位(fixed):
fixed定位,又称为固定定位,它和absolute定位一样,都脱离了文档流,并且能够根据top、right、left、bottom属性进行定位,但不同的是fixed是根据窗口为原点进行偏移定位的,也就是说它不会根据滚动条的滚动而进行偏移。
Note:使用static 定位或无position定位的元素z-index属性是无效的。