前言
《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
的元素
- 若不存在的position為absolute/relative/fixed的父block container,其CB為ICB。
若存在的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 )
文章列表