前言

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

问题

测试代码如下:

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

最新文章

  1. yum和apt-get有什么区别
  2. java的poi技术写Excel的Sheet
  3. android帧动画,移动位置,缩放,改变透明度等动画讲解
  4. JAVAWEB贵美网上商城完整项目源码(SSH2)
  5. lib库dll库的使用方法与关系
  6. ubuntu 安装php7.1
  7. BZOJ 2436 Noi嘉年华(优化DP)
  8. HDU 2151 Worm
  9. java 异常小结
  10. (困难) CF 484E Sign on Fence,整体二分+线段树
  11. Jenkins+Tomcat+svn+maven自动化构建简单过程
  12. [国嵌攻略][156][I2C自编设备驱动设计]
  13. 【LightOJ1282】Leading and Trailing(数论)
  14. fs 创建文件夹
  15. .Net Core 部署在win10 的IIS上注意问题。
  16. 结构型---外观模式(Facade Pattern)
  17. 问题1:canvas绘制图片加载不出来
  18. 尼基塔第一季/全集Nikita迅雷下载
  19. [翻译] FlatUIKit
  20. JQuery --- 第五期 (JQuery节点操作)

热门文章

  1. CentOS 最新版的下载地址 + 版本选择详解
  2. Apache ab.exe压测工具使用
  3. RocketMQ服务器监控误区
  4. 20169221 2016——2017《网络攻防》SQL注入
  5. Shell编程-01-Shell脚本初步入门
  6. FlexBox弹性盒布局
  7. docker 版本变化及说明
  8. HTML5使用总结(一)
  9. Linux Socket - UDP链接包
  10. 经典的兔子生兔子问题(C#递归解法)