element.offsetParent爲包含element的祖先元素中,層級最近的定位元素。 也就是說,offsetParent必須知足三個條件:css
<div class="position-outer" style="position: relative;">
<div class="position" style="postion: relative;">
<div class="not-position">
<div class="box">
</div>
</div>
</div>
</div>
複製代碼
打印box元素的offsetParent:html
因而可知,box祖先元素中存在:position-inner是同時知足層級最近和定位兩個條件的。web
<div class="box"></div>
複製代碼
<div class="position-outer" style="position: relative;">
<div class="position" style="postion: relative;">
<div class="not-position">
<div class="box" style="display: none;"> <!-- 注意這裏! -->
</div>
</div>
</div>
</div>
複製代碼
<div class="position-outer" style="position: relative;">
<div class="position" style="postion: relative;">
<div class="not-position">
<div class="box" style="position: fixed;"> <!-- 注意這裏! -->
</div>
</div>
</div>
</div>
複製代碼
offsetWidth = content + (垂直滾動條的寬度) + padding + borderbash
<div class="box" style="">
</div>
複製代碼
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 12px solid red;
margin: 25px;
}
複製代碼
打印element.offsetWidth:
offsetWidth = 200(content) + 20 * 2(padding) + 12 * 2(border) = 264
element左上角相對於offsetParent左邊界的偏移值。post
有個疑問? element的左上角 與 offsetParent的左邊界如何定義?是content-box、padding-box仍是margin-box?spa
<div class="position">
<div class="box">
</div>
</div>
複製代碼
.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;
}
複製代碼
很明顯,box的offsetParent爲postion3d
打印box.offsetLeft和box.offsetTop:在文檔流中,box的整個margin-box是在position的content-box中的,由此可猜想:code
box.offsetLeft = position.paddingLeft + box.marginleft = 35 + 25 = 60cdn
真的是這樣嗎?其實並無那麼簡單,須要分兩種狀況討論:htm
element.offsetLeft是指element的border-box左上角相對offsetParent的content-box的偏移量
因爲position: relative的元素並無脫離文檔流,所以,也須要加入到offseLeft/offsetTop的計算中
修改box css屬性:
.box {
position: relative; /* 新增的 */
top: 31px; /* 新增的 */
left: 31px; /* 新增的 */
width: 200px;
height: 100px;
padding: 20px;
border: 12px solid red;
margin: 25px;
}
複製代碼
再次打印box.offsetLeft和box.offsetTop:
二者的值都增長了31,也就是top和left屬性對應的值,由此更新計算公式:
element.offsetLeft = offsetParent.paddingLeft + element.left + element.marginLeft
可是,以上都是在最簡單的狀況下計算的,即element與element.offsetParent之間沒有其它層級的元素存在!
咱們在element與element.offsetParent之間再插入一個元素:
<div class="position">
<div class="middle"> <!-- 新增的 -->
<div class="box">
</div>
</div>
</div>
複製代碼
.parent {
width: 30px;
height: 150px;
padding: 11px;
border: 12px solid pink;
margin-left: 13px;
}
複製代碼
打印box.offsetLeft和box.offsetTop:
二者的值又變化了!相比上次又增長了36,正好是parent的marginLeft、borderLeft 、paddingLeft之和,11 + 12 + 13 = 36,由此獲得最終的計算公式:
element.offsetLeft = offsetParent.paddingLeft + element.left + element.marginLeft + (element與element.offsetParent之間全部 在正常文檔流且position屬性不爲relative的元素 marginLeft、borderLeft、paddingLeft之和)
如今,咱們讓parent向右浮動:
.parent {
float: right;
width: 30px;
height: 150px;
padding: 11px;
border: 12px solid pink;
margin-left: 13px;
}
複製代碼
打印box.offsetLeft和box.offsetTop:
此次只有box.offsetLeft變化了,並且也能夠猜想到是因爲parent的右浮,box是其子元素,一塊兒右浮,致使box.offsetLeft變化的。
這下要怎麼計算?難道還要算浮動的距離嗎?
並不須要!只要藉助parent就能計算!仔細想一想,element與element.offsetParent必定是沒有浮動元素的,那麼對於parent,其offsetParent也就是box的offsetParent,即postition。
咱們打印下parent.offsetleft:
再計算box到parent之間的偏移量: box.left + box.marginLeft + parent.paddingLeft + parent.borderLeft + parent.marginLeft = 31 + 25 + 11 + 12 + 13 = 92
76 + 92 = 168,與box.offsetLeft一致,這也說明咱們的計算公式是正確的!
也就是說element的display屬性爲absolute或fixed,因爲fixed會致使offsetParent爲null,因此咱們將box的display設置爲absolute:
<div class="position">
<div class="box">
</div>
</div>
複製代碼
.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;
}
複製代碼
打印box.offsetLeft和box.offsetTop:
咱們知道,display屬性爲absolute或fixed的元素,是相對於包含塊的padding-box定位的,所以在計算offsetLeft時,就不須要考慮offsetParent的paddingLeft了。
而且,element是脫離文檔流的,也就是說,除了element.offsetParent,再也不與其它任何元素產生聯繫,也就不須要再考慮element與element.offsetParent之間的任何元素了。
所以,計算公式很是簡單:
element.offsetLeft = element.left + element.marginLeft