为什么我绝对定位的元素没有位于我期望的位置?

时间:2019-02-19 20:38:38

标签: html css positioning

我只是在学习CSS的定位。基于我发现有用的文章,我开始玩转。

使用以下代码,我无法理解为什么绝对灰色框div不在其相对父级之外。我希望灰色框位于容器的左上角。

web.ctx.protocol
.container {
  background: lightblue;
  position: relative;
}

.box-orange {
  background: orange;
  height: 100px;
  width: 100px;
  position: relative;
  top: 100px;
  left: 100px;
  z-index: 2;
}

.box-blue {
  background: lightskyblue;
  height: 100px;
  width: 100px;
  /*position: static;*/
}

.box-green {
  background: lightgreen;
  height: 100px;
  width: 100px;
  position: relative;
  top: -105px;
  left: 105px;
  z-index: 2;
}

.box-grey {
  background: grey;
  height: 100px;
  width: 100px;
  position: absolute;
}

在以下情况下,也无法理解为什么灰色框不在左上角,而是移到橙色框在此处留下的空白处之后。我刚刚将灰色框移到了容器div中的第二个位置。

<div class="container">
  <div class="box-orange"></div>
  <div class="box-blue"></div>
  <div class="box-green"></div>
  <div class="box-grey"></div>
</div>
.container {
  background: lightblue;
  position: relative;
}

.box-orange {
  background: orange;
  height: 100px;
  width: 100px;
  position: relative;
  top: 100px;
  left: 100px;
  z-index: 2;
}

.box-blue {
  background: lightskyblue;
  height: 100px;
  width: 100px;
  /*position: static;*/
}

.box-green {
  background: lightgreen;
  height: 100px;
  width: 100px;
  position: relative;
  top: -105px;
  left: 105px;
  z-index: 2;
}

.box-grey {
  background: grey;
  height: 100px;
  width: 100px;
  position: absolute;
}

我发现的所有详细文档(例如MDN)和教程仅演示了2-3个框的非常简单的示例。

3 个答案:

答案 0 :(得分:2)

您必须始终在绝对定位的元素(或您想要的顶部,右侧,底部,左侧的任何值)上设置top:0; left:0;

答案 1 :(得分:0)

要正确理解这一点,您需要参考official sepcification,在其中找到元素必须满足的方程:

'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block

我们没有任何边框和填充,因此在您的情况下,它只会是:

'top' + 'margin-top' + 'height' + 'margin-bottom' + 'bottom' = height of containing block

如果您在下面阅读,将会发现以下内容:

  
      
  1. “顶部”和“底部”是“自动”,“高度”不是“自动”,然后将“顶部”设置为静态位置,将“边距- top”和“ margin-bottom”设置为0,并求解“ bottom”。
  2.   

因此,在您的情况下,您已经设置了高度并将top / bottom设置为自动,因此top将会设置为静态位置

  

..更确切地说,“顶部”的静态位置是从包含块的顶部边缘到假设框的顶部边缘的距离,该假设框如果指定了“位置”,则该框将是元素的第一个框值一直是“静态”。

为简便起见,如果未设置position:absolute,则为元素的位置。

这是一个易于理解的简单示例

.container {
  background: lightblue;
  position: relative;
  padding:40px 20px;
  display:inline-block;
  vertical-align:top;
  width: 250px;
}


.box-grey {
  background: grey;
  height: 100px;
  width: 100px;
  position: absolute;
}

.box-green {
  height:20px;
  background:green;
}
<div class="container">
  <div class="box-green"></div>
  <div class="box-grey" style="position:static;">I am static</div>
</div>

<div class="container">
  <div class="box-green"></div>
  <div class="box-grey"></div>
</div>

请注意,如果我们添加position:absolute,则会保留第一个元素的静态位置。我们没有指定任何最高值,因此浏览器将使用默认值,该默认值是元素的position:static(默认位置)之一。

