2

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;
}

clipboard.png

静态定位(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 定位是相对于 父容器的。
clipboard.png

好了知道了这一效果,那咱们在给第一个盒子加上 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 是会影响
前后元素的位置的。

clipboard.png

绝对定位(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>标签为止。

clipboard.png

所以这样:

.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;
}

这就是 盒子脱离文档流的现象,脱离了文档流,那么就不再占据原来的位置了,后面的元素就会顶上去,补充空白位置!

clipboard.png

那同样的 ,当盒子添加 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: 对象脱离常规流。

clipboard.png

固定定位(fixed):
fixed:与absolute一致,但偏移定位是以窗口为参考。当出现滚动条时,对象不会随着滚动。
所以:

.d1{
    border: 1px solid red;
    position: fixed;
    top: 20px;
    left: 20px;
}

top 和 left 是以窗口为参考的!。当出现滚动条时,对象不会随着滚动。还在原来的位置。
clipboard.png

最后一点需要注意: 使用absoulte或fixed定位的话,必须指定 left、right、 top、 bottom
属性中的至少一个,否则left/right/top/bottom属性会使用它们的默认值 auto,也就是相当于 relative 状态。


曾田生z
427 声望34 粉丝

立法者三句修改的话,全部藏书就会变成废纸。——律匠