从0到1_前端开发前端基础

CSS的absolute绝对布局相对于哪个父级元素定位的分析

2017-08-02  本文已影响149人  ef43ffb32440

使用absolute布局的同学有时候可能会疑惑,有时设置为absolute定位的元素相对父元素(最近的父级元素)定位,有时候不是。那么,绝对布局的元素到底相对哪个父级元素定位呢?

绝对定位的元素,相对于static定位以外的第一个父元素进行定位。
元素默认的定位值是static,所以往上找参照元素一直到根元素 。

下面我们用实践一步步分析。

1. 父级元素position为默认值,显然,蓝色的子元素没有相对红色的父级元素定位
<div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
    <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
</div>
红色的为父级元素,蓝色的为绝对布局的子元素

用Chrome的开发调试功能分析,发现蓝色的子元素相对页面顶部定位了:


红色的为父级元素,蓝色的为绝对布局的子元素
2. 再加一层父级元素,蓝色子元素依然是相对页面顶部定位:
<div>
    <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
        <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
    </div>
</div>
红色的为父级元素,蓝色的为绝对布局的子元素

不是相对<body>节点定位:


红色的为父级元素,蓝色的为绝对布局的子元素

而是相对<html>节点的顶部:


红色的为父级元素,蓝色的为绝对布局的子元素
3. 加3层父节点,父节点的position都依然是默认值,蓝色子元素依然是相对页面顶部定位:
<div>
    <div>
        <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
            <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
        </div>
    </div>
</div>
红色的为父级元素,蓝色的为绝对布局的子元素
4. 将第2个父节点的position设置为static,蓝色子元素依然是相对页面顶部定位:
<div>
    <div style="position: static">
        <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
            <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
        </div>
    </div>
</div>
红色的为父级元素,蓝色的为绝对布局的子元素
5. 将所有div父节点的position设置为static,蓝色子元素依然是相对页面顶部定位:
<div style="position: static">
    <div style="position: static">
        <div style="position: static; width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
            <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
        </div>
    </div>
</div>
红色的为父级元素,蓝色的为绝对布局的子元素
6. 将蓝色子元素的直接父节点的position设置为relative,这时蓝色子元素相对直接父节点定位了:
<div style="position: relative; width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
    <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
</div>
红色的为父级元素,蓝色的为绝对布局的子元素
7. 将蓝色子元素的直接父节点position为默认,间接父节点设置为relative,这时:
<div style="position: relative">
    <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
        <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
    </div>
</div>
红色的为父级元素,蓝色的为绝对布局的子元素

蓝色div在红色div的左边,好像既不相对红色元素定位,也不相对页面顶部定位:


红色的为父级元素,蓝色的为绝对布局的子元素

但我们发现设置position为relative的父节点没有设置大小,我们不妨设置一下它的背景色+透明度,好分析是不是相对relative的父节点定位的:

<div style="position: relative; background: yellowgreen; opacity: 0.5">
    <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
        <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
    </div>
</div>

如图,半透明+黄绿色的div就是设置position为relative的父节点:


红色的为父级元素,蓝色的为绝对布局的子元素

我们发现这个position为relative的节点并没有设置width和height,显然,默认的width为100%,即直接父节点的width;而默认的height为auto,自动装满最大height的子元素,即100px。

于是我们再设置一下这个relative position父节点的width和height:

<div style="position: relative; width: 150px; height: 150px;">
    <div style="position: static; width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
        <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
    </div>
</div>

设置width和height为150px后,relative position的父级元素的margin-top自动和子元素的margin-top对齐


红色的为父级元素,蓝色的为绝对布局的子元素

我们设置一下背景色和透明图,以便更好地分析:

<div style="position: relative; width: 150px; height: 150px; background: yellowgreen; opacity: 0.5">
    <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
        <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
    </div>
</div>

黄绿色+半透明的div即为relative position的父节点,虽然没有设置margin-top,但自动和红色div的margin-top对齐:


红色的为父级元素,蓝色的为绝对布局的子元素
8. 为relative position的父节点设置border:

前面实战例子中的relative position父节点都没有设置border,我们探索一下设置border对定位的影响。

步骤7我们已经分析过,没有设置margin-top的div父节点会自动对齐子div的margin-top:


红色的为父级元素,蓝色的为绝对布局的子元素

我们只在relative position的父节点设置了border: 1px solid black

<div style="position: relative; border: 1px solid black">
    <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
        <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
    </div>
</div>

设置了border之后,没有设置relativeposition父节点的margin-top,margin-top默认为0,宽度100%;高度自动包含所有子元素:


红色的为父级元素,蓝色的为绝对布局的子元素

设置宽度和高度:

<div style="position: relative; width: 150px; height: 150px; border: 1px solid black">
    <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
        <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
    </div>
</div>

设置了border和宽度之后,margin-top默认为0:


红色的为父级元素,蓝色的为绝对布局的子元素

我们再试着设置margin-top:

<div style="position: relative; width: 150px; height: 150px; margin-top: 50px; margin-left: 50px; border: 1px solid black">
    <div style="width: 100px; height: 100px; margin-top: 100px; margin-left: 100px; background: red;">
        <div style="position: absolute; top: 20px; left: 20px; width: 50px; height: 50px; background: blue"></div>
    </div>
</div>

设置了margin-top和margin-left之后,relative position父div位置随之发生改变,而蓝色子div也相对重新定位:


红色的为父级元素,蓝色的为绝对布局的子元素
9. 设置position为absolute,但不指定left、top、right、bottom的值:

这时该div还是在父节点的流内,布局效果相当于指定父节点position: relative,并且div本身的left: 0, top: 0。

通过以上8步实战分析,我们总结出以下3点:

绝对定位的元素,相对于static定位以外的第一个父元素进行定位。

没有设置border和margin-top的父div,顶部自动对齐margin-top最小的子div的顶部

设置了border但没有设置margin-top的父div,margin-top默认为0

上一篇 下一篇

猜你喜欢

热点阅读