CSS魔法堂:Absolute Positioning就這個樣

前言

當咱們以position:absolute之名讓元素脫離Normal flow的控制後,覺得經過lefttop屬性值便可讓元素得以無限的自由時,卻發現還有各類神祕的力量左右着它的來去,因而咱們意識到本身力量的微弱,開始迷茫不前。
後來有幸拾到各路前輩高人的祕笈,終於打通任督二脈,記錄在案以便往後查閱。css

以Normal flow爲基礎

Q:不是說好以左上角爲原點(0,0)嗎?怎麼top:auto;right:auto;bottom:auto;left:auto;時的效果和Normal flow中的是同樣的?html

<style type="text/css">
  #parent{
    background: blue;
  }
  #sibling{
    text-align: center;
    line-height: 100px;
    margin: 0 20px;
    height: 100px;
    background: red;
  }
  #protagonist{
    text-align: center;
    line-height: 100px;
    width: 200px;
    height: 100px;
    background: yellow;
    position: absolute;
  }
</style>
<div id="parent">
  <div id="sibling">position:static</div>
  <div id="protagonist">position:absolute</div>
</div>


A:那是由於Absolute positioning在初始化狀態時(top:auto;right:auto;bottom:auto;left:auto;),瀏覽器會生成一個看不見的採用Normal flow定位的虛擬盒子(hypothetical box),若虛擬盒子對應的盒子沒有設置top/right/bottom/left屬性值,則該盒子將與虛擬盒子重疊。
 所以當咱們僅僅設置position:absolute時,呈現出來的效果是跟position:static是無區別的。那這時咱們會有兩個疑問了,1. 既然top/right/bottom/left等默認值爲auto,那實際計算值是多少呢?2. 假如顯示設置top/right/bottom/left爲特定數值後,那效果又是如何的呢?
 若要回答上述問題,則先要理解定位參考系。一提及定位咱們必須找到對應的參考系,如相對定位那樣望文生義就知道它對應着某個參考系,而絕對定位則隱晦得多,咋看之下會讓咱們忽視參考系的重要性,而後糊里糊塗地理解和解讀它呈現的效果。
 絕對定位的參考系就是盒子所在的containing block,下面咱們來深刻一下吧!瀏覽器

定位參考系——containing block

 無論採用的是Normal flow、Floats仍是Absolute positioning,總之定位的參考系就是一個名爲containing block的四方盒子,但不一樣的position scheme會對應不一樣containing block。就Absolute positioning而言,首先會尋找最近的一個position:relative/fixed/absolute的父容器元素,若找到且父容器爲block-level element則以父容器的的padding box做爲containing block,若父容器爲inline-level element則根據父容器的directionCSS屬性值決定containing block;若一個都找不到則會以initial containing block做爲其的containing block。
更多關於containing block的信息可參考《CSS魔法堂:不得不說的Containing Block》
 所以top/right/bottom/left的實際值則是相對於containing block而言,咱們能夠經過el.offsetLeft/Top來獲取top和left的實際值。spa

絕對定位的奧義——top/right/bottom/left+box model

也許你們都見過如下這種水平垂直居中方式code

<style type="text/css">
      #parent{
        background: blue;
        width: 200px;
        height: 200px;
        position: relative;
      }
      #protagonist{
        background: yellow;
        width: 100px;
        height: 100px;
    
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
    margin: auto;
      }
    </style>
    <div id="parent">
      <div id="protagonist"></div>
    </div>


爲啥簡單設置top/right/bottom/left:0;margin:auto就輕鬆搞定這麼難搞的水平垂直居中呢?請看下圖

 當盒子採用絕對定位後,其top/right/bottom/left和box model以佔滿整個containing block爲目的,除非每一個屬性均設置的特定數值致使總體寬度或高度均小於containing block的寬度或高度。也就是獲得如下兩個等式:orm

  1. 垂直方向:'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing blockhtm

  2. 水平方向:'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block
     而後一切玄機則蘊藏在auto這個屬性值上了。blog

其中垂直方向上top/margin-top/height/margin-bottom/bottom能夠設置爲auto,而水平方向上則是left/margin-left/width/margin-right/right能夠設置爲auto。element

對於non-replaced element的垂直方向等式

margin-top/bottom設置爲auto時,實際值自動分配的狀況get

  1. top/height/bottom均不爲auto時,那麼margin-top/bottom二者的實際值相等,且足以知足等式1。

margin-top/bottom設置爲auto時,實際值爲0的狀況

  1. top/height/bottom均爲auto時,height的值由其子元素決定。top/bottom的值則根據虛擬盒子來決定,最終讓定位效果如同採用position:static通常,反正要讓等式1成立。

  2. top/bottom均不爲auto,而height爲auto時,height會自動計算以知足等式1。

  3. 其餘狀況height由子元素或自身屬性值決定,top/bottom由自身屬性值或以知足等式1來決定實際值。

注意:top/auto/bottom默認值爲auto,而margin-top/bottom默認值爲0。

對於non-replaced element的水平方向等式

margin-left/right設置爲auto時,實際值自動分配的狀況

  1. left/width/right均不爲auto時,那麼margin-left/right二者的實際值相等,且足以知足等式2。

margin-left/right設置爲auto時,實際值爲0的狀況

  1. left/width/right均爲auto時,width的值由其子元素決定。left/right的值則根據direction的值來決定,最終讓定位效果如同採用position:static通常反,正要讓等式2成立。

  2. left/right均不爲auto,而width爲auto時,width會自動計算以知足等式2。

  3. 其餘狀況width由子元素或自身屬性值決定,left/right由自身屬性值或以知足等式2來決定實際值。

注意:left/width/right默認值爲auto,而margin-left/right默認值爲0。

對於replaced element

 因爲replaced element自身有固有的width/height,所以當設置width:auto;height:auto時,其實際值就是元素固有的width/height。也就是width/height不存在爲知足等式2和1動態擴展/縮小實際值的狀況。結果就是除"2. top/bottom均不爲auto,而height爲auto時,height會自動計算以知足等式1。"和"2. left/right均不爲auto,而width爲auto時,width會自動計算以知足等式2。"兩條不知足外,其餘狀況均一致。

注意,IE5.5/6/7下會有如下例外:

  1. left/margin-left/margin-right/right均不爲auto而width爲auto時,IE5.5下width的實際值將由子元素決定;

  2. top/margin-top/margin-bottom/bottom均不爲auto而height爲auto時,IE5.5下height的實際值將由子元素決定;

  3. left/width/right均不爲auto,而margin-left/right爲auto時,IE5.5/6/7下margin-left/right的實際值爲0;

  4. top/height/bottom均不爲auto,而margin-top/bottom爲auto時,IE5.5/6/7下margin-top/bottom的實際值爲0.

Fixed positioning——Absolute positioning的子類

 對於position:fixed其實也屬於Absolute positioning,但它參考系永遠是由Viewport所產生的containing block而已,其餘均與上述內容一致。
注意:由Viewport所產生的containing block與initail containing block是不一樣的詳情請參考《CSS魔法堂:不得不說的Containing Block》

<style type="text/css">
  body{
    background: blue;
  }
  #protagonist{
    background: yellow;
    width: 100px;
    height: 100px;

    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
   }
</style>
<div id="protagonist">fsjohnhuang</div>


注意:IE6不支持position:fixed

總結

如有紕漏,望各位指正,謝謝!
尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/535...肥子John

感謝

深刻理解CSS絕對定位
10 Visual formatting model details
KB012: 絕對定位( Absolute positioning )
https://www.w3.org/TR/CSS21/visuren.html...

相關文章
相關標籤/搜索