<!-- 《CSS世界》张鑫旭著 -->

正确看待 CSS 世界里的 margin 合并

什么是 margin 合并

块元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并成单个外边距,这样的现象称为“margin合并”。

(1)块级元素,但不包括浮动元素和绝对定位元素,尽管浮动和绝对定位可以让元素块状化

(2)只发生在垂直方向,准确来说,是只发生在和当前文档流方向的相垂直的方向上

margin 合并的3种场景

(1)相邻兄弟元素margin合并。这是 margin 合并中最常见、最基本的。

(2)父级和第一个/最后一个子元素。

在实际开发中,给我们带来麻烦的多半是父子 margin 合并。示例可见 http://demo.cssworld.cn/4/3-3.php

如何阻止这里 margin 合并的发生?

对于 margin-top 合并,可以进行如下操作(满足一个条件即可):

  • 父元素设置为块状格式化上下文元素;(块状格式上下文的概念见6.3节)
  • 父元素设置 border-top 值;
  • 父元素设置 padding-top 值;
  • 父元素和第一个子元素之间添加内联元素进行分隔。

对于 margin-bottom 合并,可以进行如下操作(满足一个条件即可):

  • 父元素设置为块状格式化上下文元素;
  • 父元素设置 border-bottom值;
  • 父元素设置 padding-bottom 值;
  • 父元素和最后一个子元素之间添加内联元素进行分隔;
  • 父元素设置 height、min-height或max-height。

(3)空块级元素的 margin 合并。例如,下面 CSS 和 HTML 代码:

.father { overflow: hidden; }
.son { margin: 1em 0; } <div class="father">
<div class="son"></div>
</div>

结果,此时 .father 所在的这个父级<div>元素高度仅仅是 1em。因为.son这个空<div>元素的 margin-top 和 margin-bottom 合并在一起了。

如果不希望空<div>元素有margin合并,可以进行如下操作:

  • 设置垂直方向的 border;
  • 设置垂直方向的 padding;
  • 里面添加内联元素(直接 Space键空格是没用的);
  • 设置 height 或者 min-height。

margin 合并的计算规则

作者把 margin 合并的计算规则总结为“正正取大值”、“正负值相加”、“负负最负值”三句话

(1)正正取大值。

如果是相邻兄弟合并:

.a { margin-bottom: 50px; }
.b { margin-top: 20px; } <div class="a"></div>
<div class="b"></div>

此时,.a 和 .b 两个<div>之间的间距是 50 px,取大的那个值。

如果是父子合并:

.father { margin-top: 20px; }
.son { margin-top: 50px; } <div class="father">
<div class="son"></div>
</div>

此时,父元素 .father 等同于设置了 margin-top: 50px,取大的那个值。

如果是自身合并:

.a {
margin-top: 20px;
margin-bottom: 50px;
} <div class="a"></div>

此时,.a 元素的外部尺寸是 50px,取大的那个值。

(2)正负值相加。

如果是相邻兄弟合并:

.a { margin-bottom: 50px; }
.b { margin-top: -20px; } <div class="a"></div>
<div class="b"></div>

此时,.a 和 .b 两个<div>之间的间距是 30 px,是-20px+50px 的计算值。

父子合并与自身合并的计算规则类似。

(3)负负最负值。

如果是相邻兄弟合并:

.a { margin-bottom: -50px; }
.b { margin-top: -20px; } <div class="a"></div>
<div class="b"></div>

此时,.a 和 .b 两个<div>之间的间距是 -50 px,取绝对负值最大的值。

父子合并与自身合并的计算规则类似。

margin 合并的意义

CSS 世界的 CSS 属性是为了更好地进行图文信息展示而设计的。margin 合并设计的意义是为了让图文信息的排版更加舒服自然。

深入理解 CSS 中的 margin: auto

首先,我们需要知道下面这些事实:

(1)有时候元素就算没有设置 width 或 height,也会自动填充。

(2)有时候元素就算没有设置 width 或 height,也会自动填充对应的方位。例如:

div {
position: absolute;
left:;
right:;
}

此时<div>宽度就会自动填满包含块容器。

此时,如果设置 width 或 height,自动填充特性就会被覆盖。例如:

div { width: 200px; }

此时, <div>宽度被限制成了200px,无法自动填充外部容器的可用宽度了。

假设外部的容器宽度是300px,则有100px的宽度因为 width 设置而闲置,而 margin: auto 就是为了填充这个闲置的尺寸而设计的!

margin: auto 的填充规则如下:

(1)如果一侧定值,一侧 auto,则 auto 为剩余空间的大小

(2)如果两侧均是 auto,则平分剩余空间。

margin 的初始值大小是 0.

.father { width: 300px; }
.son {
width: 200px;
margin-right: 80px;
margin-left: auto;
}

此时,.son 的左边距是 20px,右边距是 80px。 示例见 http://demo.cssworld.cn/4/3-4.php

上面的例子中如果 margin-right 缺失,实现的效果正好是块级元素的右对齐效果,因为 margin的初始值是0.

居中对齐左右同时设置 auto 即可。

.son {
width: 200px;
margin-right: auto;
margin-left: auto;
}

触发 margin: auto 计算有一个前提条件,就是 width 或 height 为auto时,元素是具有对应方向的自动填充特性的。

那我们怎么才能用margin实现垂直方向居中呢?

第一种方法是使用 writing-mode 改变文档流的方向;但是这种方法只能实现一个方向的居中

第二种方法是绝对定位元素的 margin: auto 居中。可以实现水平垂直同时居中。

.father {
width: 300px;
height: 150px;
position: relative;
} .son {
position: absolute;
top:;
right:;
bottom:;
left:;
}

此时,.son 元素的尺寸表现为“格式化宽度和格式化高度”,和<div>的“正常流宽度”一样,同属于外部尺寸,也就是尺寸自动填充父级元素的可用尺寸,此时,我们给.son设置尺寸。

.son {
position: absolute;
top:;
right:;
bottom:;
left:;
width: 200px;
height: 100px;
}

此时,宽高被限制,原本应该填充的空间就被空余了出来,这多余的空间就是 margin: auto 计算的空间,因此,如果这时我们再设置一个 margin: auto:

.son {
position: absolute;
top:;
right:;
bottom:;
left:;
width: 200px;
height: 100px;
margin: auto;
}

那么我们这个.son元素就水平方向和垂直方向同时居中了。示例见 http://demo.cssworld.cn/4/3-5.php

由于绝对定位元素的格式化高度即使父元素 height: auto 也是支持的,因此应用场景相当广泛,唯一不足的是此居中计算 IE8 及以上版本浏览器才支持。

这种方式比top: 50% 然后margin 负一半元素高度的方法要好得多。

最后,还有一个问题,假如说这里面的元素尺寸比外面的大,那这个auto该怎么计算呢?

结果很有意思,不同流方向上的计算规则还不一样。在默认的水平流下,如果里面的元素尺寸大,水平方向 auto 计算后的负值会被当作 0 来处理,所以不会水平居中;但垂直方向计算后的负值则会保留,所以会垂直居中。

另外,对于替换元素,如果我们设置display: block,则 margin: auto 的计算规则同样合适。

