CSS 盒模型基于一对基本的概念——内部显示类型外部显示类型,都是通过display属性来指定。
外部显示类型决定盒子是块级还是内联,内部显示类型决定盒子内部的元素如何布局。本文的 CSS 盒模型就是总结其外部显示类型。

1.块级盒子和内联盒子

CSS中所有元素都被视为盒子,这些盒子分为两类——块级盒子(Block Box)和内联盒子(Inline Box)。这两类盒子在页面流和元素之间的关系方面表现出不同的行为。�

1.1 块级盒子�

一个元素被定义为块级元素,会表现出以下行为:

  • 每个盒子都单独占据一行。
  • widthheight属性可以发挥作用。
  • 内边距、外边距和边框会占据空间。
  • 盒子会在内联方向上扩展,并占据父容器在该方向上的所有可用空间。 ```html

这是一行文字

这是一行文字

  1. ![CSS3_盒模型_块级盒子_1650775999000.png](https://cdn.nlark.com/yuque/0/2022/png/21782783/1650776061673-d585ec2f-38d9-411d-9743-dc2d8869e29a.png#clientId=u3c674b1b-f3b5-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=udb68f1ec&margin=%5Bobject%20Object%5D&name=CSS3_%E7%9B%92%E6%A8%A1%E5%9E%8B_%E5%9D%97%E7%BA%A7%E7%9B%92%E5%AD%90_1650775999000.png&originHeight=526&originWidth=486&originalType=binary&ratio=1&rotation=0&showTitle=true&size=4115&status=done&style=stroke&taskId=u59bf033c-06e6-4b5b-a38f-19ab01f47dc&title=%E5%9D%97%E7%BA%A7%E7%9B%92%E5%AD%90%E7%89%B9%E6%80%A7 "块级盒子特性")
  2. <a name="KS6gn"></a>
  3. ### 1.1.1 内联方向扩展�
  4. 内联方向上盒子的宽度、内边距、边框和外边距的和必须等于父盒子的宽度,即满足下列等式:<br />![](https://cdn.nlark.com/yuque/__latex/7381de911d50a7911491ffdd55e2d139.svg#card=math&code=%7BP_w%7D%3D%7BC_%7Bml%7D%7D%2B%7BC_%7Bmr%7D%7D%2B%7BC_%7Bw%7D%7D%2B%7BC_%7Bbl%7D%7D%2B%7BC_%7Bbr%7D%7D%2B%7BC_%7Bpl%7D%7D%2B%7BC_%7Bpr%7D%7D&id=yI6WQ)<br />其中![](https://cdn.nlark.com/yuque/__latex/6aca28d62850a1728278fc8e7517810d.svg#card=math&code=C_%7Bml%7D&id=mHIf8)、![](https://cdn.nlark.com/yuque/__latex/827c074442695d3950058dd0069bd4ff.svg#card=math&code=C_%7Bmr%7D&id=HMu2R)和![](https://cdn.nlark.com/yuque/__latex/99b95d98fc0af6f91ac11e2fd7822cf7.svg#card=math&code=C_w&id=sWIvi)不指定,则默认为`auto`,![](https://cdn.nlark.com/yuque/__latex/c41c68ac1415614c94086e4cf544c258.svg#card=math&code=C_%7Bbl%7D&id=pXzRk)、![](https://cdn.nlark.com/yuque/__latex/af1b6159473065da67695ea621557802.svg#card=math&code=C_%7Bbr%7D&id=qfhiq)、![](https://cdn.nlark.com/yuque/__latex/79d13c491b9a9e11eb564b6ea2c3c0d2.svg#card=math&code=C_%7Bpl%7D&id=dUlqe)和![](https://cdn.nlark.com/yuque/__latex/af1b6159473065da67695ea621557802.svg#card=math&code=C_%7Bbr%7D&id=QR0ms)不指定,则默认为`0px`。�<br />如果不满足,浏览器会调整子盒子的`width`、`margin-left`和`margin-right`,尽最大可能满足等式。注意是“尽最大可能”,但并不保证一定能调整成功!�<br />下面是一个最基本的内联扩展的示例:�
  5. ```html
  6. <style>
  7. .parent {
  8. width: 800px;
  9. height: 200px;
  10. border: 10px solid red;
  11. }
  12. .child {
  13. width: 200px;
  14. height: 200px;
  15. background-color: green;
  16. }
  17. </style>
  18. <body>
  19. <div class="parent">
  20. <div class="child"></div>
  21. </div>
  22. </body>

