CSS 参考手册对 position 属性做了说明:
static
: 对象遵循常规流。此时4个定位偏移属性不会被应用。
relative
:对象遵循常规流,并且参照自身在常规流中的位置通过top,right,bottom,left这4个定位偏移属性进行偏移时不会影响常规流中的任何元素。
absolute
: 对象脱离常规流,此时偏移属性参照的是离自身最近的定位祖先元素,如果没有定位的祖先元素,则一直回溯到body元素。盒子的偏移位置不影响常规流中的任何元素,其margin不与其他任何margin折叠。
fixed
: 与absolute一致,但偏移定位是以窗口为参考。当出现滚动条时,对象不会随着滚动。
针对上面的说明,咱们下面通过几个例子加以解释,不过你的首先理解 常规流
是什么? 常规流
也被叫做 文档流
, 常规流
指的是元素按照其在 HTML 中的位置顺序决定排布的过程,主要的形式是自上而下,一行接一行,每一行从左至右。就像搭积木一样,一成一成,积木从下往上(常规流从上往下), 那 脱离常规流
也就好理解了,就是 积木块 不占据原来的位置了。
下面例子的 html 布局:
<div class="div">
<div class="d1">
</div>
<div class="d2">
</div>
<div class="d3">
</div>
</div>
默认 css 样式:
.div{
border: 2px solid darkgrey;
width:400px;
height: 400px;
margin-top: 50px;
}
div{
width: 100px;
height: 100px;
border: 1px solid darkgreen;
}
静态定位(static) :static
,无特殊定位,它是html元素默认的定位方式,4个定位偏移属性不会被应用。及对它设置 top,right,bottom,left 无效。
相对定位(relative) :relative
属性遵循常规流,也就设置 relative
属性不会使它脱离文档流。
如给第一个盒子 添加 relative
:
.d1{
border: 1px solid red;
position: relative;
top: 20px;
left: 20px;
}
可以看出下面的盒子还在原来的位置,而第一个盒子也占据这原来的位置(虚线的地方),并且 top 和 left 定位是相对于 父容器的。
好了知道了这一效果,那咱们在给第一个盒子加上 margin / padding ,会有什么变化呢?
.d1{
border: 1px solid red;
position: relative;
margin:10px;
padding: 10px;
top: 20px;
left: 20px;
}
可以看出 ,第一个盒子在添加 margin
属性后 ,盒子偏离了父容器 10px ,加上之前的 top,就是 30px, 而 padding
属性会使 盒子 撑开了 10px ,下面的其他盒子 d2、d3的位置也受到了影响,往下偏移了 40px !!为什么是40px 呢,可以看图中蓝色实线
部分,假设盒子 d1 没有 relative 的话 ,那么 当 margin:10px; padding: 10px; 后,整个盒子是不是呈现 蓝色实线
的状态, margin 会使 d1盒子 上下增加 10px,padding 会使 d1 盒子内容上下撑开10px,合计 d1盒子偏离了40px。
而造成这样的原因就是
relative
属性遵循常规流,并没有脱离文档流,所以 margin和padding 是会影响
前后元素的位置的。
绝对定位(absoulte) :absolute
: 对象脱离常规流。
给盒子添加 属性:
.d1{
border: 1px solid red;
position: absolute;
top: 20px;
left: 20px;
}
嗯? d1盒子怎么跑到了父容器的外面,而且 d2、d3 盒子的位置也受到了影响,往上移动了一个d1的高度。
原来我没有给父容器添加一个 position:属性
,这也引出了 absolute
的一个规则:
使用absoult定位的元素脱离文档流后,就只能根据祖先类元素(父类以上)进行定位,而这个祖先类还必须是以postion非static方式定位的,
举个例子,a元素使用absoulte定位,它会从父类开始找起,寻找以position非static方式定位的祖先类元素(注意,一定要是直系祖先才算),直到<html>标签为止。
所以这样:
.div{
border: 2px solid darkgrey;
width:400px;
height: 400px;
margin-top: 50px;
position: relative;
}
.d1{
border: 1px solid red;
position: absolute;
top: 20px;
left: 20px;
}
这就是 盒子脱离文档流的现象,脱离了文档流,那么就不再占据原来的位置了,后面的元素就会顶上去,补充空白位置!
那同样的 ,当盒子添加 absolute
属性,再添加 margin / padding ,会有什么变化呢?
.d1{
border: 1px solid red;
position: absolute;
margin: 10px;
padding: 10px;
top: 20px;
left: 20px;
}
可以看出 首先 d2、d3 盒子 是不受影响的,而 d1盒子 margin: 10px;距离父容器就偏离了10px,加上之前的 top 和 left 就是 30px,而 padding 会把 d1 盒子给撑开了 10px。
但都对下面的盒子没影响,原因也就是
absolute
: 对象脱离常规流。
固定定位(fixed):fixed
:与absolute一致,但偏移定位是以窗口
为参考。当出现滚动条时,对象不会随着滚动。
所以:
.d1{
border: 1px solid red;
position: fixed;
top: 20px;
left: 20px;
}
top 和 left 是以窗口为参考的!。当出现滚动条时,对象不会随着滚动。还在原来的位置。
最后一点需要注意: 使用absoulte或fixed定位的话,必须指定 left、right、 top、 bottom
属性中的至少一个,否则left/right/top/bottom属性会使用它们的默认值 auto,也就是相当于relative
状态。