CSS之盒子的边距塌陷(兄弟、父子)与解决方案

文章目录

  • 问题引入
  • 一、边距塌陷
  • 二、相邻(兄弟)盒子之间的塌陷
    • 解决方法
  • 三、 父子盒子之间的塌陷
    • 解决方法

tip:为能更直观地学习,本文章已省略部分css样式代码。

问题引入

如下图所示,在制作静态页面中,为了页面整体的协调与美观,我们想让子盒子image-div的上边沿距离父盒子header-div的上边沿有一定间距。

现页面效果:
CSS之盒子的边距塌陷(兄弟、父子)与解决方案_第1张图片
目标页面效果:
CSS之盒子的边距塌陷(兄弟、父子)与解决方案_第2张图片

为了达成上图的效果,我们首先就能想到给子盒子设置一个上外边距:


让我们来看看结果如何呢?
CSS之盒子的边距塌陷(兄弟、父子)与解决方案_第3张图片
结果和我们所预料的并不相同,子盒子image-div并没有和父盒子header-div的上边沿形成一定的间距!这两个盒子竟然一起往下移动了,多出了红框区域。

而这种现象,就是css中常遇到的“边距塌陷”问题中的一种。

一、边距塌陷

流内块级元素的top与bottom外边距有时会合并(塌陷)为单个外边距(合并后最大的外边距),这样的现象称之为外边距塌陷(margin collapsing)

导致边距塌陷的原因是外边距,有以下四种情况:

  1. case1:如果都是正数,则取最大值
  2. case 2:如果相同,则取其中之一
  3. case 3:如果有正有负,则取最大的正数加上最小的负数之和
  4. case4:如果都是负数,则取最小值。

二、相邻(兄弟)盒子之间的塌陷

原因:两个盒子之间的外边距区域是公共的。

下图是相关示例,设置div1盒子的下边距,另设置下方div2盒子的上边距:

示例1:

<style>
	#block1 {
	    margin-bottom: 20;
	}
	#block2 {
	    margin-top: 10;
	}
style>

<div id = "block1">div1div>
<div id = "block2">div2div>

在浏览器开发者工具先看div1的margin区域(红框):
CSS之盒子的边距塌陷(兄弟、父子)与解决方案_第4张图片
div2的margin区域(绿框区域):
CSS之盒子的边距塌陷(兄弟、父子)与解决方案_第5张图片
对应case1的情况:两个盒子之间的外边距如果都是正数,则取最大值。

示例2:
将示例1中的外边距改为负数,

<style>
#block1 {
    margin-bottom: -20;
}
#block2 {
    margin-top: -10;
}
style>

<div id = "block1">div1div>
<div id = "block2">div2div>

两个盒子的重叠距离为两个负数中最小的数“-20px”(绝对值最大|-20px|)。
CSS之盒子的边距塌陷(兄弟、父子)与解决方案_第6张图片

解决方法

  1. 只给其中一个盒子设置外边距
  2. 触发BFC:
    两个盒子分别套一个父盒子,父盒子设属性overflow:hidden,父盒子是密闭区域

三、 父子盒子之间的塌陷

  • 如果块元素的 margin-top 与它的第一个子元素的margin-top 之间没有 border、padding、inline content、 clearance 来分隔
  • 或者块元素的 margin-bottom 与它的最后一个子元素的margin-bottom 之间没有 border、padding、inline content、height、min-height、 max-height 分隔
    那么外边距会塌陷
  1. 当父盒子没有上边距时,子盒子设上边距,子盒子带着父盒子向下移动(相当于给父盒子设置外边距)
    原因:父子共用一段上边距区域
<style>
*{
    margin:0px;
    padding: 0px;
}
.div1{
    width:300px;
    height: 200px;
    background-color: cornflowerblue;
    margin:0px;
}
.div2{
    background-color: wheat;
    margin: 30px;
}
style>
    
<div class="div1">
    <div class="div2">
        div2     	 	
    div>
div>

父元素不设置外边距,第一个子元素设置margin:30px,会发现父元素与子元素一起往下移动了30px:
CSS之盒子的边距塌陷(兄弟、父子)与解决方案_第7张图片

解决方法

核心:把父子盒子分隔开

  1. 给父盒子设置边框或内边距
  2. 给父标签添加overflow:hidden属性,触发BFC规则(块级格式上下文,把父级渲染成一个独立区域

BFC规则触发方式:

  • float不为none
  • overflow不为visible(常用overflow:hidden)
  • position为fixed,absolute
  • display为flex,inline-block,table-cell

当然,在选择塌陷的解决方案时,应依据具体的情境,不能所有情况都使用相同的方案,否则会造成其他问题的出现哦~

那么,在我们学习以上知识后,就能清晰地知道开头引入的问题正是父子盒子间的塌陷,我们可以通过触发BFC规则(仅其中一种方案)来解决: