閱讀本文前,應(yīng)當(dāng)對于CSS盒模型以及視覺格式化模型中會產(chǎn)生的各種框(box,也可以成為盒子)以及各種不同的布局方式有比較準(zhǔn)確的認(rèn)識,可以閱讀杜瑤大神的兩篇文章,這兩篇文章也是對標(biāo)準(zhǔn)中相關(guān)章節(jié)的翻譯和闡述。
(1) 視覺格式化模型中的各種框
(2) 置換和非置換元素
或直接閱讀CSS2.1 SPEC中的相關(guān)章節(jié):
(1) Box model
(2) Visual formatting model
在講包含塊之前還是想先簡單說一下視覺格式化模型
1、CSS視覺格式化模型
標(biāo)準(zhǔn)中對于視覺格式化模型的闡述為:
how user agents process the document tree for visual media.
即用戶代理在視覺媒體下如何處理文檔樹,用戶代理最常見的比如瀏覽器,而負(fù)責(zé)頁面解析和渲染的就是瀏覽器的渲染引擎(現(xiàn)在更多地直接稱為瀏覽器內(nèi)核),文檔既可以包括HTML文檔,也包括其他通用標(biāo)記語言所編寫的文檔。在視覺格式化模型中,文檔樹中的每個元素都會根據(jù)盒模型產(chǎn)生0個或多個框,影響這個框的布局的因素有:
(1)框的尺寸和類型,比如塊級框和行內(nèi)級框的布局方式就是不同的。
(2)框的定位方式,display屬性絕對了一個元素所產(chǎn)生的框的定位方式,定位方式不同的框在布局時也有不同的規(guī)則。
(3)與其他框的關(guān)系,假如有兩個框,它們之間是包含關(guān)系還是同輩關(guān)系而所產(chǎn)生的布局是不相同的。
(4)其他的額外信息(比如視口的大小,置換元素的固有尺寸等)
從這個角度講,視覺格式化模型就是對上述這些因素是如何影響一個框的布局而進(jìn)行的詳細(xì)描述。
2、視口(viewport)
第一部分中出現(xiàn)了視口這個詞,直觀上看,我覺得視口可以理解為用戶代理用來呈現(xiàn)解析和渲染后的文檔樹的區(qū)域,用戶通過這個區(qū)域可以閱讀文檔得內(nèi)容,在瀏覽器中,視口一般就是瀏覽器用于呈現(xiàn)網(wǎng)頁的區(qū)域。
標(biāo)準(zhǔn)中對于視口的闡述為:
User agents for continuous media generally offer users a viewport (a window or other viewing area on the screen) through which users consult a document.
注意加粗的continuous media,我們平時所瀏覽的網(wǎng)頁就屬于連續(xù)媒體,而通過打印機(jī)打印的文檔內(nèi)容必須是分頁的,所以就是分頁媒體,即paged media(此處的解釋略粗糙,僅是個人的簡單看法)。網(wǎng)頁是連續(xù)的媒體,那么問題就來了,視口不可能跟隨網(wǎng)頁的大小而變化,因此視口在小于文檔的尺寸時,必須提供一種滾動機(jī)制,最常見的就是瀏覽器的滾動條,通過滾動條我們就可以瀏覽超出視口的文檔部分,也就是文檔中闡述的:
When the viewport is smaller than the area of the canvas on which the document is rendered, the user agent should offer a scrolling mechanism.
當(dāng)然關(guān)于視口的知識點(diǎn)可不只是上述的這么簡單,比如在移動web中,viewport的相關(guān)屬性對于移動web的開發(fā)至關(guān)重要,但本文暫不涉及其他關(guān)于視口的知識點(diǎn)。
3、包含塊(containing block)
一個網(wǎng)頁是由一個一個的框(box)所組成的,每一個框在頁面中都有自己的尺寸、位置以及其他的渲染屬性(如背景色,字體等),那么這些框在布局的時候,它們的位置是如何決定的呢?另外,如果沒有為框定義顯示的尺寸(width,padding,border,margin)等,那么它們的尺寸又是如何確定的呢?答案的關(guān)鍵點(diǎn)就是包含塊,個人認(rèn)為,包含塊是學(xué)習(xí)CSS布局時基礎(chǔ)中的基礎(chǔ),不過還好,這個概念也并不難理解。
首先看一下標(biāo)準(zhǔn)中對于包含塊的闡述:
The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element.
即視覺格式化模型中所產(chǎn)生的各種框,它們的位置和大小往往都是根據(jù)一個特定的矩形框邊緣來計算得到的, 這個矩形框就是這個box的包含塊。
注:如果講一個框的包含塊時,指的是它所處的包含塊,而不是它形成的包含塊。
那么該如何確定一個框的包含塊呢?標(biāo)準(zhǔn)中規(guī)定了相應(yīng)的規(guī)則:
3.1根元素的包含塊
根元素(HTML中就是html標(biāo)簽)的包含塊稱為初始包含塊:對于連續(xù)媒體(比如網(wǎng)頁),它具有視口的尺寸并且定位在畫布的原點(diǎn)(可以直觀理解為視口的內(nèi)容起始位置,如果初始包含塊的direction屬性為ltr,那么起點(diǎn)位置就是視口的左上角,如果為rtl,那么就為視口的右上角)。初始包含塊的direction與根元素的direction屬性相同,默認(rèn)為ltr,即從左到右。
特別注意:初始包含塊具有視口的尺寸,也就是說寬高都是和視口相同的,即使視口中出現(xiàn)了滾動
3.2元素定位為static(默認(rèn)值)或relative(相對布局)時的包含塊
對于定位屬性為static(默認(rèn)值)或relative(相對布局)的元素,其包含塊是由最近的祖先塊容器框的內(nèi)容區(qū)域構(gòu)成。
這一點(diǎn)也比較好理解,雖然出現(xiàn)了塊容器框和內(nèi)容區(qū)域兩個詞,對于CSS盒模型和視覺格式化模型中的各種框有所了解后應(yīng)該就能明白。下面有個簡單的例子:
##DEMO 1:static或relative定位的元素的包含塊
CSS代碼:
.container{
width: 1000px;
margin: 50px auto;
border: 2px solid #000000;
padding: 50px;
}
static定位的元素
3.3元素定位為absolute時的包含塊
對于position為absolute的元素,其包含塊為最近的擁有非static定位屬性(即position為relative,absolute或fixed)的元素所產(chǎn)生,有下面兩種情況:
<1>如果這個元素為一個塊容器框元素,那么包含塊由這個元素的內(nèi)邊距邊界(padding edge)形成
<2>如果這個元素是一個行內(nèi)元素,那么這個包含塊由包圍該行內(nèi)級元素的第一個行框和最后一個行框的box形成。如果行內(nèi)元素被分割成了多行,那么在CSS2.1中,包含塊則是未定義的。
如果沒有這樣的祖先,那么其包含塊就是初始包含塊
注:在分頁媒體中包含不一樣的情況,本文暫不討論分頁媒體中的情況
absolute的情況相對復(fù)雜一些,看以下例子:
##DEMO 2:絕對定位元素的包含塊(1)-塊容器框形成包含塊
CSS代碼:
.container{
width: 1000px;
margin: 50px auto;
border: 2px solid #000000;
padding: 50px;
position: relative;
}
.absolute-div-1{
position: absolute;
left: 0px;
top: 0px;
}
absolute定位的元素
效果如下:
##DEMO 3:絕對定位元素的包含塊(2)-行內(nèi)元素形成包含塊
DEMO3中,我們把container換成行內(nèi)元素span,為了更明顯地顯示效果,我們給body加了一個高度并且設(shè)置了背景色,并且為span和absolute-div-1設(shè)置了不同的字體顏色,代碼如下CSS代碼:
body{
margin: 0px;
font-size: 14px;
height: 500px;
background: #a0b3d6;
}
.container{
margin: 50px auto;
position: relative;
color: #eeeeee;
}
.absolute-div-1{
position: absolute;
color: #ff0000;
left: 0px;
top: 0px;
}
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
absolute定位的元素
在IE6/7中效果也相同,另外我們提到過,如果元素是一個行內(nèi)級元素,那么這個包含塊由包圍該行內(nèi)級元素的第一個行框和最后一個行框的box形成。我們來驗證標(biāo)紅部分的闡述,即把a(bǔ)bsolute-div-1的top定位改為bottom,即bottom:0px,效果如下:
這也驗證了標(biāo)準(zhǔn)中所闡述的內(nèi)容。
注:在IE6中,絕對定位元素如果只用bottom定位,但是形成包含塊的元素沒有觸發(fā)hasLayout時,bottom不會根據(jù)包含塊的底部來定位,這個bug通過zoom:1等屬性觸發(fā)hasLayout可以解決。
##DEMO 4:絕對定位元素的包含塊(4)-行內(nèi)元素被分割成多行時
視覺格式化模型中描述過,如果一個行內(nèi)級元素包含了塊級元素,那么這個行內(nèi)級元素就會被分割成2塊,并且都成為了塊級元素。我們把DEMO3中的container改動一下:
< span class= "container">
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
中間出來了一個div
absolute定位的元素
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
而chrome中的效果為:
可以看出,chrome中的絕對定位元素在定位時是基于被分割后形成的第二個框來定位的,而如果我們把絕對定位元素移動到分割元素之前,即:
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
absolute定位的元素
中間出來了一個div
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含塊行內(nèi)級包含
##DEMO 5:絕對定位元素的包含塊(4)-初始包含塊作為包含塊
如果一個絕對定位元素找到有非static定位屬性的祖先,那么初始包含塊就作為其包含塊,這里需要注意的是初始化包含塊的尺寸問題,2.1節(jié)中曾經(jīng)講過初始包含塊具有視口的尺寸,即使存在滾動時,DEMO代碼如下:CSS代碼:為了出現(xiàn)滾動,我們?yōu)閎ody加了1000px的高度
.body-for-demo4{
height:1000px;
background: #a0b3d6;
}
.absolute-div-2{
height: 100px;
width: 100px;
background: #03a9f4;
position: absolute;
bottom: 0px;
left:0px;
}
HTML代碼:
如果我們把body設(shè)置一個position:relative的屬性,那么絕對定位框就會跑到頁面底部了。
2.4元素定位為fixed時的包含塊
元素定位屬性為fixed時,對于連續(xù)媒體,包含塊由視口形成,對于分頁媒體,則由頁面區(qū)域形成。
position為fixed的元素特點(diǎn)是不隨頁面的滾動而滾動,它的包含塊由視口形成,這一點(diǎn)也比較好理解。但是IE6不支持fixed的屬性,可以使用css表達(dá)式或者h(yuǎn)ack的方式使IE6支持fixed。可參考:
http://caibaojian.com/468.html
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com