盒模型是CSS布局的基础,因为所有的HTML元素都能看做是一个一个的盒子。
CSS盒模型
CSS盒模型包含四个部分:

- Content:盒内容,文本和图片显示在这里
- Padding:内容周围的空白部分,padding是透明的
- Border:边框,边框围绕padding和内容
- Margin:边框外的空白部分,margin是透明的
相关属性
padding
padding是透明的,我们可以分别设置padding的宽度:padding-top,padding-left,padding-bottom,padding-right
margin
margin也是透明的,我们也可以分别设置margin的宽度:margin-top,margin-left,margin-bottom,margin-right
**需要注意的是,当两个盒子相邻时,它们之间的距离是两个盒子中较大的margin,而不是两个margin之和。这个现象叫margin-collapse**。
border
border可以分别设置宽度:border-top,border-left,border-bottom,border-right- 设置边框的样式
border-width设置边框的宽度(可以设置数值,也可以设置thick,medium,thin)border-style设置边框样式,如(dotted点状,solid实线,inset嵌入)border-color设置边框颜色- 以上三个属性可以通过
border简写直接设置border: 1px solid black
- 混合设置,如
border-top-width,border-right-color
元素宽高
width和height属性
元素的宽高通过width和height属性来设置。但是width和height属性设置的是内容即content area的宽高,元素的实际宽高需要将padding,border,margin计算进去。
IE盒子模型和W3C盒子模型
如上所述,W3C标准的盒模型在计算宽高时,是计算的内容部分的宽高。

但IE盒模型包含padding和border,所以在计算width和height时,会得到不一样的值。

指定盒模型
box-sizing属性可以指定使用元素的哪个宽高作为元素的整体宽高。
box-sizing: content-box:以内容为宽高
box-sizing: border-box:以content+border+padding为宽高
还可以将设定放在CSS reset部分:
1 | * { |
设定盒子的最大/最小宽高
min-width,max-width,min-height,max-height属性可以设定元素的最大/最小宽高。
设置元素的宽高可以使用数值,也可以设置百分比,百分比会按照元素父元素的宽高来计算元素的对应宽高。
内容溢出
当盒子内放置的内容超出盒子大小时,就会溢出。我们使用overflow来控制这种情况:
overflow: auto当内容过多时,溢出内容被隐藏,使用滚动条来滚动查看所有内容overflow: hidden溢出内容被隐藏overflow: visible溢出内容显示在盒子外面(默认行为)

CSS盒子类型
块级盒子(Block box)
可以堆放在其他盒子上的盒子(内容会单独占一行),可以设置宽高
行内盒子(inline box)
- 多个行内元素在一排时,会出现在一行
- 对行内盒子设置宽高无效
padding,margin横向有效,垂直方向无效- 行内盒子的高度可以通过
line-height来设置
行内块级盒子(inline-block box)
- 会像行内盒子一样,和其他行内盒子出现在一行
- 但是不会像行内盒子那样出现断行,也就是说,如果一行剩下的空间不够行内块级盒子放下全部内容,那么它会在新的一行开始内容
- 可以像块级盒子一样设置宽高
BFC
BFC(Block Formatting Context),即“块级格式化上下文”。它是页面中CSS渲染的一部分,在布局过程中生成块级盒子的区域。它像一个隔离的独立容器,容器里面的子元素不会影响到外面元素。容器内的长度大于容器长度时,会出现内部滚动,但是滚动不会影响父容器之外的布局。
触发条件
根元素本身就是BFC
float值不为noneoverflow值不为visibledisplay值为inline-block,table-cell,table-captionposition值为absolute或fixed
应用场景
自适应两栏布局
通常文本会围绕浮动元素,但有些时候,我们并不希望发生这样的情况:

我们想要Figure2的样式,
我们将元素内容列出来:
1 | <div class="container"> |
1 | .container { |

但我们注意看W3C给BFC的规范:
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
在BFC中,每一个盒子的左边外部边缘会挨着父容器的左边缘(如果是从右向左排版,则盒子右边缘挨着父容器的右边缘)。即使是浮动布局的情况下,这一点也不会改变(尽管父容器的子元素可能会因为浮动而尺寸缩小)。除非子元素创建一个新的BFC,这样它也会因为浮动布局而变窄。
也就是说,如果我们希望p元素不要围绕图片,那么可以通过给p建立一个BFC来实现。
1 | p { |

清除内部浮动
我们经常会遇到容器里面是浮动元素,于是容器的高度就塌陷到0的情况。
1 | <div class="container"> |
1 | .container { |

页面中只有两个孤独的div漂浮。.container因为没有高度,并不会显示出来。通常我们会设置一个空的伪元素去把容器敞开,但利用BFC,我们能更容易地处理这个情况。
1 | .container { |

防止垂直的margin重叠
1 | <div class="container"> |
我们创建一个div,中间包含3个p元素,此时如果给p元素设定margin值,上下相邻的两个margin是会塌陷的。
1 | .container { |

此时p元素之间的margin值是10px,而并不是20px。

如果我们还记得根元素整体也是一个BFC,那么我们就能理解,同一个BFC中是会发生margin collapse的,要想解决它,需要让元素属于不同的BFC。所以我们要建立一个新的BFC。
1 | <div class="container"> |
给新的BFC也设置overflow
1 | .container { |

通过设置元素在不同的BFC中避免了垂直方向的margin collapse。