盒模型
概念
所有的HTML
元素都被一个看不见的盒子包围着,这个盒子被称为盒模型(Box Model)。
如图所示,是Chrome
浏览器所绘制的某个元素的盒模型示意图,由内容区(content)、内边距(padding)、边框(border)、外边距(margin)。
内容区
指盒子的主要内容区域,用来显示和存储元素的“真实”内容,通常可由 width
、min-width
、max-width
、height
、min-height
和 max-height
分别设置内容区的宽度、最小宽度、最大宽度、高度、最小高度、最大高度
内边距
指内容区与边框之间的距离,可使用padding
属性设置或者padding-top
、padding-bottom
、padding-left
、padding-right
分别可设置上、下、左、右四个方向上的距离。内边距不支持设置负值,可以设置百分比,且按照宽度计算
边框
指内边距与外边距间的距离,可使用boder
属性设置或者使用border-width
、border-style
、border-color
分别设置边框的宽度、样式、颜色等属性
外边距
指元素边框周围一定距离的空间,与内边距类似,可使用padding
属性设置或者margin-top
、margin-bottom
、margin-left
、margin-right
分别设置上、下、左、右四个方向上的距离。但外边距可设置负值,相邻元素之间的外边距大小遵循规则“正正按大,正负相加,负负最小”
分类
实际上,CSS的盒模型有两种,分别是标准盒模型和怪异盒模型,它们的区别主要体现在元素的width
属性是否只包含内容区的宽度。
标准盒模型
在标准盒模型中,widht属性只包含内容区content
的宽度。因此标准盒模型的宽度为:width
+padding
+border
+magin
。
元素可通过设置box-sizing: content-box
使用标准盒模型,这也是默认的属性。
怪异盒模型(IE盒模型)
在怪异盒模型中,width
属性不仅包含内容区content
宽度,还包括边框和内边距的宽度。因此标准盒模型的宽度为:width
+magin
。
元素可通过设置box-sizing: border-box
使用怪异盒模型。
BFC
概念
块级盒子(Block-level Box)和行内盒子(Inline Box)
块级元素和行内元素会生成上述盒模型所表达的块级盒子和行内盒子,这两种盒子类型是CSS
中用来描述HTML
元素的基本显示类型,可通过display属性的值来定义元素的显示类型。块级盒子的display
属性值通常为"block
",行内盒子的display
属性值通为"inline
"(并不绝对)。
BFC的定义
MDN的定义为:区块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视 CSS
渲染的一部分,是块级盒子(Block-level Box)布局过程发生的区域,也是浮动元素与其他元素交互的区域。
通俗来说,BFC
是一个独立的渲染区域,他规定了内部块级盒子的布局方式,此区域的布局不会受到BFC外部元素布局的影响。
注:实际开发中,BFC
中是允许存在行内元素的,但是上述定义却说BFC
是块级盒子的布局过程发生的区域,这是因为行内元素所存在的内联盒子在布局时会形成一个匿名块级盒子,该匿名块级盒子的布局行为与普通块级盒子类似。因此,内联盒子在BFC
中的布局行为可以看作是一种特殊的块级盒子布局。
BFC的产生条件
- 文档的根元素(
<html>
)。 - 浮动元素(
float
值不为none
的元素)。 - 绝对定位元素(
position
值为absolute
或fixed
的元素)。 - display值为
inline-block
、table
、inline-table
、table-cell
、table-caption
、table-row
、table-row-group
、table-header-group
、table-footer-group
、flow-root
overflow
值不为visible
或clip
的块级元素。contain
值为layout
、content
或paint
的元素。- 弹性元素(
display
值为flex
或inline-flex
元素的直接子元素),如果它们本身既不是弹性、网格也不是表格容器。 - 网格元素(
display
值为grid
或inline-grid
元素的直接子元素),如果它们本身既不是弹性、网格也不是表格容器。 - 多列容器(
column-count
或column-width
值不为auto
,且含有column-count: 1
的元素)。 column-span
值为all
的元素始终会创建一个新的格式化上下文,即使该元素没有包裹在一个多列容器中。
BFC的布局规则
- 内部的
Box
会在垂直方向,一个接一个地放置。 Box
垂直方向的距离由margin
决定。属于同一个BFC
的两个相邻Box
的margin
会发生重叠。- 每个盒子(块盒与行盒)的
margin box
的左边,与包含块border box
的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此。 BFC
的区域不会与float box
重叠。BFC
就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。- 计算
BFC
的高度时,浮动元素也参与计算。
BFC在开发中的作用
解决外边距重叠问题
假如页面中有两个div
元素,他们的样式设置如下:
#div1, #div2{
width: 100px;
height: 100px;
}
#div1 {
background-color: yellow;
margin: 20px;
}
#div2 {
background-color: aliceblue;
margin: 30px;
}
只看代码可能会理所当然的认为两个div
之间的边距应该是50px
,但通过调试工具发现实际上只有30px
。
这是因为当两个div
同时设置margin
的时候,它们接触地方的外边距会发生重叠,即实际边距为两者中最大的一个。其原因就是BFC的布局规则第二条所讲的属于同一个BFC
的两个相邻Box
的margin
会发生重叠。既然规则中说的是同属于一个BFC
下的两个DIV
会发生这种情况,那么只需将其放在不同的BFC
下,就可以解决这个问题。
如以下代码所示,在div2
上新包裹一个div标签,并设置属性overflow: hidden
创建一个BFC
区域,从而解决外边距重叠的问题。
#div1, #div2{
width: 100px;
height: 100px;
}
#div1 {
background-color: yellow;
margin: 20px;
}
#div2 {
background-color: aliceblue;
margin: 30px;
}
#div3 {
overflow: hidden;
}
包含内部浮动元素
假设div1
作为父元素,有div2
和div3
两个子元素,并且设置以下样式:
#div2, #div3{
width: 100px;
height: 100px;
}
#div1 {
border: 1px solid;
margin: 20px;
}
#div2 {
background-color: aliceblue;
}
#div3 {
background-color: grey;
float: left;
}
由上图可知,父元素div1
并没有包含浮动子元素div3
的高度,这便是经典的高度塌陷问题。
根据BFC
布局规则的第六条,计算BFC
的高度时,浮动元素也参与计算,因此可通过为div1
设置样式overflow: hidden
,使其创建一个BFC
的方式,消除因子元素浮动引起的高度塌陷。
排除外部浮动元素
假设有div1
和div2
两个元素,设置以下样式:
#div1 {
background-color: yellowgreen;
float: left;
}
#div2 {
background-color: lightblue;
}
如上图所示,当div1
设置浮动后,div2
中的文本会环绕在div1
周围。
根据BFC布局规则的第四条,BFC
的区域不会与float box
重叠,可以给div2
设置 overflow: hidder
属性从而创建一个独立的BFC
后,从而形成一种两栏布局,如下图所示:
1