前言:外边距重叠与高度塌陷是在写前端页面的时候经常碰到的一个问题,所以我想通过这篇博客记录下这块的知识点,方便后续查阅。
问题1:外边距重叠(外边距合并)
首先来看下MDN给出的定义:
块级元素的上外边距 (margin-top)和下外边距 (margin-bottom)有时合并 (或者折叠) 为单个外边距,其大小取其中的最大者(如果相等,则取其中一个),这种行为称为边距折叠(margin collapsing)。
备注: 浮动元素和绝对定位元素的外边距不会折叠。
那么对应的有3种情况:
- 相邻元素之间
- 父元素和后代元素之间
- 空的块级元素
下面依次来看看这些情况。
相邻元素之间
代码:
HTML
|
|
CSS
|
|
可以看到上下两个元素本来应该是有150px
的距离,但是发生了外边距重叠,只会挑选最大的边距的值,结果只有100px
。
父元素和后代元素
代码:
HTML
|
|
CSS
|
|
在预想的情况下,父级盒子也就是section
元素的上下边距应该分别为13px
以及87px
,但是发生了外边距重叠,父块元素和其内后代块元素外边界重叠,重叠部分最终会溢出到父级块元素外面,导致上下的外边距都为87px
。
空的块级元素
代码:
HTML
|
|
CSS
|
|
在预想的情况下,中间的div
盒子应该将两个p
标签隔开100px
的距离,由于空元素的margin-top
直接贴到元素下边界的margin-bottom
,导致发生了外边距重叠。
问题2:高度塌陷
在浮动布局中,父元素默认是被子元素撑开的 当子元素浮动后,其会完全脱离文档流,子元素从文档流中脱离 将会无法撑起父元素的高度,导致父元素的高度丢失 父元素高度丢失后,其下的元素会自动上移,导致页面布局混乱。
比如现在有这样一个塌陷的案例:
代码:
HTML
|
|
CSS
|
|
因为父元素没有设置大小(或不设置高度)子元素浮动,子元素会跳出父元素的边界(脱离标准流)当父元素的高度为auto时,父元素的高度直接为0(父盒子将没有内容,不再有高度)。
BFC
首先来看看MDN官方的定义:
块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视 CSS 渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
理解:具有BFC特性的元素可以看作是一个隔离的独立的容器,容器里面的元素不会在布局上影响外面的元素,BFC具有普通容器所没有的特性。
BFC的作用
- 自适应两栏布局
- 阻止元素被浮动覆盖
- 清除内部浮动
- 防止外边距塌陷
- 解决高度塌陷问题
开启BFC的方法
- 根元素(
<html>
) - 浮动元素(
float
值不为none
) - 绝对定位元素(
position
值为absolute
或fixed
) - 行内块元素(
display
值为inline-block
) - 表格单元格(
display
值为table-cell
,HTML 表格单元格默认值) overflow
值不为visible
、clip
的块元素display
值为flow-root
的元素
所以就可以通过BFC的方式来解决上面遇到的问题1与问题2,现在就来看看怎么解决吧!
解决方法
外边距重叠
相邻元素之间
比如上面提到的 相邻元素之间 的情况,可以使用将两个div分别放入两个不同的容器中,设置容器的overflow
值不为 visible
、clip
,使其变为BFC,这样up
与down
两个盒子就置于不同的BFC中了,从而解决了外边距重叠。
代码:
HTML
|
|
CSS
|
|
父元素和后代元素
同样的可以利用刚才解决 相邻元素之间 情况的思路,将父元素设置为BFC(即设置overflow
),此时父元素与子元素置于不同的BFC,就可以解决高度重叠的问题了
代码:
HTML
|
|
CSS
|
|
高度塌陷
对于问题2的高度塌陷,解决的思路相对会多一些,请参考以下的几种解决思路:
-
将盒子的大小写死
缺点:非自适应。
-
在高度塌陷那层的盒子上设置,
overflow
使其变为BFC1 2 3
overflow:hidden; /*或者*/ overflow:auto;
缺点:
auto
会出现滚动条,影响美观hidden
会带来内容不可见的问题。
-
给外部的父盒子也添加浮动,也让其脱离标准流
缺点:不易维护
-
给父盒子末尾添加一个空盒子,并设置成清除浮动
代码:
HTML
1 2 3 4 5 6
<div class="parent"> <!-- 父亲颜色是红色 --> <div class="child">SON</div> <!-- 儿子的颜色是蓝色 --> <br style="clear:both" /> </div>
缺点:引入了不必要的冗余元素
-
用
after
伪元素清除浮动(推荐使用)-
给外部盒子的after伪元素设置clear属性,再隐藏它。
-
这是一种纯CSS的解决浮动造成盒子塌陷方法,没有引入任何冗余元素,推荐使用此方法来解决CSS盒子塌陷。
代码:
HTML
1 2 3 4 5
<div class="parent"> <!-- 父亲颜色是红色 --> <div class="child">SON</div> <!-- 儿子的颜色是蓝色 --> </div>
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*css代码*/ div.parent{ width: 200px; background: red; } div.child{ width: 50px; height: 50px; background: blue; color: #fff; float: left; } div.parent:after{ content: ""; display: block; height: 0; clear: both; overflow: hidden; visibility: hidden; /*为了保险起见把能写上的都写上叭*/ }
缺点:低版本IE不兼容。
-
参考文献
- box-sizing - CSS(层叠样式表) | MDN (mozilla.org)
- 外边距重叠 - CSS(层叠样式表) | MDN (mozilla.org)
- 浅谈盒模型、BFC以及高度塌陷的问题 - 掘金 (juejin.cn)
- 样式优先级、盒子塌陷、伪类和伪元素、行内元素的margin和padding、max-width和max-width之间的覆盖规则、浏览器如何解析CSS选择器 - 笔下洛璃 - 博客园 (cnblogs.com)
- 块格式化上下文 - Web 开发者指南 | MDN (mozilla.org)
- CSS之BFC、高度塌陷和外边距重叠_我是真的垃圾啊的博客-CSDN博客_css bfc absolute高度
- CSS解决高度塌缩问题和外边距重叠问题_Recyclable brother的博客-CSDN博客