CSS3_盒模型_内联扩展_1650776604000.png
借助开发者工具可以发现,根据代码的定义,子盒子只在父盒子内联方向上占据200px的位置,但是浏览器却自动将子盒子的margin-right调整为了600px。�
上面例子中,子盒子显式指定了width,没有指定外边距,而浏览器为其调整了margin-right的值,这涉及widthmargin-leftmargin-right三项间的调整规律,但是规律很复杂,这里仅列出一个常用技巧,子盒子居中:�
CSS3_盒模型_内联扩展_1650776809000.png

1.2 内联盒子�

一个元素被定义为块级元素,会表现出以下行为:

  • 盒子不会独占一行。
  • widthheight属性将不起作用。
  • 垂直方向的内边距、外边距以及边框会被应用,但是不会把其他内联盒子推开。
  • 水平方向的内边距、外边距以及边框会被应用,且会把其他内联盒子推开。 ```html

这是一段长长长长长长长长长长的文字
这是一段文字 这是另一段文字 这是一段文字
这是一段长长长长长长长长长长的文字

![CSS3_盒模型_内联盒子_1650777071000.png](https://cdn.nlark.com/yuque/0/2022/png/21782783/1650777115254-410f2589-984d-449c-b363-4fff4c68cab0.png#clientId=u3c674b1b-f3b5-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=uf452de97&margin=%5Bobject%20Object%5D&name=CSS3_%E7%9B%92%E6%A8%A1%E5%9E%8B_%E5%86%85%E8%81%94%E7%9B%92%E5%AD%90_1650777071000.png&originHeight=115&originWidth=632&originalType=binary&ratio=1&rotation=0&showTitle=true&size=6389&status=done&style=stroke&taskId=u26da9344-17b0-4500-85eb-0bf1f823410&title=%E5%86%85%E8%81%94%E7%9B%92%E5%AD%90 "内联盒子")
<a name="keBeP"></a>
# 2.盒模型
CSS盒模型由以下四个部分组成:

- Content(内容):这个区域是用来显示内容,大小可以通过设置`width`和`height`。
- Padding(内边距):包围在内容区域外部的空白区域,大小通过`padding`相关属性设置。
- Border(边框):边框包裹内容和内边距,大小通过`border`相关属性设置。
- Margin(外边距):这是最外面的区域,是盒子和其他元素之间的空白区域。大小通过`margin`相关属性设置。

![CSS3_盒模型_盒模型_1650777178000.png](https://cdn.nlark.com/yuque/0/2022/png/21782783/1650777222691-47014ed4-dacf-4718-ad79-e83ccfec15e6.png#clientId=u3c674b1b-f3b5-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u50f4a900&margin=%5Bobject%20Object%5D&name=CSS3_%E7%9B%92%E6%A8%A1%E5%9E%8B_%E7%9B%92%E6%A8%A1%E5%9E%8B_1650777178000.png&originHeight=300&originWidth=544&originalType=binary&ratio=1&rotation=0&showTitle=true&size=7374&status=done&style=stroke&taskId=uc932553e-5674-40a1-9646-2a1730bdf62&title=%E7%9B%92%E6%A8%A1%E5%9E%8B "盒模型")
<a name="IejzQ"></a>
## 2.1 标准盒模型�
在标准盒模型中,盒子的大小由内容、内边距和边框共通决定,`width`和`height`描述的是内容区的大小。�<br />![CSS3_盒模型_标准盒模型_1650777391000.png](https://cdn.nlark.com/yuque/0/2022/png/21782783/1650777421590-1df30263-0a23-49d6-9eb3-6b9ec220a802.png#clientId=u3c674b1b-f3b5-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=ub58bc0f9&margin=%5Bobject%20Object%5D&name=CSS3_%E7%9B%92%E6%A8%A1%E5%9E%8B_%E6%A0%87%E5%87%86%E7%9B%92%E6%A8%A1%E5%9E%8B_1650777391000.png&originHeight=300&originWidth=500&originalType=binary&ratio=1&rotation=0&showTitle=true&size=6903&status=done&style=stroke&taskId=u3d9079c0-b37c-4afc-8ec0-b8182057bb6&title=%E6%A0%87%E5%87%86%E7%9B%92%E6%A8%A1%E5%9E%8B "标准盒模型")<br />假设定义了如下盒子:�
```css
.box {
  width: 350px;
  height: 150px;
  margin: 25px;
  padding: 25px;
  border: 5px solid black;
}

