You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two margins are adjoining if and only if:
• both belong to in-flow block-level boxes that participate in the same block formatting context
• no line boxes, no clearance, no padding and no border separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
• both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
◦ top margin of a box and top margin of its first in-flow child
◦ bottom margin of box and top margin of its next in-flow following sibling
◦ bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
◦ top and bottom margins of a box that does not establish a new block formatting context and that has zero computed 'min-height', zero or 'auto' computed 'height', and no in-flow children
这里面有一个很重要的条件就是两个折叠元素都是普通文档流in-flow,并且没有非空内容、padding、border 或 clear 分隔开, 同时最后几个小例子也说明外边距折叠不一定只发生在相邻兄弟元素,父级与子元素也可以。
块级元素
块级元素也是现在web定位的主要依赖,最基本就是div + css了。对它再熟悉不过。 块级元素一个最大的特征就是它要独占一行,不管内容够不够,反正就是任性。 我们一点点来看块级元素的一些规则。
包含块
每个块级元素在横轴上都有margin-left、border-left、padding-left、width、padding-right、border-right、margin-right这个几个部分构成。一般width指内容区域。
而每个html元素都是由一个外层元素包裹的、我们真正页面上的最外层也至少被body包裹,body也是一个巨大的块级元素。
外层包裹的那个元素其实就是内部元素的“布局上下文”,外层包裹元素就是内层元素的包含块。可能有点抽象
在这个例子中,wrapper就是inner的包含块, inner就是p的包含块。
一般而言,元素都要在它的包含块内进行定位、显示、布局的。当然行内元素不考虑包含块。
水平—块级元素
我们知道一个块级元素 我们可以为其设置宽度,也可以不为其设置宽度。当不为其设置宽度时,它会自动铺满整行。其实这是有根据的:块级元素的宽度之和必须等于包含块的内容区域宽度(规则1,之后会提到) , 而块级元素的宽度之和是指块级元素内容区、左右内边距、左右边框和左右外边距的宽度之和。
正是有这个规定,所以我们平时才可以使用
margin: 0 auto
来实现水平居中。也就是说有在我们普通计算margin-left、border-left、padding-left、width、padding-right、border-right、margin-right
之和不能达到包含块的内容区域宽度时,肯定有属性被浏览器默认更改了。我们先来看一下各个值初始的默认情况:
我们来一点点测试。
html:
测试1
不附加任何css规则也就是全部都是默认值,结果发现黄色填满整行。
结论:在margin为0时(默认不进行设置),为满足刚才说的规则1, width会自动延展。
测试2
只设置margin-left或者margin-right, 可以发现结果还是width进行延展。
结论:在只设置一个margin时,为满足刚才说的规则1, width会自动延展。
测试3
设置margin-left和margin-right, 可以发现结果还是width进行延展。
结论:在设置margin-left和margin-right,为满足刚才说的规则1, width会自动延展。
测试4
只设置width时, 可以发现黄色部分尺寸固定,延展的是嘛margin-right。其实这个也可以理解,浏览器是从上到下,从左到右布局,不设置margin-left肯定是不太想有左边间隙,那扩展margin-right也无可厚非
结论:在仅设置width情况下,延展的是margin-right。
测试5
设置width和margin-left时, 可以发现黄色部分尺寸固定,延展的是嘛margin-right。
结论:与测试4的结论一致。
测试6
设置width和margin-right时, 可以发现黄色部分尺寸固定,延展的还是margin-right。
这里比较奇怪,明明设置的margin-right,但是和没设置一样的,那是因为margin-left也有默认值0哦,所以可能没效果,或者认为left优先级比right高吧,至少在从左向右排列格式时。
结论:与测试4的结论一致。
测试7
设置width和margin-right时,同时设置margin-left:auto, 可以发现黄色部分尺寸固定,延展的还是margin-left。
这一次我们发现终于按照我们设想的margin-right体现出来了。
结论:在主动更改margin-left为auto后,width和margin-right会按原设置宽度。
测试8
设置margin-left和width为auto,margin-right为初始值即0。结果与不进行任何设置一样。
结论:margin的auto优先级低于width的auto。
测试9
设置margin-left、margin-right、 width全部为auto。结果与测试8测试1一样。
结论:与测试8的结论一致。
结论
负margin
水平上负margin导致width总和可能会超出包含块内容区域。
一般为扩展宽度采用。
垂直—块级元素
在垂直方向上,其实一般不太关心,毕竟浏览器下滑已经是大家都习以为常的事情。 因此很多时候我们不会为块级元素设置高度。
默认情况下
height: auto
, 因此他会随着内部元素增加而自动拉伸,但如果显式的设置它的高度,他就不会再拉伸了。为垂直方向设置
margin: auto 0
,其实是没有意义的,它会将margin-top和margin-bottom重置为0, 其实它就失去了上下外边距。当然定位和浮动元素不算。外边距合并
在垂直外边距合并指的是,**当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。**但只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。
下面是w3c官方的解释 为什么会出现垂直外边距折叠。
按照规定来说我们如果要解决外边距折叠的问题可以有以下几条思路:
然后我们在这里都没有发现任何BFC(格式化上下文)的影子, 那为什么经常能看到BFC来解决外边距折叠呢?
先来看如何触发BFC:
看完上面的内容希望得出一个基本的结论: 外边距折叠是外边距折叠,BFC是BFC,两者还是要进行区别开来的。
总结
块级元素在CSS中其实不关心,CSS关心的是块级盒子,只是块级盒子是由块级元素产生的,这部分内容可以看另一篇BFC的文章。在块级盒子之上其实还有一个BFC的概念,BFC之内才是块级盒子自由的排版。但BFC不是一个特殊的元素,而是块级元素的某些特殊属性产生的。
上文仅仅介绍的是块级元素的一些特性,从水平和垂直两个切入点来理解块级元素的一些特性,也理解了一下外边距折叠的触发条件与解决思路。强烈推荐本文搭配BFC一起浏览。
The text was updated successfully, but these errors were encountered: