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