(注1:如果有問(wèn)題歡迎留言探討芥牌,一起學(xué)習(xí)!轉(zhuǎn)載請(qǐng)注明出處峦椰,喜歡可以點(diǎn)個(gè)贊哦A淠)
(注2:更多內(nèi)容請(qǐng)查看我的目錄。)
1. 簡(jiǎn)介
前面在入門文章中講到了盒模型還有塊級(jí)元素和行內(nèi)元素√拦Γ現(xiàn)在我們來(lái)回顧并重新認(rèn)識(shí)一下盒模型物邑。
2. 再看盒模型
首先,要清楚一件事情滔金。CSS框模型描述了為文檔樹(shù)中的元素生成的矩形框色解,并根據(jù)可視化格式模型進(jìn)行布局。瀏覽器在解析和渲染頁(yè)面時(shí)會(huì)生成DOMTree 和RenderTree(此處會(huì)在后面詳細(xì)講解)餐茵。CSS作用的是RenderTree科阎,而盒模型就是RenderTree的節(jié)點(diǎn)。
每個(gè)盒子都有一個(gè)content area(例如文本钟病,圖像等)以及可選的padding area萧恕、border area盒margin area。每個(gè)區(qū)域的大小由下面定義的屬性指定肠阱。
margin票唆、border、padding屹徘、content分別定義了元素四種邊走趋,然后每種類型的邊的四條邊定義了一個(gè)盒子,分別是content box噪伊、padding box簿煌、border box、margin box鉴吹。如下圖所示:
以下四個(gè)盒子組成了一個(gè) box:
- content box:必備姨伟,由content area和4條content/inner edge組成;
- padding box:可選豆励,由padding和4條padding edge組成夺荒。若padding寬度設(shè)置為0,則padding edge與content edage重疊良蒸;
- border box:可選技扼,由border和4條border edge組成。若border寬度設(shè)置為0嫩痰,則border edge與padding edage重疊剿吻;
- margin box:可選,由margin和4條margin/outer edge組成串纺。若margin寬度設(shè)置為0丽旅,則margin edge與border edage重疊椰棘。
是不是很眼熟,是的魔招,如果你還記得box-sizing屬性的話晰搀。
CSS3中提供了一個(gè)新的屬性,box-sizing办斑,來(lái)控制和模型的表現(xiàn)形式外恕。box-sizing有三個(gè)取值,分別是content-box乡翅,border-box和inherit鳞疲。
(注:其實(shí)還有一個(gè)padding-box,width和height屬性包括內(nèi)容和內(nèi)邊距蠕蚜,但是不包括邊框和外邊距尚洽。只有Firefox實(shí)現(xiàn)了這個(gè)值,它在Firefox 50中被刪除靶累。)
- content-box
默認(rèn)值腺毫,表現(xiàn)形式同W3C標(biāo)準(zhǔn)和模型。 - border-box
表現(xiàn)形式同IE盒模型挣柬,常用值潮酒,經(jīng)常在css-reset中設(shè)置。 - inherit
規(guī)定應(yīng)從父元素繼承box-sizing屬性的值邪蛔。
現(xiàn)在急黎,我們終于明白了。所謂的W3C標(biāo)準(zhǔn)盒模型和IE盒模型只是在設(shè)置width和height時(shí)所指定的對(duì)象不同而已侧到。W3C標(biāo)準(zhǔn)盒模型是content-box勃教,而IE盒模型是 - border-box。
當(dāng)然匠抗,如果沒(méi)有特殊指定的情況下故源,我們默認(rèn)是使用W3C標(biāo)準(zhǔn)盒模型。如果不想指定box-sizing汞贸,想讓各瀏覽器都是用W3C標(biāo)準(zhǔn)盒模型心软,只要在html文件開(kāi)頭指定<!DOCTYPE html>即可。
另外著蛙,一個(gè)盒子的content area的寬高取決于如下的因素:
- 元素生成的盒子是否有“寬度”和“高度”屬性集
- 盒子里是否包含文本或其他盒子
- 盒子是否是table
etc...
盒模型寬高我們會(huì)在今后詳細(xì)討論。
而一個(gè)盒子的content area耳贬,padding area和border area的背景由生成元素的background屬性指定踏堡,而margin area的背景總是透明的。
3. 盒的生成與類型
上面討論了盒子的基本組成和在不同瀏覽器中的表現(xiàn)咒劲,這一節(jié)我們來(lái)看一下盒子的類型顷蟆。這里所描述的是CSS2.2中可生成的盒類型诫隅。CSS 視覺(jué)格式化模型的一部分工作是從文檔元素生成盒。生成的盒擁有不同類型帐偎,并對(duì)視覺(jué)格式化模型的處理產(chǎn)生影響逐纬。生成盒的類型取決于 CSS 屬性 display。盒的類型會(huì)影響其在視覺(jué)格式化模型中的表現(xiàn)削樊。
3.1 塊級(jí)元素Block-level Elements與塊盒Block Boxes
塊級(jí)元素是指源文檔中以塊(如段落)的形式被格式化豁生,生成主要塊級(jí)盒(principal block-level box)的元素。display 屬性取以下值會(huì)讓一個(gè)元素成為塊級(jí)元素: block 漫贞、 list-item 以及 table 甸箱。
塊級(jí)盒(Block-level Boxe)是參與塊格式化上下文( Block Formatting Context )的盒。每個(gè)塊級(jí)元素生成一個(gè)主要的塊級(jí)盒( principal block-level box)迅脐。 一些元素芍殖,比如li和list-item,生成額外的盒來(lái)放置項(xiàng)目符號(hào)谴蔑,這些額外的盒會(huì)相對(duì)于主要盒來(lái)擺放豌骏。不過(guò)多數(shù)元素只生成一個(gè)主要塊級(jí)盒。
主要的塊級(jí)盒( principal block-level box)將包含其后代盒和生成的內(nèi)容隐锭,同時(shí)參與定位體系 (Positioning Scheme )窃躲。
在CSS 2.2中,塊級(jí)盒(block-level box)也是一個(gè)塊容器盒 (block container box)成榜,除非它是一個(gè)表盒(table box)或替換元素(replaced elemen)的主盒(principal box)框舔。一個(gè)塊容器盒 (block container box)要么只包含塊級(jí)盒(block-level box),要么只建立一個(gè)內(nèi)聯(lián)的格式化上下文(Inline Formatting Context)并因此只包含行內(nèi)級(jí)盒(Inline-level Boxes)赎婚。
一個(gè)主盒(principal box)是塊容器盒 (block container box)的元素是一個(gè)塊容器元素(block container element)刘绣。display取如下值時(shí)可以是一個(gè)非替換元素(non-replaced element)生成一個(gè)塊容器(block container):'block', 'list-item' 和 'inline-block'。并非所有的塊容器盒都是塊級(jí)盒:非替換的行內(nèi)塊(non-replaced inline blocks) 和非替換的表格單元格 (non-replaced table cells) 也是塊容器但不是塊級(jí)的挣输。
既是塊級(jí)盒(block-level box)同時(shí)也是塊容器盒 (block container box)的盒稱作塊盒(block box) 纬凤。
這三個(gè)術(shù)語(yǔ),“塊級(jí)盒”撩嚼、“塊容器盒”停士、“塊盒”在意義明確時(shí)可簡(jiǎn)稱為“塊”(block)。
3.2 匿名塊盒(Anonymous block boxes)
有時(shí)需要添加補(bǔ)充性盒,這些盒稱為匿名盒(anonymous boxes), 它們沒(méi)有名字逻族,不能被 CSS 選擇符選中蜻底。
不能被 CSS 選擇符選中意味著不能用樣式表添加樣式。這意味著所有繼承的 CSS 屬性值為 inherit 聘鳞,所有非繼承的 CSS 屬性值為 initial 薄辅。
塊容器盒要么只包含行內(nèi)級(jí)盒要拂,要么只包含塊級(jí)盒。但通常文檔會(huì)同時(shí)包含兩者站楚。在這種情況下脱惰,將創(chuàng)建匿名塊盒來(lái)包含毗鄰的行內(nèi)級(jí)盒。
<div>
Some inline text
<p>followed by a paragraph</p>
followed by more inline text.
</div>
該段代碼將創(chuàng)建兩個(gè)匿名塊盒窿春,一個(gè)包含 <p> 前面的文本 (Some inline text)拉一, 一個(gè)包含 <p> 后面的文本(followed by more inline text), 結(jié)構(gòu)如下:
結(jié)果如下所示:
和 <p>元素不同, 開(kāi)發(fā)者不能控制這兩個(gè)匿名盒。對(duì)于可繼承屬性谁尸, 它們將取 <div> 的屬性值, 比如 font-size舅踪。對(duì)于非繼承屬性,值為初始值 良蛮,比如沒(méi)有指定 background-color, 值為初始值即 transparent抽碌,于是 <div> 背景可見(jiàn)。而 <p> 可以指定 background-color 决瞳。類似的货徙,這兩個(gè)匿名盒文本是一樣的顏色。如下:
<style>
div {
background-color: green;
font-size: 30px;
}
p {
background-color: red;
}
</style>
另一種將創(chuàng)建匿名塊盒的情況是皮胡,一個(gè)行內(nèi)盒包含了一個(gè)或幾個(gè)塊盒痴颊。當(dāng)一個(gè)行內(nèi)盒 inline box 包含一個(gè)文檔流內(nèi) In-flow 的塊級(jí)盒,這個(gè)行內(nèi)盒(及在同一行盒的 Line Box 它的行內(nèi)祖先)會(huì)在該塊級(jí)盒(及其連續(xù)的或者中間只被可折疊空白屡贺、脫離文檔流元素分隔的塊級(jí)同胞)的周圍打斷蠢棱,把行內(nèi)盒分離成兩個(gè)盒(甚至一邊為空也如此),各在塊級(jí)盒一邊甩栈。在打斷之前和打斷之后的行盒 Line Box 都被匿名塊盒包含泻仙,并且該塊級(jí)盒成為匿名塊盒的同胞。當(dāng)這樣的行內(nèi)盒受到相對(duì)定位影響量没,任何產(chǎn)生的移動(dòng)同樣影響到包含在其中的塊級(jí)盒玉转。如下:
<body>
<p>
This is anonymous text before the SPAN。
<span>This is the content of SPAN.</span>
This is anonymous text after the SPAN殴蹄。
</p>
</body>
p 元素包含一段匿名文本 C1 究抓,接著是一個(gè)塊級(jí)元素,隨后又是另一段匿名文本 C2 袭灯。結(jié)果是一個(gè)代表 body 的塊盒刺下,它包含了圍繞 C1 一個(gè)匿名塊盒、 span 的塊盒稽荧,和圍繞 C2 的另一個(gè)匿名塊盒橘茉。原來(lái)的行內(nèi)盒p被分割消失了。
當(dāng)一個(gè)元素導(dǎo)致了匿名塊盒的生成,則該元素上設(shè)置的屬性一樣能應(yīng)用于該元素生成的盒和該元素的內(nèi)容捺癞。例如,在上面例子中构挤,如果在 p 元素上設(shè)置了邊框髓介,則這個(gè)邊框?qū)嬙?C1 (在行的結(jié)尾開(kāi))和 C2 (在行的結(jié)尾閉)周圍。
<style>
p {
display: inline;
border: 1px solid red;
}
span {
display: block;
}
</style>
style保持不變筋现,再來(lái)看一下兩種情況:
<body>
<p>
This is anonymous text before the SPAN唐础。
<span>This is the content of SPAN.</span>
This is anonymous text after the SPAN。
<span>This is the content of SPAN.</span>
<span>This is the content of SPAN.</span>
This is anonymous text after the SPAN矾飞。
</p>
</body>
以及
<body>
<p>
This is anonymous text before the SPAN一膨。
<span>This is the content of SPAN.</span>
</p>
</body>
和
<body>
<p>
<span>This is the content of SPAN.</span>
</p>
</body>
說(shuō)明如果行內(nèi)盒包含多個(gè)塊盒,并且這些塊盒之間沒(méi)有夾雜內(nèi)容洒沦,將在這些塊盒前后創(chuàng)建匿名塊盒豹绪,即使其前后內(nèi)容為空。
3.3 行內(nèi)級(jí)元素Inline-level Elements和行內(nèi)盒Inline Boxes
行內(nèi)級(jí)元素(Inline-level Elements)是在源文檔中那些不為其內(nèi)容形成新的塊的元素申眼,其內(nèi)容以行形式分布(如瞒津,段落內(nèi)強(qiáng)調(diào)文本,行內(nèi)圖片等等)括尸∠矧剑“display”屬性取以下值時(shí)產(chǎn)生一個(gè)行內(nèi)級(jí)元素(inline-level element): 'inline'、'inline-table'和'inline-block'濒翻。行內(nèi)級(jí)元素(inline-level element)生成行內(nèi)級(jí)盒 (Inline-level Boxes) 屁柏,而這些盒會(huì)參與行內(nèi)格式化上下文 (Inline Formatting Context) 。
一個(gè)行內(nèi)盒是行內(nèi)級(jí)盒有送,且其內(nèi)容參與了該行內(nèi)盒的行內(nèi)格式化上下文淌喻。一個(gè) display 值是 inline 的不可替換元素會(huì)生成一個(gè)行內(nèi)盒。那些不是行內(nèi)盒的行內(nèi)級(jí)盒(例如可替換的行內(nèi)級(jí)元素 Replaced Inline-level Elements 娶眷、行內(nèi)塊元素 inline-block 似嗤、行內(nèi)表格元素 inline-table )被稱為原子行內(nèi)級(jí)盒 Atomic Inline-level Boxes ,因?yàn)樗鼈円詥我徊煌该骱械男问絹?lái)參與它們的行內(nèi)格式化上下文届宠。
我們用下面的例子來(lái)看一下它們的區(qū)別:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
<style>
em {
display: inline;
}
</style>
</head>
<body>
<div style="width:6em;">
<span>em之前的行內(nèi)盒</span>
<em>em形成的行內(nèi)盒</em>
<span>em之后的行內(nèi)盒</span>
</div>
</body>
</html>
結(jié)果如下:
發(fā)現(xiàn)em的內(nèi)容參與了em生成行內(nèi)盒的行內(nèi)格式化上下文豌注。
再看以下代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
<style>
em {
display: inline-block;
}
</style>
</head>
<body>
<div style="width:6em;">
<span>em之前的行內(nèi)盒</span>
<em>em形成的原子行內(nèi)級(jí)盒</em>
<span>em之后的行內(nèi)盒</span>
</div>
</body>
</html>
em生成的原子行內(nèi)級(jí)盒作為一個(gè)單一不透明盒與span生成的行內(nèi)盒區(qū)別開(kāi)來(lái)伤塌。
3.4 匿名行內(nèi)盒 Anonymous Inline Boxes
任何直接包含在塊容器元素中的文本(不在內(nèi)聯(lián)元素內(nèi))都必須作為匿名行內(nèi)元素處理。
一個(gè)HTML文檔如下:
<p>Some <em>emphasized</em> text</p>
p 產(chǎn)生一個(gè)塊盒轧铁,其中包含了一些行內(nèi)盒每聪。 emphasized 的盒是一個(gè)由行內(nèi)元素 em 生成的行內(nèi)盒,但其他盒( some 和 text 的)是由塊級(jí)元素 p 生成的行內(nèi)盒。后面這種盒被稱作匿名行內(nèi)盒药薯,因?yàn)樗鼈儧](méi)有相關(guān)的行內(nèi)級(jí)元素绑洛,沒(méi)法被選擇。這些匿名行內(nèi)盒繼承所有可繼承的屬性童本,非繼承的屬性取初始值(initial value)真屯。在上面例子中,匿名行內(nèi)盒的 color 從 p 那里繼承穷娱,但 background 為 transparent 绑蔫。
空白內(nèi)容,根據(jù) white-space 屬性泵额,如果可被折疊則不會(huì)產(chǎn)生任何匿名行內(nèi)盒配深。
注:
- 如果可根據(jù)上下文來(lái)清晰界定一個(gè)匿名盒的類型,則匿名行內(nèi)盒和匿名塊盒都可被簡(jiǎn)稱為匿名盒嫁盲。
- 在格式化表格時(shí)篓叶,還會(huì)有更多類型的匿名盒出現(xiàn)。
3.5 插入盒Run-in boxes
插入盒亡资,由 display:run-in 定義澜共,根據(jù)上下文來(lái)決定其為塊盒還是行內(nèi)盒。屬性根據(jù)插入盒的最終狀態(tài)(行內(nèi)級(jí)還是塊級(jí))應(yīng)用于其上锥腻。
4. 影響盒子類型的display屬性
看下表是CSS2.2的定義嗦董,CSS3的內(nèi)容我們會(huì)在今后講解。
該屬性與“float”和“position”相結(jié)合瘦黑,共同確定了為元素生成的盒的類型(三者關(guān)系會(huì)在今后講解)京革。其值如下:
- block
元素會(huì)生成一個(gè)塊盒(block box) - inline-block
元素會(huì)生成一個(gè)行內(nèi)級(jí)塊容器(inline-level block container),其本身作為一個(gè)獨(dú)立的原子行內(nèi)級(jí)盒參與流布局幸斥,就像一個(gè)替換元素一樣匹摇。而其內(nèi)部?jī)?nèi)容則按照塊盒進(jìn)行格式化。 - inline
生成行內(nèi)盒 - list-item
這個(gè)值會(huì)導(dǎo)致一個(gè)元素(例如甲葬,HTML中的LI)生成一個(gè)主塊盒(principal block box)和一個(gè)標(biāo)記盒(marker box)廊勃。 - none
元素不出現(xiàn)在格式化結(jié)構(gòu)中(也就是說(shuō),在視覺(jué)媒體中元素既不產(chǎn)生盒也不影響布局)经窖。其后代元素也不產(chǎn)生任何盒:該元素及其內(nèi)容會(huì)被從格式化結(jié)構(gòu)中完全移除坡垫。對(duì)后代元素設(shè)定 display 屬性不能覆蓋這個(gè)表現(xiàn)。 - table, inline-table, table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, table-caption
使元素表現(xiàn)像一個(gè)表格元素一樣画侣。
請(qǐng)注意冰悠,盡管“display”的初始值是“inline”,但用戶代理的默認(rèn)樣式表中的規(guī)則可能會(huì)覆蓋這個(gè)值配乱。
參考
https://www.w3.org/TR/css3-box/
https://www.w3.org/TR/CSS22/box.html
https://www.w3.org/TR/CSS22/visuren.html
http://www.w3.org/TR/CSS2/visuren.html
什么是BFC
CSS規(guī)范 > 9 視覺(jué)格式化模型 Visual Formatting Model
MDN-視覺(jué)格式化模型
CSS魔法堂:重新認(rèn)識(shí)Box Model溉卓、IFC皮迟、BFC和Collapsing margins