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

我相信下面的情形大家在日常工作中常常碰到:在制作静态页面中,为了页面整体的协调与美观,我们想让子盒子 image-div 的上边沿距离父盒子 header-div 的上边沿有一定间距。

现页面效果:

目标页面效果:

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

<style>
.image-div { /*子盒子*/
margin-top:25px;
}
</style>

让我们来看看结果如何呢?

结果和我们所预料的并不相同,子盒子 image-div 并没有和父盒子 header-div 的上边沿形成一定的间距。这两个盒子竟然一起往下移动了,多出了红框区域。

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

边距塌陷

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

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

  • 如果都是正数,则取最大值

  • 如果相同,则取其中之一

  • 如果有正有负,则取最大的正数加上最小的负数之和

  • 如果都是负数,则取最小值。

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

在 CSS 当中,相邻两个兄弟盒子的外边距区域是公共的,这会导致相邻兄弟盒子之间的边距出现塌陷情况。

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

<style>
#block1 {
margin-bottom: 20;
}
#block2 {
margin-top: 10;
}
</style> <div id = "block1">div1</div>
<div id = "block2">div2</div>

在浏览器开发者工具先看 div1 的 margin 区域(红框):

div2 的 margin 区域(绿框区域):

对应情况:两个盒子之间的外边距如果都是正数,则取最大值。

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

<style>
#block1 {
margin-bottom: -20;
}
#block2 {
margin-top: -10;
}
</style> <div id = "block1">div1</div>
<div id = "block2">div2</div>

两个盒子的重叠距离为两个负数中最小的数“-20px”(绝对值最大 |-20px|)。

解决方法

如果想要避免这种塌陷,可以通过下面两种方法解决:

  • 只给其中一个盒子设置外边距

  • 给两个盒子分别套一个父盒子,父盒子属性设置为 overflow:hidden,同时让父盒子是密闭区域,从而触发 BFC

父子盒子之间的塌陷

然而设置父盒子也不是万全的,当出现以下情况时外边距会塌陷:

  • 块元素 的 margin-top 与 它的第一个子元素 的 margin-top 之间没有 border、padding、inline content、clearance 来分隔。

  • 块元素 的 margin-bottom 与 它的最后一个子元素 的 margin-bottom 之间没有 border、padding、inline content、height、min-height、max-height 分隔。

同时,如果父子公用一段上边距区域,比如父盒子没有上边距时,子盒子设上边距。这时子盒子带着父盒子向下移动(相当于给父盒子设置外边距)就会产生盒子塌陷。


<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:

解决方法

想要解决这种塌陷的核心办法是把父子盒子分隔开。我们可以给父盒子设置边框或者内边距,或者给父盒子标签添加 overflow:hidden 属性,通过触发 BFC 规则,也就是块级格式上下文,把父级渲染成一个独立区域,从而解决父子盒子之间的塌陷问题。

BFC 规则触发方式:

  • float 不为 none

  • overflow 不为 visible(常用 overflow:hidden)

  • position 为 fixed,absolute

  • display 为 flex,inline-block,table-cell

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

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

<style>
.image-div { /*子盒子*/
margin-top:25px;
}
.header-div { /*父盒子*/
overflow:hidden; /*触发bfc*/
}
<style>

以上就是 CSS 盒子边距常见的塌陷与解决办法,希望能够对你有所帮助。

推荐阅读

一文读懂浏览器存储与缓存机制

Python Type Hints 从入门到实践

