本篇文章帶大家了解一下CSS 盒模型,介紹一下什么是外邊距折疊?什么情況下會(huì)出現(xiàn)外邊距折疊?并談?wù)劷鉀Q方法。
在 CSS 中,所有的元素都被一個(gè)個(gè)的 “盒子(box)” 包圍著,我們廣泛地使用兩種“盒子” —— 塊級(jí)盒子 (block box
) 和 內(nèi)聯(lián)盒子 (inline box
)。
什么是 CSS 盒模型?
在 CSS 中,盒模型(box model)是在設(shè)計(jì)和布局時(shí)使用。
盒模型的定義可以分成這幾部分:
- Content box: 這個(gè)區(qū)域是用來顯示內(nèi)容,大小可以通過設(shè)置
width
和height
. - Padding box: 包圍在內(nèi)容區(qū)域外部的空白區(qū)域; 大小通過
padding
相關(guān)屬性設(shè)置。 - Border box: 包裹內(nèi)容和內(nèi)邊距。大小通過
border
相關(guān)屬性設(shè)置。 - Margin box: 這是最外面的區(qū)域,是盒子和其他元素之間的空白區(qū)域。大小通過
margin
相關(guān)屬性設(shè)置。
塊級(jí)盒子完整地應(yīng)用了 CSS 盒模型,內(nèi)聯(lián)盒子只使用盒模型中定義的部分內(nèi)容。
box-sizing
box-sizing
屬性定義了瀏覽器應(yīng)該如何計(jì)算一個(gè)元素的總寬度和總高度。
content-box
(默認(rèn)值),即標(biāo)準(zhǔn)盒模型,width: 100px
指的是內(nèi)容區(qū)會(huì)有 100px 寬。- 盒子的大小 =
content(100px)
+padding
+border
- 盒子的大小 =
border-box
,即替代(IE)盒模型,width: 100px
指的是內(nèi)容區(qū) + 邊框 + 內(nèi)邊距
的總和是 100px 寬。- 盒子的大小 =
content
+padding
+border
=100px
- 盒子的大小 =
不論那種模型,margin 都是不計(jì)入實(shí)際大小 —— 當(dāng)然,它會(huì)影響盒子在頁面所占空間,但是影響的是盒子外部空間。
display
這里可以補(bǔ)充一個(gè)概念 — 內(nèi)部和外部顯示類型。
- 外部顯示類型,我們通過對盒子
display
屬性的設(shè)置,比如inline
或者block
,來控制盒子的是內(nèi)聯(lián)還是塊級(jí)。 - 內(nèi)部顯示類型,它決定了盒子內(nèi)部元素是如何布局的。
如果設(shè)置 display: flex
,在一個(gè)元素上,外部顯示類型是 block
,但是內(nèi)部顯示類型修改為 flex
。 該盒子的所有直接子元素都會(huì)成為 flex
元素,會(huì)根據(jù) 彈性盒子(Flexbox
)規(guī)則進(jìn)行布局。
還有一個(gè)特殊的值 — display: inline-block
,它在內(nèi)聯(lián)和塊之間提供了一個(gè)中間狀態(tài)。這對于以下情況非常有用:不發(fā)生換行,但可以設(shè)定寬度和高度,也就是說實(shí)現(xiàn)了塊級(jí)的部分效果:
- 設(shè)置
width
和height
屬性會(huì)生效。 padding
,margin
, 以及border
會(huì)推開其他元素。
行內(nèi)元素 / 塊級(jí)元素
HTML4 中,元素被分成兩大類: inline
(內(nèi)聯(lián)元素) 與 block
(塊級(jí)元素)。
1. 什么是行內(nèi)元素?
一個(gè)行內(nèi)元素只占據(jù)它對應(yīng)標(biāo)簽的邊框所包含的空間。
常見的行內(nèi)元素有 a
、 b
、 span
、 img
、 strong
、 sub
sup
、 button
、 input
、 label
、 select
、 textarea
2. 什么是塊級(jí)元素?
塊級(jí)元素占據(jù)其父元素(容器)的整個(gè)空間,因此創(chuàng)建了一個(gè)“塊”。通常瀏覽器會(huì)在塊級(jí)元素前后另起一個(gè)新行。
常見的塊級(jí)元素有 div
、ul
、ol
、 li
、 dl
、 dt
、 dd
、 h1
、 h2
、 h3
、h4
、 h5
、h6
、p
3. 區(qū)別?
-
格式上(默認(rèn)情況),行內(nèi)元素不會(huì)換行,而塊級(jí)元素都會(huì)換行。
-
內(nèi)容上(默認(rèn)情況),行內(nèi)元素只能包含數(shù)據(jù)和其他行內(nèi)元素。而塊級(jí)元素可以包含行內(nèi)元素和其他塊級(jí)元素。
-
在屬性上:
- 行內(nèi)元素
width
和height
設(shè)置無效(可以設(shè)置 line-height),- 內(nèi)邊距(
padding
)、外邊距(margin
) 和 邊框(border
) 在 上下方向 不會(huì)對其他元素產(chǎn)生影響。
- 塊級(jí)元素
width
和height
屬性可以發(fā)揮作用,- 內(nèi)邊距(
padding
)、外邊距(margin
) 和 邊框(border
) 會(huì)將其他元素從當(dāng)前元素周圍“推開”
- 行內(nèi)元素
外邊距(margin)折疊
塊的上外邊距(margin-top
)和下外邊距(margin-bottom
)有時(shí)合并(折疊)為單個(gè)邊距,其大小為單個(gè)邊距的最大值(或如果它們相等,則僅為其中一個(gè)),這種行為稱為 邊距折疊。
什么情況才會(huì)出現(xiàn)
2 個(gè)或多個(gè)毗鄰的的普通流中的塊元素垂直方向上的 margin 會(huì)折疊
- 毗鄰: 是指沒有被非空內(nèi)容、padding、border 或 clear 分隔開
- 垂直方向: 是指只有垂直方向的 margin 才會(huì)
如何解決?
-
創(chuàng)建了
BFC
的元素 和它的子元素/兄弟元素不會(huì)發(fā)生折疊 -
設(shè)置
padding
/border
,一些具體的場景:-
父元素的
margin-top
和子元素的margin-top
發(fā)生重疊。發(fā)生重疊是因?yàn)樗鼈兪窍噜彽模晕覀兛梢酝ㄟ^這一點(diǎn)來解決這個(gè)問題。我們可以為父元素設(shè)
border-top
、padding-top
值來分隔它們。 -
高度為
auto
的父元素的margin-bottom
和子元素的margin-bottom
發(fā)生重疊。發(fā)生重疊一個(gè)是因?yàn)樗鼈兿?鄰,一個(gè)是因?yàn)楦冈氐母叨炔还潭?。因此我們可以為父元素設(shè)置
border-bottom
、padding-bottom
來分隔它們,也可以為父元素設(shè)置一個(gè)高度,max-height
和min-height
也能解決這個(gè)問題。 -
是沒有內(nèi)容的元素,自身的
margin-top
和margin-bottom
發(fā)生的重疊。我們可以通過為其設(shè)置
border
、padding
或者高度來解決這個(gè)問題。
-
觸發(fā) BFC
的因素
float
(除了 none)overflow
(除了 visible)display
(table-cell / table-caption / inline-block)position
(除了 static / relative)