CSS 垂直外边距合并:规范、延伸、原理、解决办法
《CSS 权威指南》第七章基本视觉格式化.p192,提到了 垂直外边距合并 的情况,解释总体算清晰,但是感觉不全且没有归纳成一条一条的,参考 CSS框模型中外边距(margin)折叠图文详解,总结如下:
规范:
计算方法:
- 如果外边距都是正数,取大的;
- 如果一个正数,一个负数,正外边距-负外边距的绝对值,相当于正外边距+负外边距;
- 都为负数,取外边距绝对值较大的;
- 如果相邻外边距有多个,要一起参与计算,不能分布计算;要注意,相邻的元素不一定非要是兄弟节点,父子节点也可以,即使不是兄弟父子节点也可以相邻,而且,在计算时,相邻的 margin 要一起参与计算,不得分步计算;
示例代码:
<div style="margin:50px 0; background-color:green; width:50px;">
<div style="margin:-60px 0;">
<div style="margin:150px 0;">A</div>
</div>
</div>
<div style="margin:-100px 0; background-color:green; width:50px;">
<div style="margin:-120px 0;">
<div style="margin:200px 0;">B</div>
</div>
</div>
错误的计算方式:
算 A 和 B 之间的 margin,分别算 A 和其父元素的折叠,然后与其父元素的父元素的折叠,这个值算出来之后,应该是 90px。依此法算出 B 的为 80px;然后,A和B折叠,margin 为 90px。
请注意,多个 margin 相邻折叠成一个 margin,所以计算的时候,应该取所有相关的值一起计算,而不能分开分步来算。
正确的计算方式:
A 和 B 之间的 margin 折叠产生的 margin,是6个相邻 margin 折叠的结果。将其 margin 值分为两组:
正值:50px,150px,200px
负值:-60px,-100px,-120px
根据有正有负时的计算规则,正值的最大值为 200px,负值中绝对值最大的是 -120px,所以,最终折叠后的 margin 应该是 200 + (-120) = 80px。
延伸:
1、浮动元素、inline-block 元素、绝对定位元素的 margin 不会和垂直方向上其他元素的 margin 折叠,因为他们都不属于 流内块级盒;
2、元素自身的 margin-bottom 和 margin-top 相邻时也会折叠,也就是说元素自身 height:0;
代码:
<div style="border:1px solid red; width:100px;">
<div style="margin-top: 100px;margin-bottom: 50px;"></div>
</div>
示例:

你看父元素 height 是 100px,不是 150px,证明 margin-bottom 被合并了
原理:(截图自 《CSS 权威指南》p192-p193)


解决办法:
1、给父元素加上 overflow:hidden,创建了新的 BFC,可以让父元素不和它的子元素发生 margin 折叠,
示例:

代码:
<div style="margin-top:30px; width:100px; height:100px; background-color:green; overflow:hidden;">
<div style="margin-top:50px; background-color:gold;opacity: 0.5;">B</div>
</div>
你可能感觉很正常,是的,因为父元素加了 overflow:hidden; 去掉之后,是这样子:

父元素和子元素的 margin-top 合并了,以子元素 margin-top:50px 大的为准;
2、垂直外边距合并是针对 流内块级盒,把他变成非块级流内元素不就行了,比如,浮动,绝对定位,inline-block ;
CSS 垂直外边距合并:规范、延伸、原理、解决办法的更多相关文章
- css盒子模型、垂直外边距合并
css盒子模型由四部分组成:内容(content).填充(padding).边框(border).边距(margin),其中css样式中定义的width属性是定义内容区域的宽度,正常情况下,设置了内容 ...
- CSS min-height不能解决垂直外边距合并问题
垂直外边距合并有一种情况是嵌套元素的垂直外边距合并,当父级元素没有设定外边距时,在顶部或者底部边缘的子元素的垂直外边距就会和父级的合并,导致父级也有了“隐形”的垂直外边距. 当父级元素的min-hei ...
- CSS Margin外边距合并
应该知道这点东西的!!! 可是偏偏记不住! 外边距合并会发生在以下两种情况下: 1 垂直出现的两个拥有外边距的块级元素. div1 { margin-bottom: 20px; } div2 { ma ...
- 文本溢出、垂直外边距合并、BFC、hasLayout
今天学习文本溢出,又遇到了一些小问题,先上图: 关于文本溢出推荐:http://www.cnblogs.com/yzg1/p/5089534.html 从里面学习到单行文本和多行文本溢出, overf ...
- 关于CSS的外边距合并问题
首先,需要明确的是只有普通文档流中块框的垂直外边距才会发生外边距合并.行内框.浮动框或绝对定位之间的外边距不会合并. 而在普通文档流中,这又分两种情况,分别是父子元素之间和相邻元素之间. <!D ...
- css的外边距合并或者外边距塌陷问题
第一种情况: 已知两个宽和高均为100px,margin均为20px的div垂直排列,现象如下图所示: 当设置css1的margin-bottom:40px:或者css2的margin-top:40p ...
- css中外边距合并
最近在布局时遇到一个有趣的问题 <style> #div1{width:200px;height:200px;background:red;} #div2{width:50px;heig ...
- CSS外边距合并的几种情况
CSS外边距合并的几种情况 外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距.合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者. 外边距在CSS1中就有 The width ...
- Margin的垂直外边距问题
做练习的时候遇到一个margin的问题,代码结构如下,给父元素body中的子元素div设置了margin:50px auto;本来我是想让子元素div距离父元素上边拉开50个像素,结果却是子元素div ...
随机推荐
- Redis 实现接口访问频率限制
为什么限制访问频率 做服务接口时通常需要用到请求频率限制 Rate limiting,例如限制一个用户1分钟内最多可以范围100次 主要用来保证服务性能和保护数据安全 因为如果不进行限制,服务调用者可 ...
- Nginx配置优化详解
如果你已经安装过Nginx并在生产环境中使用,那么Nginx配置优化你一定也要做,这样才能看到Nginx性能,本文就从基本配置优化开始到高层配置教你如何优化Nginx 大多数的Nginx安装指南告诉你 ...
- python核心编程——python对象
一.什么是python对象 在python中,构造的不论什么类型的值都是一个对象.比方一个整数类型的值,一个字符串.一个列表等,都能够看做是对象. 全部的对象分为三部分: (1)身份.每一个对象都有个 ...
- Linux下恢复误删文件:思路+实践
周五篮球群里有人问误删文件了怎么恢复,得知是ext4文件系统之后我推荐了ext4magic这个工具,然后又有人提到了xfs的话怎么办,正好前几天看到Dave Chinner在邮件列表里提到了这个问题, ...
- js eval深入
在JS中将JSON的字符串解析成JSON数据格式,一般有两种方式: 1.一种为使用eval()函数. 2. 使用Function对象来进行返回解析. 使用eval函数来解析,并且使用jquery的ea ...
- cf339d Xenia and Bit Operations
Xenia and Bit Operations Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- Spring.Net框架三:使用Spring.Net框架实现多数据库
在前面的两篇文章中简单介绍了Spring.Net和如何搭建Spring.Net的环境,在本篇文章中将使用Spring.Net实现多数据库的切换. 一.建立一个空白的解决方案,名称为“SpringDot ...
- [JS] 页面回车键提交表单-常用于登录页面
//判断是否按下了回车键 var EnterSubmit = function(evt){ evt= window.event || evt; if (evt.keyCode == 13){ //若按 ...
- 项目中遇到的direct3d问题,设备丢失
今天在调试项目的时候,遇到一个问题,之前在写代码的时候,调试都是在本地的电脑上进行调试,然而今天是通过远程登陆到电脑进行调试的,所以在调试的过程中遇到了一个问题. 其实开始的时候,有同事反应说,当远程 ...
- css -- hover伪类
CSS代码: .btn-setDefaultGateway{display: none;} .netDiv:hover span .btn-setDefaultGateway { display: i ...