三分钟带你回顾margin折叠问题
一、什么是 margin 折叠?
只有块级盒子才会出现这个现象: 上下挨在一起的两个块盒子,它们上下方向的外边距碰到一起,不会叠加,会合并成一个外边距,只保留数值更大的那一个。
两个关键点
- 只在上下垂直方向生效(
margin-top/margin-bottom) - 左右水平外边距(
margin-left/margin-right)永远不会折叠
二、三种会发生折叠的情况
两个兄弟盒子上下挨着上面盒子的底部外边距,和下面盒子的顶部外边距合并。
父子嵌套盒子父盒子没有边框、内边距、BFC 隔离时,子盒子的上下外边距会 “穿出去”,和父盒子外边距合并。
完全空的块盒子盒子里面没有文字、没有边框、没有内边距,它自己的顶部和底部外边距会互相合并。
三、5 种解决折叠的简单方法
方法 1:父盒子用内边距 padding,子盒子取消外边距
不用子元素 margin 撑开距离,改用父元素 padding,从根源避免折叠
方法 2:给父盒子加边框 / 一点点内边距
边框能隔开父子的外边距,透明边框不影响页面外观
方法 3:给子盒子加浮动或者绝对定位
浮动、绝对定位的盒子脱离普通文档流,不会出现 margin 折叠
方法 4:父盒子用 flex/grid 弹性布局
只要父容器设为弹性布局,里面子元素的外边距不会穿透父盒子
方法 5:父盒子开启 BFC(最常用)
最简单写法:父盒子设置overflow: hidden,创建独立格式化区域,锁住子元素 margin
四、实操完整例子
1. 原生状态:出现 margin 折叠
子盒子的上边距会穿透父盒子,整个灰色父盒子一起往下移,而不是子盒子在父内部下移
2. 用 BFC 修复后:折叠消失
父盒子加overflow: hidden,子盒子的外边距被限制在父盒子内部
五、注意细节
- 只有普通文档流的块级元素才会折叠;行内元素、浮动、绝对定位盒子无折叠
- 负数外边距也会折叠,最后取两个负数里相对更大(没那么负)的值
- 左右水平 margin 永远不会折叠,不用考虑
