前言

之前在前端开发的过程中,都没有遇到外边距合并的问题(其实是因为大多时候都直接用前端样式库(〃'▽'〃)),这一次需要动手排一个页面,也挺简单,但是遇到了一个奇怪的问题,所以学习记录一下。

问题

测试代码如下:

<!doctype html>
<html class="no-js" lang=""> <head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>test</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<style>
* {
margin: 0;
padding: 0;
} body {
max-width: 750px;
margin: 0 auto;
} .div1 {
background: yellow;
height: 200px;
} .div2 {
background: blue;
height: 200px;
} .div2Child {
background: red;
height: 100px;
}
</style> <body>
<div class="div1">我是吃瓜群众</div>
<div class="div2">
<div class="div2Child" style="margin-top: 50px">我是子div</div>
<p style="color: white">我是父div</p>
</div>
</body> </html>



子div设置了margin-top之后,父div也跟着一起margin-top了。

原因如下:

Margin Collapsing 外边距合并

块的顶部外边距和底部外边距有时被组合(折叠)为单个外边距,其大小是组合到其中的最大外边距,这种行为称为外边距塌陷(margin collapsing),或外边距合并。

外边距合并的3中基本原因:

1、相邻的元素

毗邻的两个兄弟元素之间的外边距会合并

2、块级父元素与其第一个/最后一个子元素

  • 如果块级父元素中,不存在border, padding, inline part, block formatting context created, or clearance 来隔离第一个子元素的上边距,就会发送外边距合并现象。
  • 如果块级父元素,不存在border, padding, inline content, height, min-height, max-height来隔离下边距,则会和最后一个子元素合并。

3、空块元素

如果存在一个空的块级元素,不存在 border、padding、inline content、height、min-height来隔离上下外边距,那么它的上下外边距将会合并。

  • 当都为正数时,取两者中较大者。
  • 当都为负数时,取绝对值较大者。
  • 当一正一负时,取相加之和。
  • 外边距设为0时,这些规则也仍旧生效。

BFC(Block Formatting Context 块格式化上下文)与元素外边距合并 :

  • 当两个元素属于不同的BFC时,这两个元素的外边距不会合并
  • 但在同一个BFC内,两个相邻元素的外边距仍会合并。

Block Formatting Context 块格式化上下文

一个块格式化上下文(block formatting context) 是Web页面的可视化CSS渲染出的一部分。它是块级盒模型出现的区域,也是浮动元素与其他元素进行交互的区域。

一个块格式化上下文由以下之一创建:

  • 根元素或一些包含它的元素
  • 浮动元素 (元素的 float 不是 none)
  • 绝对定位元素 (元素的 position 为 absolute 或 fixed)
  • 内联块 (元素具有 display: inline-block)
  • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
  • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
  • display隐式创建的匿名表格列,包括table, table-row, table-row-group, table-header-group, table-footer-group (这些都是html的默认样式), or inline-table
  • 具有overflow 且值不是 visible 的块元素,
  • display: flow-root
  • flex 项目
  • grid 项目
  • 多列容器(column-count 和 column-width 不是 auto, 包括 column-count: 1的元素)
  • column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。

解决方案

知道了问题原因所在,以及了解了相关原理,就很好办了。

1、给div2设置border

为了不改变div2的大小,还需将设置 box-sizing为border-box将padding和border包含在定义的width和height之内

.div2 {
background: blue;
height: 200px;
border-top: 1px solid transparent;
box-sizing: border-box;
}

2、去掉div2Child的margin,改为设置div2的padding

.div2 {
background: blue;
height: 200px;
padding-top:50px;
box-sizing: border-box;
}

3、div2设置为内联元素

.div2 {
background: blue;
height: 200px;
display: inline-block;
width: 100%;
}

4、清除浮动

所有浮动元素包含在div2内,增加样式clearfix

.clearfix::before, .clearfix::after{
overflow: hidden;
display: table;
visibility: hidden;
content: '';
clear: both;
}

或者创建一个新的BFC,使其在不同的上下文中,不合并外边距。

5、给div2设置Position

.div2 {
background: blue;
height: 200px;
position: absolute;
width: 100%;
max-width: 750px;
}

6、给div2设置float,注意后面的元素需要clear浮动

.div2 {
background: blue;
height: 200px;
float: left;
width: 100%;
}

7、给div2设置display

.div2 {
background: blue;
height: 200px;
display: inline-block;
/*display: table;*/
width: 100%;
}

8、给div2设置flex

.div2 {
background: blue;
height: 200px;
display: flex;
flex-direction: column;
}