CSS 盒子的边距塌陷的更多相关文章

  1. css - 盒子内外边距

    css - 盒子内外边距 元素内边距 内边距是指元素包含的内容离元素边框之间的间距,padding会撑大盒子.在浏览器中显示的元素宽高包含了padding. div{     width:200px; ...

  2. 外边距塌陷之clearance

    在一个BFC中,垂直方向上相邻的块级盒子产生外边距塌陷,本文要说一个特殊的外边距塌陷情况,即当垂直方向上,两个块级盒子之间有个浮动元素相隔时,这个时候会产生什么样的效果呢? .outer{ overf ...

  3. 深入理解CSS盒子模型

    在CSS中浮动.定位和盒子模型,都是很核心的东西,其中盒子模型是CSS很重要基石之一,感觉还是很有必要把CSS盒子模型相关知识更新一下...... CSS盒子模型<BoxModel>示意图 ...

  4. CSS 基础 例子 盒子模型及外边距塌陷

    我们通常设置的宽度和高度,是指盒子模型中内容(content)的宽度和高度.元素的高度,还要加上上下padding和上下border,元素整个盒子的高度还要加上上下margin:宽度类似计算. 注意: ...

  5. css盒子模型、边框border、外边距margin、填充padding、轮廓outline

    盒子模型:盒子默认的宽度为容器的宽度,也可以自省设定宽度,高度根据内容适应,也可以自行设定高度.min-height设定最小高度 一个盒子包括外边距.边框.内边距和实际内容 Margin(外边距):清 ...

  6. 2 CSS盒子模型&边框&轮廓&外边距&填充&分组嵌套&尺寸&display与visibility

    盒子模型 Box  Model 所有HTML元素可以看做盒子,CSS模型本质上是一个盒子,封装周围的HTML元素 包括:边距,边框,填充和实际内容 盒子模型允许我们在其他元素和周围元素边框之间的空间放 ...

  7. CSS -- 盒子模型之边框、内边距、外边距

    一.使用border为盒子添加边框 盒子模型的边框就是围绕着内容及补白的线,这条线你可以设置它的粗细.样式和颜色(边框三个属性). 1.border-style(边框样式)常见样式有: dashed( ...

  8. css盒子模型、垂直外边距合并

    css盒子模型由四部分组成:内容(content).填充(padding).边框(border).边距(margin),其中css样式中定义的width属性是定义内容区域的宽度,正常情况下,设置了内容 ...

  9. CSS盒子内容

    内边距 内边距(padding):内容与边框之间的距离 注意:padding 只能移动盒子的内容 padding属性联写: padding: 10px: 内边距的上下左右都移动 padding: 10 ...

随机推荐

  1. Shell系列(18)- 什么是正则表达式

    概念: 正则表达式是用于描述字符排列和匹配模式的一种语法 它主要用于字符串的模式分割.匹配.查找及替换操作.

  2. PHP 处理历史数据的伪代码

    <?php class a { protected static $Senior = [1, 2, 3]; protected static $NoSenior = [13, 14, 15, 1 ...

  3. k8s-PodApi对象

    init容器 pod的生命周期钩子 资源限制 podApi对象概览 apiVersion + kind  一个是版本 一个是资源组  共同确定当前yaml由谁来管理 metadata元数据 用来唯一标 ...

  4. CF700E-Cool Slogans【SAM,线段树合并,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/CF700E 题目大意 给出一个字符串\(S\),求一个最大的\(k\)使得存在\(k\)个字符串其中\(s_1\)是 ...

  5. Python爬虫--淘宝“泸州老窖”

    爬虫淘宝--"泸州老窖" 爬去淘宝"泸州老窖" 相关信息: import requests import re import json import panda ...

  6. NOIP 模拟 十一

    T1 math 分析性质,对于 $$ ax+by=c$$ 有 $$ gcd(x,y)|c$$ 所以 $$ gcd(a_1,a_2 .....,a_n)|num$$ 换句话说就是最后得到的数一定是 GC ...

  7. C#开发BIMFACE系列44 服务端API之计算图纸对比差异项来源自哪个图框

    BIMFACE二次开发系列目录     [已更新最新开发文章,点击查看详细] 在前两篇博客<C#开发BIMFACE系列42 服务端API之图纸对比>.<C#开发BIMFACE系列43 ...

  8. IEEE 754舍入的问题

    写在前面 本文的舍入方法只适用于保留0位或1位小数,个人水平所限,暂时没有发现保留更多小数位的舍入的规律- IEEE 754的舍入模式 IEEE 754标准提供了2类,5种舍入模式,在默认情况下一般是 ...

  9. Apache Common-collection 反序列化利用链解析--TransformedMap链

    Apache Common-collection 反序列化利用链解析 TransformedMap链 参考Java反序列化漏洞分析 - ssooking - 博客园 (cnblogs.com) poc ...

  10. 【UE4 设计模式】适配器模式 Adapter Pattern

    概述 描述 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper). 套路 Target(目标抽象类) 目标抽象类定义了客户所需要的接口,可 ...