你不该忽视的小问题之margin叠加篇

在我刚开始学习html的时候,几乎所有会的人都说最多一个星期就学会了。当我学习css到了一定阶段的时候,觉得也挺容易的呀,为什么有那么多人都做了那么久,还在那儿研究什么呢?与此同时,还有很多人去吐槽jquery,说它就是设计师玩儿的东西,前端敲代码的你应该去研究js以及各种框架诸如此类等等,反正你要让自己在搞的东西别人听了觉得高大上、不明觉厉就对了。这样的现象也不能说不好,因为毕竟还是在不断的学习,可是,不得不说也是浮躁的表现,高手用树叶都能杀人,你却一直只想要绝世好剑,在鄙视自己的道路上前进不止~问题是你也顺便鄙视了别人,呵呵。

每种技术确实都存在着一些不足,但亮点也绝对是大于不足的,还远没到被你说烂的地步,不然它也不会那么流行并且被你知道和愿意学习。
不多说了,回到正题——margin。

我们平时在写代码的时候,经常会拿一个词用来形容显示异常,叫“bug”。bug它也分为“人为”和浏览器。margin的这个叠加算不算呢?~在遇到这些问题的时候,你绝不能仅仅是觉得不对劲,或者以一句“应该是浏览器的问题吧“去敷衍过去,而是要进一步寻求真相。

margin的叠加有三种方式

第一种方式我觉得大家都不会去忽视,那就是两个上下相邻的元素,上边元素的下外边距会与下边元素的上外边距叠加,叠加的意思不是二者相加,而是取更大者。

你不该忽视的小问题之margin叠加篇 - 灵感 - linggan

绿色边框是h2标题,未消除底外边距,计算之后近似12px,但红色箭头所标出的外边距为30px,是蓝色边框容器所添加的上外边距。此为不同元素间的上下重合。

第二种是有容器之间的嵌套,父元素和子元素外边距也会相叠加,有一个条件是,中间没有边框和外边距存在,那到底是谁没有边框或者内边距呢,父元素还是子元素?

你不该忽视的小问题之margin叠加篇 - 灵感 - linggan

此图中,蓝色边框30px上外边距未变。红色边框元素添加了50px上外边距,看起来很正常,

你不该忽视的小问题之margin叠加篇 - 灵感 - linggan

把红色边框的上边框去掉了,也正常

你不该忽视的小问题之margin叠加篇 - 灵感 - linggan

此图中,蓝色边框去除,哇偶,父子紧紧贴在了一起亲密无间~而且父元素和上面的元素的边距变成了50px!由此可见,取决于父元素的边框~那么,加个内边距试试呢?

你不该忽视的小问题之margin叠加篇 - 灵感 - linggan

咱给父元素加了10px的内边距,好吧,父子又分离了。由此可见,内边距也是取决于父元素。
子元素加内边距和去除边框的情况就不在这里跟大家展示了,已测对边距叠加无影响。

第三种呢,那就是,自己跟自己打架。同样要求无边框和内边距。
为了方便(也就是方便我自己罢了,哈哈),咱在刚才那个红色边框容器里加上个容器

你不该忽视的小问题之margin叠加篇 - 灵感 - linggan

再澄清一下纯属为了方便哈,跟另外俩容器没任何关系,当然,可以用来对比。不过。。咦,你加的是啥?容器呢?你这么做可不好,什么都看不到怎么能明白呢?!
好吧,千万不要怪我,下面分开解释

一、自己跟自己打架是有个前提的,那就是,元素为空,空是什么意思呢,内容为空,而且没有高度,这样上下外边距就碰面了,就可以打了~所以你什么都看不到了。

二、你说什么都看不到,但我明明看到了啊,红色容器不是被撑开了么,这就是奥妙所在,其实我在里面放了俩容器,而且,都加了外边距,什么?是的,都各加了30px的上下边距,什么?!是的,你没看错,理论上讲,这里应该有120px像素的高度出来,就算加上上面说的上下元素的边距会发生叠加,那也有90px吧?好吧,咱就算再退一步讲,中间30px也没了,那咱得有60px吧至少,可结果就是,只有30px了,这是见人杀人,见佛杀佛的节奏啊,这么一个小小的空白信息量也太丰富了吧?是不是醉了?~如果,你还是不相信它的残忍,再加几个也没关系,结果相同,还是30px。

友情提示,这种外边距叠加只是在普通流的块框元素才存在,而且是垂直外边距!行内框、浮动框、绝对定位框,没有这些叠加的出现。

好了,margin叠加的事儿咱就先说到这儿,其中奇妙还得各位自己去感受了。

第三种情况应该是极少会碰到的,因为一般不会出现这种用途的空元素,如果你只知道第一种而不知道第二种,那请相信你早晚会碰到第二种的,碰到的时候你会怎么办?索性不用外边距了?这的确是一种方法,可是,你不会总是能躲过去一些问题。

就像是文章开头所说的那样,这个话题只是一个引子。其实一个人的技术水平的提高就在于,不要勤于去说”知了“,而是要勤于发问,为什么?真的是这样么?还可以怎样?然后去实践、验证。再者,每个人都不会是全面系统的学习了之后才开始做页面的,都会时常带着一种兴奋去尝试,这样就难免只看到了知识的一面而漏掉了其他,或者理解不到位。时间长了就会遇到所谓的”瓶颈“~时常的去回顾,或者多找资料多方学习,才能让自己不断发现自身不足,不断进步,更全面,功夫更深。与大家共勉!~欢迎一起交流。

另推荐《精通css:高级web标准解决方案(第2版)》这本书,更适合有一定css编写经验的人看,收获会更大

因朋友提醒,又参考了一下别人的资料,在margin叠加的条件方面做如下修正:
相关链接

1.父子元素(分2种情况)之间发生margin叠加的条件:

父元素和第一个子元素发生margin-top叠加
父元素没有创建BFC(文章底部对BFC有简要介绍)
父元素和第一个子元素之间没有非空内容
父元素没有border-top
父元素没有padding-top

父元素和最后一个子元素发生margin-bottom叠加
父元素没有创建BFC
父元素height为auto、min-height为0
父元素和最后一个子元素之间没有非空内容
父元素没有border-bottom
父元素没有padding-bottom

2种情况都总结了,那么让他们不发生外边距叠加也就显得很容易了:

为父元素创建BFC
为父元素设置相应的padding或者border

2.兄弟元素之间发生外边距叠加的条件:

兄弟元素都不是float元素
兄弟元素都不是absolute元素
兄弟元素都不是inline-block元素

什么情况下会创建BFC ——Block Formatting Context (块格式化上下文)?

CSS 规范说明了在下列这些情况下会创建新的 block formatting context:
浮动元素(float: left | right);
绝对定位元素(position: absolute | fixed); 行内块元素(display: inline-block);
表格的单元格(display: table-cells,TD、TH); 表格的标题(display: table-captions,CAPTION);
‘overflow’ 特性不为 visible 的元素(除非该值已经传播到viewport); 表格元素创建的 “匿名框”

注意,”display:table” 本身并不产生 “block formatting contexts”。但是,它可以产生匿名框 6, 其中包含 “display:table-cell” 的框会产生块格式化上下文。 总之,对于 “display:table” 的元素,产生块格式化上下文的是匿名框而不是 “display:table”
注意,是这些元素创建了块格式化上下文,它们本身不是块格式化上下文。

修正告一段落,具体大家可以自行验证,欢迎学习交流!~