那么盒子的总宽度就是410px(即350+25+25+5+5),高度为210px(即150+25+25+5+5)。�

2.2 替代盒模型

替代盒模型是也叫IE盒模型,是IE浏览器使用的盒模型,后被加入CSS3当中。
替代盒模型的宽高即可见宽高,即width和height包括边框、内边距和内容,内容区宽高等于可见宽高减去边框和内边距。
CSS3_盒模型_替代盒模型_1650865910000.png
默认浏览器会使用标准模型。如果需要使用替代模型,可以为盒子设置 box-sizing: border-box 来转换。
同样对于上面的例子,盒子的总宽度就是width: 350px;的宽度,盒子的总高度就是height: 150px;的高度。一般来说,相同width和height的盒子,使用替代盒模型的盒子通常要比使用标准盒模型的盒子大。

3.外边距折叠

3.1 父子外边距折叠

父子外边距会在以下情况发生折叠:

  • 父子盒子之间没有borderpadding、元素或父盒子没有开启 BFC 模式,父子盒子的上外边距会合并。
  • 父子盒子之间没有borderpadding、元素或父盒子没有指定heightmin-height,父子盒子的下外边距会合并。
    <div class="box"></div>
    <!-- 上外边距折叠 -->
    <div class="parent">
      <div class="child"></div>
    </div>
    <!-- 下外边距折叠 -->
    <div class="box"></div>
    
    ```css .box { height: 50px; background-color: black; }

.parent { background-color: red; margin: 10px 0; }

.child { width: 150px; height: 150px; background-color: green; / 父子外边距折叠 / margin: 100px 0; }

![CSS3_盒模型_父子外边距折叠_1650866130000.png](https://cdn.nlark.com/yuque/0/2022/png/21782783/1650866162959-f7c801f0-bcc1-419d-8c5a-1c817377261c.png#clientId=u3753c8cb-85fc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=470&id=ua1f99635&margin=%5Bobject%20Object%5D&name=CSS3_%E7%9B%92%E6%A8%A1%E5%9E%8B_%E7%88%B6%E5%AD%90%E5%A4%96%E8%BE%B9%E8%B7%9D%E6%8A%98%E5%8F%A0_1650866130000.png&originHeight=587&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=true&size=4810&status=done&style=stroke&taskId=uabec74c3-7cac-4a39-83ca-3595a9293fa&title=%E7%88%B6%E5%AD%90%E5%A4%96%E8%BE%B9%E8%B7%9D%E6%8A%98%E5%8F%A0&width=1536 "父子外边距折叠")<br />在修正外边距折叠时,如果使用元素隔开,会出现如下特殊情况:�
```css
.parent::before,
.parent::after {
  content: "";
  /* display: block; */
  /* display: line; */
}

当伪元素content内容为空或空格时,使用display: line | block;无法修正父子外边距合并,必须要使用可视字符或指定至少1px高度才能生效。
而如果指定内部显示模式能开启 BFC 模式,就无需补充content的内容或者指定高度就能修正。
实际开发中使用如下方式修复问题,该方式常见于清除浮动当中:

.clearfix:before,
.clearfix:after {
    display: table;
    content: " ";
}

�3.2 兄弟外边距折叠

<div class="box top"></div>
<div class="box bottom"></div>
.box {
  width: 200px;
  height: 200px;
}

.top {
  background-color: red;
  /* 兄弟外边距折叠 */
  margin-bottom: 200px;
}

.bottom {
  background-color: green;
  margin-top: 100px;
}

CSS3_盒模型_兄弟外边距折叠_1650866268000.png

4.内联块级盒子�

display有一个特殊的值inline-block,它在内联和块之间提供了一个中间状态。该类型的盒子不会单独占据一行,但它可以设定宽度和高度,并避免((20220304133618-4nl8re3 “上面”))看到的重叠
一个元素被定义为行内块级元素,会表现出以下行为:

  • 盒子不会单独占据一行。
  • 设置widthheight属性会生效。
  • 内边距、外边距和边框会将其他元素从当前盒子周围“推开”。

在例子1.2中添加display: inline-block;,会看到一下情形:
CSS3_盒模型_行内块元素_1650866439000.png

参考文章