element.offsetParent

define

Element. offsetParent is the closest location element in the parent element that contains an element. That is, offsetParent must satisfy three conditions:

  • Is the ancestor of Element
  • The most close to the element
  • Is a positioning element, that is, the position property is not static
<div class="position-outer" style="position: relative;">
    <div class="position" style="postion: relative;">
        <div class="not-position">
        	<div class="box">
        	</div>
        </div>
    </div>
</div>
Copy the code

Print offsetParent of box element:

  • Position-outer, a positioning element of level 3
  • Position-inner, a positioning element of level 2
  • A non-position element of level 1, not-position

Position-inner satisfies both the level nearest and position conditions.

There is no location element in the ancestor element

<div class="box"></div>
Copy the code

Webkit kernel, Firefox special case

  • Element’s own display attribute is None
<div class="position-outer" style="position: relative;">
    <div class="position" style="postion: relative;">
        <div class="not-position">
        	<div class="box" style="display: none;"> <! -- Watch this! -->
        	</div>
        </div>
    </div>
</div>
Copy the code

  • Element’s own position attribute is fixed
<div class="position-outer" style="position: relative;">
    <div class="position" style="postion: relative;">
        <div class="not-position">
        	<div class="box" style="position: fixed;"> <! -- Watch this! -->
        	</div>
        </div>
    </div>
</div>
Copy the code

element.offsetWidth / element.offsetHeight

define

OffsetWidth = Content + (width of vertical scroll bar) + padding + border

  • In the case of no scroll bar
<div class="box" style="">
</div>
Copy the code
.box {
    width: 200px;
    height: 100px;
    padding: 20px;
    border: 12px solid red;
    margin: 25px;
}
Copy the code

  • In the case of scroll bars

element.offsetLeft / element.offsetTop

define

The offset of the upper-left corner of element relative to the left edge of offsetParent.

Question? What is the left margin between the upper-left corner of an Element and the offsetParent? Is it Content-box, padding-box or margin-box?

<div class="position">
    <div class="box">
    </div>
</div>
Copy the code
.position {
    position: relative;
    top:  0;
    left:  0;
    width: 400px;
    height: 200px;
    padding:  35px;
    border: 15px solid purple;
}

.box {
    width: 200px;
    height: 100px;
    padding: 20px;
    border:  12px solid red;
    margin:  25px;
}
Copy the code

Obviously, the offsetParent of box is postion

In the document stream, the entire margin-box of box is in the content-box of position.

box.offsetLeft = position.paddingLeft + box.marginleft = 35 + 25 = 60

Is it really so? In fact, it is not that simple, need to be divided into two cases:

Element is in normal document flow

Element. offsetLeft is the offset of the upper-left corner of element’s border-box relative to offsetParent’s Content-box

Since the position: relative element is not removed from the document flow, it also needs to be added to the offseLeft/offsetTop calculation

Modify box CSS properties:

.box {
    position: relative; /* 新增的 */
    top: 31px;          /* 新增的 */
    left: 31px;         /* 新增的 */
    width: 200px;
    height: 100px;
    padding: 20px;
    border:  12px solid red;
    margin:  25px;
}
Copy the code

Print box. OffsetLeft and box. OffsetTop again:

Both values are increased by 31, which corresponds to the top and left attributes, thus updating the formula:

element.offsetLeft = offsetParent.paddingLeft + element.left + element.marginLeft

However, this is done in the simplest case, where there are no other levels of elements between element and element.offsetparent!

We insert another element between element and element.offsetparent:

<div class="position">
    <div class="middle">    <! -- New -->
        <div class="box">
        </div>
    </div>
</div>
Copy the code
.parent {
    width: 30px;
    height: 150px;
    padding:  11px;
    border:  12px solid pink;
    margin-left:  13px;
}
Copy the code

Print box. OffsetLeft and box. OffsetTop:

The values of the two have changed again! Add 36 to parent marginLeft, borderLeft, paddingLeft, 11 + 12 + 13 = 36.

Element.offsetleft = offsetparent.paddingleft + element.left + element.marginleft + (All between element and element.offsetParent MarginLeft, borderLeft, paddingLeft sum of elements in normal document flow where position is not relative.)

There are floating elements between element and element.offsetParent

Now we float parent to the right:

.parent {
    float: right;
    width: 30px;
    height: 150px;
    padding:  11px;
    border:  12px solid pink;
    margin-left:  13px;
}
Copy the code

Print box. OffsetLeft and box. OffsetTop:

This time only box.offsetLeft changed, and we can guess that the box. OffsetLeft changed because the parent element floated right.

How do we calculate this? Do you have to calculate the floating distance?

Not necessarily! Just use parent to calculate! If you think about it, element and element.offsetParent must have no floating element, so for parent, its offsetParent is the offsetParent of box, i.e. Postition.

Let’s print out parent-offsetLeft:

Then calculate the offset between box and parent: box.left + box.marginLeft + parent.paddingLeft + parent.borderLeft + parent.marginLeft = 31 + 25 + 11 + 12 + 13 = 92

76 + 92 = 168, consistent with box. OffsetLeft, which also shows that our calculation formula is correct!

Element leaves the document flow

In other words, the display property of element is absolute or fixed. Since fixed causes offsetParent to be null, we set the display property of box to absolute:

<div class="position">
    <div class="box">
    </div>
</div>
Copy the code
.box {
    position: absolute; /* 新增的 */
    top: 31px;
    left:  31px;
    width: 200px;
    height: 100px;
    padding: 20px;
    border:  12px solid red;
    margin:  25px;
}

.position {
    position: relative;
    top:  0;
    left:  0;
    width: 400px;
    height: 200px;
    padding:  35px;
    border: 15px solid purple;
}
Copy the code

Print box. OffsetLeft and box. OffsetTop:

We know that elements with an absolute or fixed display attribute are positioned relative to the padding-box containing the block, so we don’t need to consider the paddingLeft of offsetParent when calculating offsetLeft.

Also, element is out of document flow, that is, it is no longer associated with any other element except element.offsetparent, and there is no need to consider any element between Element and element.offsetparent.

Therefore, the calculation formula is very simple:

element.offsetLeft = element.left + element.marginLeft