《CSS世界》读书笔记(十二)的更多相关文章

  1. 《深入理解Java虚拟机》读书笔记十二

    第十二章  Java内存模型与线程 1.硬件效率与一致性 由于计算机的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cac ...

  2. Machine Learning for hackers读书笔记(十二)模型比较

    library('ggplot2')df <- read.csv('G:\\dataguru\\ML_for_Hackers\\ML_for_Hackers-master\\12-Model_C ...

  3. How tomcat works 读书笔记十二 StandardContext 下

    对重载的支持 tomcat里容器对重载功能的支持是依靠Load的(在目前就是WebLoader).当在绑定载入器的容器时 public void setContainer(Container cont ...

  4. How tomcat works 读书笔记十二 StandardContext 上

    在tomcat4中,StandardContext.java是最大的一个类,有117k.废话不说,开始分析吧. 其实要分析StandardContext,也就主要分析两个方法,一个start,一个in ...

  5. Java 读书笔记 (十二) Java Character 类

    在实际开发过程中, 我们经常会遇到需要使用对象,而不是内置数据类型的情况. 为了解决这个问题, Java语言为内置数据类型char提供了包装类Character类. 可以使用Character的构造方 ...

  6. 《CSS世界》笔记二:盒模型四大家族

    上一篇:<CSS世界>笔记一:流/元素/尺寸下一篇:<CSS世界>笔记三:内联元素与对齐 写在前面 在读<CSS世界>第四章之前,粗浅的认为盒模型无非是margin ...

  7. CSS揭秘读书笔记 (一)

    CSS揭秘读书笔记      (一) 一.半透明边框 要想实现半透明边框可以使用border: border: 10px  solid  hsla(0,0%,100%,.5); background: ...

  8. 《JavaScript面向对象编程指南(第2版)》读书笔记(二)

    <JavaScript面向对象编程指南(第2版)>读书笔记(一) <JavaScript面向对象编程指南(第2版)>读书笔记(二) 目录 一.基本类型 1.1 字符串 1.2 ...

  9. 《图解tcp/ip》读书笔记(二)

    <图解tcp/ip>读书笔记(二) 本周主要阅读的是本书的第三章--数据链路. 当然了,从某些角度讲,我认为这一章就是计算机网络的最基本的内容之一.整章讲述了数据链路层的作用和相关技术,主 ...

  10. 图解TCP/IP读书笔记(二)

    图解TCP/IP读书笔记(二) 第二章.TCP/IP基础知识 一.TCP/IP出现的背景及其历史 年份 事件 20世纪60年代后半叶 应DoD(美国国防部)要求,美国开始进行通信技术相关的研发 196 ...

随机推荐

  1. maven和glassfish安装和部署及hello1和hello2的部署

    1.安装maven和glassfish及配置环境变 首先搜索并下载maven3.6.0和glassfish4.1.1(版本看按需要选择). 点击安装包进行安装 安装完成后开始配置环境变量 打开系统环境 ...

  2. 执行发送邮件Send方法时,报错:邮箱不可用。 服务器响应为: 5.7.1 Unable to relay for xxx@xxx.com

    .net代码在执行发送邮件Send方法时,往往出现这个的报错: 邮箱不可用. 服务器响应为: 5.7.1 Unable to relay for xxx@xxx.com 这个问题应该是smtp的设置问 ...

  3. bitmap 合并图片

    把两张bitmap覆盖合成为一张图 /** * 把两个位图覆盖合成为一个位图,以底层位图的长宽为基准 * @param backBitmap 在底部的位图 * @param frontBitmap 盖 ...

  4. Enable Coded UI Testing of Your Controls

    http://msdn.microsoft.com/en-us/library/hh552522.aspx AccessibleObject Class http://msdn.microsoft.c ...

  5. 颠覆传统的Word进阶

    第1课视频:无所不能的多样“替换”,为你换来大把时间 第2课视频:长文档的排版,又快又美又专业 - 之快 第3课视频:长文档的排版,又快又美又专业 - 之好 第4课视频:长文档的排版,又快又没有专业 ...

  6. Mysqlutil.JDBCutil.Dtabaseutil数据库操作工具类[批量操作]

    一个用来操作数据库的常用工具类. 提供批量操作,生成建表,插入语句等 操作示例: // 1.获取连接 DataBaseUtil jdbc = new DataBaseUtil(); jdbc.getC ...

  7. 2017(5)软件架构设计,web系统的架构设计,数据库系统,分布式数据库

    试题五(共 25 分) 阅读以下关于 Web 系统架构设计的叙述,在答题纸上回答问题1 至问题 3. [说明] 某公司开发的 B2C 商务平台因业务扩展,导致系统访问量不断增大,现有系统访问速度缓慢, ...

  8. webpack入门操作教程

    1. webpack介绍 在传统的项目中,一个html文件可能会加载多个js.css文件,如果多人协同开发的话,就会出现全局变量被污染.文件直接的依赖问题 而webpack打包工具,会先分析入口文件的 ...

  9. MySQL 误删数据、误更新数据(update,delete忘加where条件)

    MySQL 误操作后数据恢复(update,delete忘加where条件) 关键词:mysql误删数据,mysql误更新数据 转自:https://www.cnblogs.com/gomysql/p ...

  10. ngnix 反向代理来解决前端跨域问题

    1.定义 跨域是指a页面想获取b页面资源,如果a.b页面的协议.域名.端口.子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源.注意:跨域限制访 ...