如果您不想这样做,只需设置最高值,然后遵循以下规则:

  
      
  1. “底部”为“自动”,“顶部”和“高度”不是“自动”,然后将“ margin-top”和“ margin-bottom”的“ auto”值设置为0并求解“ bottom”
  2.   

.container {
  background: lightblue;
  position: relative;
  padding:40px 20px;
  display:inline-block;
  vertical-align:top;
  width: 250px;
}


.box-grey {
  background: grey;
  height: 100px;
  width: 100px;
  position: absolute;
  top:0;
}

.box-green {
  height:20px;
  background:green;
}
<div class="container">
  <div class="box-green"></div>
  <div class="box-grey" style="position:static;">I am static</div>
</div>

<div class="container">
  <div class="box-green"></div>
  <div class="box-grey"></div>
</div>

相同的逻辑适用于the left property


您可能还会注意到使用了包含块这个词,在这里非常重要,并在same specification

中进行了解释。
  

有时会相对于某个矩形(称为元素的包含块)来计算元素框的位置和大小。元素的包含块定义如下:

     

...

     
      
  1. 如果元素具有“位置:绝对”,则包含块由最接近的祖先以“绝对”,“相对”或“固定”的“位置”建立,方法如下:
  2.   
     

...

这还不够,因为还有其他属性(下面列出)也可以建立一个包含块,因此您可以相对于未定位的祖先定位元素!

filter属性:https://stackoverflow.com/a/52937920/8620333

transform属性:https://stackoverflow.com/a/15256339/8620333(与perspective相同)

will-change属性:https://stackoverflow.com/a/53680794/8620333

答案 2 :(得分:-1)

首先,该元素相对于其第一个定位(非静态)祖先元素定位。

在这种情况下,绝对位置对同级而不对祖先有效。

关于祖先和兄弟姐妹,有一个很不错的文档:Ancestors and siblings

    function ZombieDirectionChanger(o){
                console.log("Camera position has changed");
                zombie.lookAt(camera.position);
                console.log("Zombie has been rotated towards you");
            }

    controls.addEventListener('change', ZombieDirectionChanger);

.container {
  background: lightblue;
  position: relative;
}

.box-orange {
  background: orange;
  height: 100px;
  width: 100px;
  position: relative;
  top: 100px;
  left: 100px;
  z-index: 2;
}

.box-blue {
  background: lightskyblue;
  height: 100px;
  width: 100px;
  /*position: static;*/
}

.box-green {
  background: lightgreen;
  height: 100px;
  width: 100px;
  position: relative;
  top: -105px;
  left: 105px;
  z-index: 2;
}

.box-grey {
  background: grey;
  height: 100px;
  width: 100px;
  position: absolute;
}

如果我将元素放置在div容器之后,则一切正常,没有问题

Documentation of postion

关于第二部分,那个盒子出现在那儿,因为盒子绿色与盒子绿色的顶部和右边无关紧要,知道吗?病了一个例子:

<div class="container">
  <div class="box-grey"></div>
  <div class="box-orange"></div>
  <div class="box-blue"></div>
  <div class="box-green"></div>
</div>
.container {
  background: lightblue;
  position: relative;
}

.box-orange2 {
  background: orange;
  height: 100px;
  width: 100px;
  position: relative;
  z-index: 2;
}

.box-orange {
  background: orange;
  height: 100px;
  width: 100px;
  position: relative;
  top: 100px;
  left: 100px;
  z-index: 2;
}

.box-blue {
  background: lightskyblue;
  height: 100px;
  width: 100px;
  /*position: static;*/
}

.box-green {
  background: lightgreen;
  height: 100px;
  width: 100px;
  position: relative;
  top: -105px;
  left: 105px;
  z-index: 2;
}

.box-grey {
  background: grey;
  height: 100px;
  width: 100px;
  position: absolute;
}

.box-yellow {
  background: yellow;
  height: 100px;
  width: 100px;
  position: absolute;
}

您可以看到,无论顶部和右侧是否在同级中,灰色和黄色框都不会改变行为。