Why aren't my absolutely-positioned elements located where I expect?

孤者浪人 提交于 2019-11-27 05:39:23

To correctly understand this, you need to refer to the official sepcification where you find the equation the element must satisfy:

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

We don't have any border and padding so in your case it will simply be:

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

And if you read under you will find this:

  1. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'.

So in your case, you have set a height and kept top/bottom to auto thus top will be set to static position

..More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'..

To make it easy, it's the position of the element if you didn't set position:absolute.

Here is an easy illustration to better understand

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

Note the static position of the first element that is kept if we add position:absolute. We didn't specify any top value so the browser will use a default one that is the one of the position:static (default position) of the element.

If you don't want this, simply set the top value and you fall into this rule:

  1. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'

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

Same logic apply to the left property


You may also notice the use of the word containing block which very important here and explained in the same specification

The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:

...

  1. If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:

...

And it's not enough as there is other properties (listed below) that also establish a containing block so you can have an element positionned relatively to an ancestor that is not positionned!

The filter property: https://stackoverflow.com/a/52937920/8620333

The transform property: https://stackoverflow.com/a/15256339/8620333 (same thing with perspective)

The will-change property: https://stackoverflow.com/a/53680794/8620333

Ted Fitzpatrick

You must always set top:0; left:0; on absolutely-positioned elements (or whatever values you want for top, right, bottom, left).

First of all, the element is positioned relative to its first positioned (not static) ancestor element.

In this case, the position absolute works with the sibling, not with the ancestor.

About the ancestors and siblings, there are a godd documentation about it : Ancestors and siblings

.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 class="container">
  <div class="box-grey"></div>
  <div class="box-orange"></div>
  <div class="box-blue"></div>
  <div class="box-green"></div>
</div>

If i put the element after the div container all works without problem

Documentation of postion

About the second part, that box appears there because the box-gery doesnt matter about the top and right of box-green, got it? Ill put an example:

.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;
}
<div class="container">
  <div class="box-orange2"></div>
  <div class="box-grey"></div>
  <div class="box-orange"></div>
  <div class="box-yellow"></div>
</div>

You can see that the grey and yellow boxes do not change the behavior even if the top and right are in the sibling or not.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!