1.盒模型是CSS的基石之一牵祟,它指定元素如何顯示以及(在某種程度上)如何相互交互痪蝇。頁面上的每個元素被看作是一個矩形框,這個框由元素的內(nèi)容喻旷、內(nèi)邊距生逸、邊框和外邊距組成。
內(nèi)邊距出現(xiàn)在內(nèi)容周圍且预。如果在元素上添加背景槽袄,那么背景會應用于由內(nèi)容和內(nèi)邊距組成的區(qū)域。添加邊框會在內(nèi)邊距的區(qū)域外邊加一條線锋谐。在邊框的外邊是外邊距遍尺。外邊距是透明的。一般使用它控制元素之間的間隔涮拗。
在CSS中乾戏,width和height指的是內(nèi)容區(qū)域的寬度和高度迂苛。增加內(nèi)邊距、邊框鼓择、外邊距不會影響內(nèi)容區(qū)域的尺寸灾部,但是會增加元素框的總尺寸。假設框的每個邊上有10像素的外邊距和5像素的內(nèi)邊距惯退,如果希望這個框達到100像素寬赌髓,就需要將內(nèi)容的寬度設置為70像素。
2.外邊距疊加是一個相當簡單的概念催跪。簡單的說锁蠕,當兩個或者更多垂直外邊距相遇時,它們將形成一個外邊距懊蒸。這個外邊距的高度等于兩個發(fā)生疊加的外邊距的高度中的較大者荣倾。
當一個元素包含在另一個元素中時(假設沒有內(nèi)邊距或者邊框?qū)⑼膺吘喾指糸_),它們的頂或底外邊距也會發(fā)生疊加骑丸。盡管看上去有些奇怪舌仍,但是外邊距甚至可以與自身發(fā)生疊加。假設有一個空元素通危,它有外邊距铸豁,但是沒有內(nèi)邊距和邊框。在這種情況下菊碟,頂外邊距與底外邊距就碰到了一起节芥,它們會發(fā)生疊加。
只有普通文檔流中塊框的垂直外邊距才會發(fā)生外邊距疊加逆害。行內(nèi)框头镊、浮動框或絕對定位框之間的外邊距不會疊加。
3.CSS中有3種基本的定位機制:普通流魄幕、浮動和絕對定位相艇。顧名思義,普通流中元素框的位置由元素在HTML中的位置決定纯陨。
塊級框從上到下一個接一個地垂直排列坛芽,框之間的垂直距離由框的垂直編劇計算出來。
行內(nèi)框在一行中水平排列队丝∶夷伲可以使用水平內(nèi)邊距欲鹏、邊框和外邊距調(diào)整它們的水平間距机久。但是垂直內(nèi)邊距、邊框赔嚎、外邊距不影響行內(nèi)框的高度膘盖。同樣在行內(nèi)框設置顯式的高度和寬度也沒有影響胧弛。但是設置行高可以增加這個框的高度。
4.CSS的position屬性設置元素的定位方式侠畔,為將要定位的元素定義定位規(guī)則结缚。該屬性在將動畫特效腳本化時尤其有用。初始值為static软棺。
定位元素是計算后位置屬性為relative红竭、absolute、fixed或sticky的元素喘落。
相對定位元素是計算后位置屬性為relative的元素 茵宪。
絕對定位元素是計算后位置屬性為absolute或fixed的元素。
粘性定位元素是計算后位置屬性為sticky的元素瘦棋。
static
該關鍵字指定元素使用正常的布局行為稀火,即元素在文檔流中當前的布局位置。此時 top, right, bottom, left 和 z-index 屬性無效赌朋。
relative
該關鍵字下凰狞,元素先放置在未添加定位時的位置,再在不改變頁面布局的前提下調(diào)整元素位置(因此會在此元素未添加定位時所在位置留下空白)沛慢。position:relative 未定義對 table-*-group, table-row, table-column, table-cell, table-caption 元素應用的效果赡若。
absolute
不為元素預留空間,通過指定元素相對于最近的非 static 定位祖先元素的偏移团甲,來確定元素位置斩熊。絕對定位的元素可以設置外邊距(margins),且不會與其他邊距合并伐庭。
fixed
不為元素預留空間粉渠,而是通過指定元素相對于屏幕視口(viewport)的位置來指定元素位置。元素的位置在屏幕滾動時不會改變圾另。打印時霸株,元素會出現(xiàn)在的每頁的固定位置。fixed 屬性會創(chuàng)建新的棧上下文集乔。當元素祖先的 transform 屬性非 none 時去件,容器由視口改為該祖先。
sticky
元素先按照普通文檔流定位扰路,然后相對于該元素在流中的 flow root(BFC)和 containing block(最近的塊級祖先元素)定位尤溜。在所有情況下(即便被定位元素為 table 時),該元素定位均不對后續(xù)元素造成影響汗唱。當元素 B 被粘性定位時宫莱,后續(xù)元素的位置仍按照 B 未定位時的位置來確定。position: sticky 對 table 元素的效果與 position: relative 相同哩罪。
5.相對定位是一個非常容易掌握的概念授霸。如果對一個元素進行相對定位巡验,它將出現(xiàn)在它所在的位置上。然后可以通過設置垂直或者水平的位置碘耳,讓這個元素“相對于”它的起點移動显设。如果將top設置為20像素,那么框?qū)⒊霈F(xiàn)在原位置頂部下面20像素的地方辛辨。如果將left設置為20像素捕捂,那么會在元素左邊創(chuàng)建20像素的空間,也就是將元素向右移動斗搞。在使用相對定位的時绞蹦,無論是否移動元素仍然占據(jù)原來的空間。因此榜旦,移動元素會導致它覆蓋其他框幽七。
6.相對定位元素并未脫離文檔流,而絕對定位元素則脫離了文檔流溅呢。在布置文檔流中其他元素時澡屡,絕對定位元素不占據(jù)空間。絕對定位元素相對于最近的非static定位的祖先元素定位咐旧。當這樣的祖先元素不存在時驶鹉,則相對于根級容器定位。
7.固定定位與絕對定位相似铣墨,但元素的包含塊為viewport視口室埋。該定位方式常見于創(chuàng)建在滾動屏幕時仍固定在相同位置的元素。
8.粘性定位是相對定位和固定定位的混合伊约。元素在跨越閾值之前為相對定位姚淆,之后為固定定位。
9.CSS中float屬性可以使一個元素脫離正常的文檔流屡律,然后被安放到它所在的容器的左端或者右端腌逢,并且其他文本和行內(nèi)元素環(huán)繞著它。浮動元素指那些float屬性不為none的元素超埋。
left
表明元素必須浮動在其所在的塊容器左側(cè)的關鍵字搏讶。
right
表明元素必須浮動在其所在的塊容器右側(cè)的關鍵字。
none
表明元素不進行浮動的關鍵字霍殴。
inline-start
關鍵字媒惕,表明元素必須浮動在其所在塊容器的開始一側(cè),在ltr腳本中是左側(cè)来庭,在rtl腳本中是右側(cè)妒蔚。
inline-end
關鍵字,表明元素必須浮動在其所在塊容器的結(jié)束一側(cè),在ltr腳本中是右側(cè)面睛,在rtl腳本中是左側(cè)絮蒿。
10.清除浮動可以對想要清除浮動的元素使用clear屬性尊搬,但是這個方法只是在同一塊級格式化上下文中沒有其他浮動元素時才是有效的叁鉴。如果不能使用清除浮動,另一種做法是浮動容器的限制塊級格式化上下文佛寿。
11.塊級格式化上下文
CSS > 譯文:理解CSS中的塊級格式化上下文
塊級格式化上下文(Block Formatting Context)是網(wǎng)頁CSS視覺渲染的一部分幌墓,并用于決定塊盒子的布局。在定位體系(Positioning Scheme)中它屬于常規(guī)流(Normal Flow)冀泻。根據(jù)W3C所言:
浮動常侣、絕對定位元素(position為 absolute或 fixed)、行內(nèi)塊元素 display:inline-block弹渔、表格單元格display:table-cell胳施、表格題 display:table-caption 以及 overflow 屬性值不為 visible 的元素(除了該值被傳播到視點 viewport 的情況)將創(chuàng)建一個新的塊級格式化上下文。
上面的引言差不多總結(jié)了一個BFC是如何形成的肢专。但讓咱們用另外一種更通俗易懂的方式來重定義它舞肆。一個BFC就是一個HTML盒子,它至少滿足以下條件之一:
float 的值不為 none
position 的值不為 static 或 relative
display 的值為 table-cell博杖、table-caption椿胯、inline-block、flex 或 inline-flex
overflow 的值不為 visiable
創(chuàng)建一個塊級格式化上下文
一個BFC可以顯式觸發(fā)剃根。如果我們想創(chuàng)建之哩盲,我們只需給它添加上面提到的任何一個CSS樣式。
比如狈醉,看下面的HTML:
<div class="container">
Some Content here
</div>
一個新的BFC可以通過給容器添加任意一個必要的CSS樣式來創(chuàng)建廉油,比如overflow: scroll,overflow: hidden苗傅,display: flex娱两,float: left,或 display: table 金吗。盡管上述條件都可以創(chuàng)建BFC十兢,但也會產(chǎn)生一些其他效果,如:
display: table 可能引發(fā)響應性問題
overflow: scroll 可能產(chǎn)生多余的滾動條
float: left 將把元素移至左側(cè)摇庙,并被其他元素環(huán)繞
overflow: hidden 將裁切溢出元素
所以無論何時旱物,當要創(chuàng)建一個BFC時,我們要基于需求選擇最恰當?shù)臉邮轿捞弧榱吮3忠恢滦韵海以诒疚牡乃欣又芯褂胦verflow: hidden。
.container { overflow: hidden;}
你可以自由選擇使用除 overflow: hidden 之外的其他樣式夕凝。
BFC中盒子的對齊
W3C規(guī)范道:
在BFC上下文中宝穗,每個盒子的左外側(cè)緊貼包含塊的左側(cè)(從右到左的格式里户秤,則為盒子右外側(cè)緊貼包含塊右側(cè)),甚至有浮動也是如此(盡管盒子里的行盒子 Line Box 可能由于浮動而變窄)逮矛,除非盒子創(chuàng)建了一個新的BFC(在這種情況下盒子本身可能由于浮動而變窄)鸡号。
簡單來說,如上圖所示须鼎,所以屬于BFC的盒子都左對齊(在從左到右的格式下)并且它們的左外側(cè)緊貼包含塊的左側(cè)鲸伴。在最后一個盒子中我們可以看到盡管左側(cè)存在一個浮動元素(棕色),另外一個元素(綠色)仍然緊貼包含塊的左側(cè)晋控。該情況的產(chǎn)生原理將在下文關于文字環(huán)繞的部分中討論汞窗。
BFC造成的外邊距折疊
在常規(guī)流中,盒子從包含塊的頂部開始一個個地垂直擺放赡译。兩個同胞盒子間的垂直舉例由兩個盒子各自的外邊距所決定仲吏,但不是二者外邊距之和。
為便于理解蝌焚,我們看個例子裹唆。
在上圖中,一個紅盒子(div)包含著兩個同胞綠元素(p)综看,一個BFC已經(jīng)創(chuàng)建了出來品腹。
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
</div>
相應的CSS是:
.container {
background-color: red;
overflow: hidden; /* creates a block formatting context */
}
p {
background-color: lightgreen;
margin: 10px 0;
}
理論上兩個同胞元素間的外邊距應當是二者外邊距之和(20px)但實際上卻是10px。這就是眾所周知的外邊距折疊(Collapsing Margins)红碑。如果同胞元素外邊距不同舞吭,將應用最大的那個。
使用BFC避免外邊距折疊
在討論了上面BFC折疊外邊距的情況后析珊,現(xiàn)在說避免折疊可能有點讓人摸不著頭腦羡鸥。但我們必須牢記于心的一件事是,相鄰塊級盒子(同胞)之間的垂直外邊距只有在它們處于同一個BFC時才會發(fā)生折疊忠寻。如果它們分屬于不同的BFC惧浴,就不會折疊了。所以奕剃,通過創(chuàng)建新的BFC我們可以避免外邊距折疊衷旅。
讓我們在早前的例子中添加第三個同胞元素,現(xiàn)在HTML是:
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
<p>Sibling 3</p>
</div>
CSS是:
.container {
background-color: red;
overflow: hidden; /* creates a block formatting context */
}
p {
background-color: lightgreen;
margin: 10px 0;
}
結(jié)果和上面一樣纵朋,即是說柿顶,折疊還是會發(fā)生并且三個同胞間分隔的垂直距離是10px。這是因為三個 p
標簽都從屬于同一個BFC操软。
現(xiàn)在我們修改第三個同胞元素嘁锯,使之成為一個新的BFC的一部分。現(xiàn)在的HTML變成了:
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
<div class="newBFC">
<p>Sibling 3</p>
</div>
</div>
CSS:
.container {
background-color: red;
overflow: hidden; /* creates a block formatting context */
}
p {
margin: 10px 0;
background-color: lightgreen;
}
.newBFC {
overflow: hidden; /* creates new block formatting context */
}
現(xiàn)在輸出的結(jié)果就有所不同了:
因為第二個和第三個同胞元素現(xiàn)在分屬于不同的BFC,它們之間就不會發(fā)生外邊距折疊了家乘。
使用BFC包含浮動
BFC可以包含浮動蝗羊。我們經(jīng)常遇到容器中含有浮動元素的情況。這種情況下容器元素沒有高度并且其浮動子元素脫離了網(wǎng)頁的常規(guī)流仁锯。我們通常用清除浮動解決這個問題耀找,最普遍的做法就是使用偽元素。但我們也可以通過創(chuàng)建一個BFC來解決問題扑馁。
看個例子:
<div class="container">
<div>Sibling</div>
<div>Sibling</div>
</div>
CSS:
.container {
background-color: green;
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}
在上面這個例子中涯呻,容器沒有任何高度凉驻,并且它包不住浮動子元素腻要。為解決此問題,我們通過添加 overflow: hidden
來在容器中創(chuàng)建一個新的BFC涝登。修改后的CSS成了:
.container {
overflow: hidden; /* creates block formatting context */
background-color: green;
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}
現(xiàn)在容器可以包住浮動子元素雄家,并且其高度會擴展至包住其子元素,在這個新的BFC中浮動元素又回歸到頁面的常規(guī)流之中了胀滚。
使用BFC避免文字環(huán)繞
有時候浮動DIV旁邊的文本會環(huán)繞它(如下圖1所示)而這種情況有時候并不如我們所愿趟济,我們想要下圖2的效果。要解決這個問題咽笼,我們可以用外邊距顷编,但也可以用BFC。
首先讓我們弄明白為何文字會環(huán)繞剑刑。要理解這個我們必須明白媳纬,當存在元素浮動的時候,盒模型如何工作施掏。這就是我早先討論BFC中對齊時候的遺留問題钮惠。我們通過下圖來看圖1到底發(fā)生了什么。
假設HTML是:
<div class="container">
<div class="floated">
Floated div
</div>
<p> Quae hic ut ab perferendis sit quod architecto, dolor debitis
quam rem provident aspernatur tempora expedita.
</p>
</div>
上圖整個黑色區(qū)域表示 p元素七芭,如我們所見素挽,p元素沒有移位但它疊在了浮動元素之下,而p元素的行盒子(即文本行)卻移位了狸驳,行盒子水平變窄來給浮動元素騰出了空間预明。
隨著文本的增加,最后文本將環(huán)繞在浮動元素之下耙箍,因為那時候行盒子不再需要移位撰糠,也就成了圖1的樣子。這就是為什么即便有浮動元素究西,段落仍緊貼包含塊的左側(cè)窗慎,而行盒子會變窄來給浮動元素騰位子。
如果我們能位移整個 p元素,這個環(huán)繞問題也就迎刃而解了遮斥。
在說解決方案之前峦失,我們再回顧下W3C規(guī)范:
在BFC上下文中,每個盒子的左外側(cè)緊貼包含塊的左側(cè)(從右到左
格式里术吗,則為盒子右外側(cè)緊貼包含塊右側(cè))尉辑,甚至有浮動也是如此
(盡管盒子里的行盒子 Line Box可能由于浮動而變窄),除非盒
子創(chuàng)建了一個新的BFC(在這種情況下盒子本身可能由于浮動而變窄)较屿。
據(jù)此隧魄,如果 p 元素創(chuàng)建一個新的BFC那它就不會再緊貼包含塊的左側(cè)了。給 p 元素添加 overflow: hidden 就能輕而易舉地辦到隘蝎。這解決了文本環(huán)繞浮動對象的問題购啄。
在多列布局中使用BFC
如果我們創(chuàng)建一個占滿整個容器寬度的多列布局,在某些瀏覽器中最后一列有時候會掉到下一行嘱么。這可能是因為瀏覽器四舍五入了列寬從而所有列的總寬度會超出容器狮含。但如果我們在多列布局中的最后一列里創(chuàng)建一個新的BFC,它將總是占據(jù)其他列先占位完畢后剩下的空間曼振。
我們來舉個三列布局的例子:
這是HTML:
<div class="container">
<div class="column">column 1</div>
<div class="column">column 2</div>
<div class="column">column 3</div>
</div>
CSS:
.column {
width: 31.33%;
background-color: green;
float: left; margin: 0 1%;
}/* Establishing a new block formatting context in the last column */
.column:last-child {
float: none;
overflow: hidden;
}
現(xiàn)在盡管盒子的寬度稍有改變几迄,但布局不會打破。當然冰评,對多列布局來說這不一定是個好辦法映胁,但能避免最后一列下掉。這個問題上彈性盒或許是個更好的解決方案甲雅,但這個辦法可以用來說明元素在這些環(huán)境下的行為解孙。