文章出處

前言

《CSS魔法堂:重新認識Box Model、IFC、BFC和Collapsing margins》中提到在沒有floated兄弟盒子時,line box的左右邊框會與所屬的containing block的左右content edge相接觸。那到底什么是containing block(abbr. CB)呢?
 containing block在CSS的visual formatting model中十分重要的理論基礎,因為盒子的寬/高度自動值/相對值的計算,相對/浮動/絕對定位,均依賴containing block

如何判斷盒子的containing block?

 一圖勝千言

initial containing block

 首先我們關注一個特殊的CB——initial containing block(abbr. ICB),可以將它作為“備胎”CB,注意是“備胎”而不是最外層的CB,因為CB們不存在嵌套關系,應該說CB間無任何直接關系。“備胎”顧名思義是說若盒子對應不上其他CB,至少還有它。"dear, i would be there 4 u 4ever" by ICB:)
 因為CB涉及到盒子的定位,因此我們還要關注另一個CSS屬性——direction。而ICB的direction則繼承自root element,也就是html元素。
 那ICB的尺寸和定位又是如何呢?ICB尺寸和定位與Viewport一致。說了跟沒說似的:(
 說起Viewport大家應該會想起開發mobile web時必備的<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">,這句元信息就是用來操作Viewport也就是說會影響到ICB。
 而Viewport的尺寸固定為 瀏覽器的工作區域尺寸 - 垂直/水平滾動條尺寸
通過JS獲取Viewport的高寬

;(function(exports){
  var doc = document,
      docEl = doc.documentElement,
      scrollLen = function(tpl){
    var muav = null,
            ret = 0,
            factory = document.createElement("div")

        factory.innerHTML = tpl
    doc.body.appendChild(muav = factory.firstChild)
    ret = muav.offsetWidth
    muav.remove()

    return ret
      }('<div style="position:absolute;overflow:scroll;height:10px;visiblity:hidden;">')

  var v = exports.viewport = function(prop){
    return v[prop]()
  }

  v['width'] = function(){
    return docEl.clientWidth || (window.innerWidth - getVScrollLen())
  }
  v['height'] = function(){
    return docEl.clientHeight || (window.innerHeight - getHScrollLen())
  }

  function getVScrollLen(){
    return docEl.scrollHeight !== docEl.offsetHeight ? scrollLen : 0
  }
  function getHScrollLen(){
    return docEl.scrollWidth !== docEl.offsetWidth ? scrollLen : 0
  }
}(window))

其實document.documentElement.clientHeight/clientWidth獲取的就是ICB的高寬,而window.innerHeight/innerWidth獲取的是瀏覽器的工作區域高寬。

2016/04/06追加

 ICB僅僅是尺寸與Viewport一致而已,但不是由Viewport所產生的,而是由根元素<html>所產生的,由"ICB的左上角與Canvas原點重合"就可知道這一點。而Viewport自身也會產生containing block,這個containing block的尺寸和左上角均與Viewport一致,就是說若由于Canvas尺寸大于Viewport導致產生滾動條時,拖動滾動條后,Viewport所產生的containing block也會跟隨移動,從而保持與Viewport重合。這時我們會想起position:fixed定位不就是這樣的嗎?確實position:fixed的定位參考系就是Viewport所生產的containing block了。

找啊找啊找朋友,找到一個好CB

對于display:static/relative的元素
 它的CB與最近一個父block container(block box/inline box/table cell)的content box重疊。
對于position:fixed的元素
 它的CB就是ICB。
對于position:absolute的元素

  1. 若不存在的position為absolute/relative/fixed的父block container,其CB為ICB。
  2. 若存在的position為absolute/relative/fixed的父block container
    2.1. 若block container不是inline box,則其CB與這個父block container(block box/inline box/table cell)的padding box重疊。
    2.2. 若block container是inline box,那情況就復雜些了。
     如果 'direction' 是 'ltr',包含塊的頂、左邊是祖先元素生成的第一個框的頂、左內邊距邊界(padding edges) ,右、下邊是祖先元素生成的最后一個框的右、下內邊距邊界(padding edges)

    <p style="border:1px solid red; width:200px; padding:20px;">
    T
    <span style="background-color:#C0C0C0; position:relative;">
            這段文字從左向右排列,紅 XX 和 藍 XX 和黃 XX 都是絕對定位元素,它的包含塊是相對定位的SPAN。 可以通過它們絕對定位的位置來判斷它們包含塊的邊緣。
            <em style="position:absolute; color:red; top:0; left:0;">XX</em>
            <em style="position:absolute; color:yellow; top:20px; left:0;">XX</em>
            <em style="position:absolute; color:blue; bottom:0; right:0;">XX</em>
    </span>
    </p>

    <p style="border:1px solid red; width:200px; padding:20px;">
    TEXT TEXT TEXT
    <span style="background-color:#C0C0C0; position:relative;">
        這段文字從左向右排列,紅 XX 和 藍 XX 和黃 XX 都是絕對定位元素,它的包含塊是相對定位的SPAN。 可以通過它們絕對定位的位置來判斷它們包含塊的邊緣。
        <em style="position:absolute; color:red; top:0; left:0;">XX</em>
        <em style="position:absolute; color:yellow; top:20px; left:0;">XX</em>
        <em style="position:absolute; color:blue; bottom:0; right:0;">XX</em>
    </span>
    </p>


     如果 'direction' 是 'rtl',包含塊的頂、右邊是祖先元素生成的第一個框的頂、右內邊距邊界 (padding edges) ,左、下邊是祖先元素生成的最后一個框的左、下內邊距邊界 (padding edges)

    <p style="border:1px solid red; width:200px; padding:20px; direction:rtl;">
    T
    <span style="background-color:#C0C0C0; position:relative;">
         這段文字從右向左排列,紅 XX 和 藍 XX 和黃 XX 都是絕對定位元素,它的包含塊是相對定位的SPAN。可以通過它們絕對定位的位置來判斷它們……
        <em style="position:absolute; color:red; top:0; left:0;">XX</em>
        <em style="position:absolute; color:yellow; top:20px; left:0;">XX</em>
        <em style="position:absolute; color:blue; bottom:0; right:0;">XX</em>
    </span>
    </p>

注意

雖然盒子的寬/高度自動值/相對值的計算,相對/浮動/絕對定位,均依賴CB,但CB并不限制盒子的尺寸。
正常情況:若子box尺寸>containing block尺寸,則子box溢出CB(溢出后的顯示效果由overflow屬性值決定)。
異常情況:IE5.5~6下當overflow:visible時,若子box的尺寸大于CB的尺寸而城撐大CB。

總結

搞掂,收工:)
尊重原創,轉載請注明來自: http://www.cnblogs.com/fsjohnhuang/p/5295859.html肥子John^_^

感謝

https://www.w3.org/TR/CSS2/visuren.html#containing-block
https://www.w3.org/TR/CSS21/visudet.html#containing-block-details
KB008: 包含塊( Containing block )


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()