9、给div2设置overflow

.div2 {
background: blue;
height: 200px;
overflow: hidden;
}

万变不离其宗

参考

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing

https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context

CSS外边距合并&块格式上下文的更多相关文章

  1. CSS外边距合并的几种情况

    CSS外边距合并的几种情况 外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距.合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者. 外边距在CSS1中就有 The width ...

  2. css外边距合并和z-index的问题

    参考这篇文章, 将外边距的 折叠 参考这篇文章, 将bfc的生成, bfc的应用 参考这篇文章 position: absolute的元素, 仍然具有内填充padding和border边框属性样式, ...

  3. CSS外边距合并(塌陷/margin越界)

    原文 简书原文:https://www.jianshu.com/p/5f18f12cd162 大纲 1.什么是外边距合并?(折叠外边距) 2.外边距带来的影响 3.折叠的结果 4.产生折叠的原因 5. ...

  4. CSS 外边距合并

    外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距. 合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者. 外边距合并 外边距合并(叠加)是一个相当简单的概念.但是,在实践中对网 ...

  5. CSS外边距合并问题

    今天无意中碰到了外边距合并的问题,于是便研究了一下.这里做个笔记. 所谓外边距合并,指的是当两个垂直外边距相遇时,它们将形成一个外边距.合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者. ...

  6. CSS 外边距合并。

    <div id = "parent"> <div id = "child"> demo </div> </div> ...

  7. CSS框模型(框模型概述、内边距、边框、外边距、外边距合并)

    CSS 框模型概述 CSS 框模型 (Box Model) 规定了元素框处理元素内容.内边距.边框 和 外边距 的方式. 元素框的最内部分是实际的内容,直接包围内容的是内边距.内边距呈现了元素的背景. ...

  8. CSS min-height不能解决垂直外边距合并问题

    垂直外边距合并有一种情况是嵌套元素的垂直外边距合并,当父级元素没有设定外边距时,在顶部或者底部边缘的子元素的垂直外边距就会和父级的合并,导致父级也有了“隐形”的垂直外边距. 当父级元素的min-hei ...

  9. 关于CSS inline-block、BFC以及外边距合并的几个小问题

    CSS inline-block和BCF对于初学者来说,总是弄不太明白,下面记录下我在学习这块知识的过程中遇到的几个问题,供大家参考,有不足的地方,欢迎大家批评指正. 一.在什么场景下会出现外边距合并 ...

随机推荐

  1. 09 Finding a Motif in DNA

    Problem Given two strings ss and tt, tt is a substring of ss if tt is contained as a contiguous coll ...

  2. tomcat服务器输入localhost可以访问,ip无法访问解决办法

    最近在开发项目中,遇到的一个问题是: 在 tomcat中发布一个web项目,但是发布成功后,只能用http://localhost:8080/fm访问项目,不能用 http://127.0.0.1:8 ...

  3. uva 10169 - Urn-ball Probabilities !(概率)

    题目链接:uva 10169 - Urn-ball Probabilities ! 题目大意:在一个箱子中,原本有1个红球,然后任意取出(有放回)一个球,然后再往里放一个白球(每次取都要放进一个白球) ...

  4. UI 设计概念介绍

    UI 设计概念介绍 http://www.slideshare.net/tedzhaoxa/ui-and-ue-design-basic

  5. Python学习-10.Python函数定义(二)

    在Python中定义函数的时候,可以使用参数默认值的方式定义函数 例子: def welcome(who,state='is',action='talking'): print(who,state,a ...

  6. [JAVA]java复制文件的4种方式

    尽管Java提供了一个可以处理文件的IO操作类. 但是没有一个复制文件的方法. 复制文件是一个重要的操作,当你的程序必须处理很多文件相关的时候. 然而有几种方法可以进行Java文件复制操作,下面列举出 ...

  7. leetcode 有效的字母异位词

    给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词. 示例 1: 输入: s = "anagram", t = "nagaram" ...

  8. 【.net】Dictionary<TKey, TValue>源码分析

    一图胜过千言万语~

  9. 基于GeoServer切片地图服务的发布

    接着上一篇文章,如何将JPG格式的图片转化为带地理坐标的TIFF格式里提及的最近的一个项目,数据源是一张高分辨率的2.5维图片,现在已经成功转化成了带有地理坐标的TIFF格式.下面将介绍借助GeoSe ...

  10. dokcer 的export 、improt和save 、load

    export .improt 是对容器操作也就是类似于虚拟机的快照 save .load 是针对于镜像操作的..