系列文章
CSS 盒模型
要说两种盒模型,那自然要先说一下,什么是 CSS 的盒模型。
事实上,所有HTML元素可以看作盒子。在 CSS 中,box model 这一术语是用来设计和布局时使用。
而这个盒子,由四个部分组成:
| 属性 | 内容 |
|---|---|
| margin | 外边距,可以当做盒子与盒子之间的距离 |
| border | 边框,可以当做是盒子的厚度 |
| padding | 内边距,可以当做盒子边框于其中容纳物的距离 |
| content | 内容,即盒子中存放文本或图片的区域 |
下图可以很好的说明 CSS 的盒子模型;

标准模型和 IE模型(怪异盒子)
在 CSS 中,我们可以通过
box-sizing: conent-box;将盒子设置为标准模型(盒子默认为标准模型)box-sizing: border-box;将盒子设置为 IE 模型(也叫做怪异盒子)
那么这两种模型,有何种区别呢?
标准模型
widt = content
也就是说,如果我们给一个标准盒子设定:
content-box {
width: 100px;
height: 100px;
border: 50px solid;
padding: 50px;
}
那么这个盒子如下图所示:

它在页面中实际占有的宽高为:(50px * 2)(border) + (50px * 2)(padding) + 100px(content) = 300px
IE 模型
widt = content + padding + border
给这个 IE 模型的盒子以上述相同的设置,效果如下所示:

它在页面中实际占有的宽高为:100px,但可以看到,由于 border + padding 已经等于 100px 了,所以这里 content 已经被压缩到只剩 0 了,实际盒子看起来已经无法很好的存放 content 内容了:

(tip:为了防止盒子在页面中实际占有面积超出预计以出现横向滚动条,通常会有开发者将最外部的盒子设为 IE 模型 )
真正的问题
你以为到这里就完了吗?不不不,接下来才是问题的开始,面试官不会问些不痛不痒的问题,又不能考察水平,又浪费时间。
这个时候通常会接着问外边距重叠,或者是 BFC 相关的问题了。
那么什么是边距重叠呢?我们来看个例子
<div class="futher">
<div class="child"></div>
</div>
<style>
* {
margin: 0;
padding: 0;
}
.futher {
background: deeppink;
}
.child {
margin-top: 50px;
height: 100px;
background: deepskyblue;
}
</style>
关于上述代码,你以为会是这个结果:

而实际上,结果是这样的:

父亲的盒模型如下:

那么到底发生了什么:为什么父亲的高度不是 150px,而是 100px?
要解释这个现象,我们需要引入一个概念:外边距重叠。
当块级元素 (block) 的上外边距 (margin-top) 和下外边距 (margin-bottom) 同时都有设定时只会只会保留最大边距,这种行为称为边界折叠 (margin collapsing),有时也翻译为外边距重叠。
那么这个外边距重叠到底是什么呢?
我们来看几个例子:
同一层相邻元素
两个相邻的块级元素,如果他们之间同时存在着上下外边距(后一个元素没有清除浮动),那么最终他们之间的外边距并不等于上下外边距之和,而等于其中较大的那一个:
<style>
.box-1 {
width: 100px;
height: 100px;
margin-bottom: 50px;
background-color: aqua;
}
.box-2 {
width: 100px;
height: 100px;
margin-top: 50px;
background-color: blueviolet;
}
</style>
<div class="box-1"></div>
<div class="box-2"></div>
最终结果如图:

可以看到,box1 和 box2 之间的边距明显不是二者边距之和,而只为其中一半。
父元素和子元素之间没有内容
关于这个情况,MDN 是这么说的:
如果没有边框 border,内边距 padding,行内内容,也没有创建块级格式上下文或清除浮动来分开一个块级元素的上边界 margin-top 与其内一个或多个后代块级元素的上边界 margin-top;或没有边框,内边距,行内内容,高度 height,最小高度 min-height或 最大高度 max-height 来分开一个块级元素的下边界 margin-bottom与其内的一个或多个后代后代块元素的下边界 margin-bottom,则就会出现父块元素和其内后代块元素外边界重叠,重叠部分最终会溢出到父级块元素外面。
翻译成人话就是:
| 边距 | 内容 |
|---|---|
| margin-top | border、padding、inline content、BFC、清除浮动 |
| margin-bottom | border、padding、inline content、height、min-height、max-height |
如果父元素的 margin-top 或 margin-bottom 没有其中对应的部分而子元素设置了 margin-top 或 margin-bottom 就会出现外边距重叠,其现象为我们前面看到的

那么这里我们根据上述总结,随便给父元素添加一点内容,其结果如下:

可以看到,父元素已经如同我们所预期的那般,具有 150px 的高度了。
至于前面提到的 BFC,由于内容较多,完全可以单独提出来讲一章,这里就暂不展开了。