资讯专栏INFORMATION COLUMN

深入理解CSS外边距折叠(Margin Collapse)

zhonghanwen / 1967人阅读

摘要:我们可以注意定义中的几个关键字毗邻两个或多个垂直方向和普通流。如何避免外边距叠加上面讲了外边距的叠加,那如何避免呢,其实只要破坏上面讲到的四个条件中的任何一个即可毗邻两个或多个普通流和垂直方向。

外边距叠加一直是前端开发必须了解的一个概念,面试一般也会问到这个问题。所以整理一下相关外边距叠加相关的知识点。外边距叠加是什么?什么时候会发生外边距叠加?如何避免外边距叠加?

什么是外边距叠加

先来看看 W3C 对于外边距叠加的定义:

In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

大概意思是:在CSS中,两个或多个毗邻的普通流中的盒子(可能是父子元素,也可能是兄弟元素)在垂直方向上的外边距会发生叠加,这种形成的外边距称之为外边距叠加。

我们可以注意定义中的几个关键字:毗邻、两个或多个、垂直方向和普通流。

毗邻

毗邻说明了他们的位置关系,没有被 paddingborderclearline box 分隔开。

两个或多个

两个或多个盒子是指元素之间的相互影响,单个元素不会存在外边距叠加的情况。

垂直方向

Horizontal margins never collapse.

只有垂直方向的外边距会发生外边距叠加。水平方向的外边距不存在叠加的情况。

普通流(in flow)

啥为普通流?W3C 只对 out of flow 作了定义:

An element is called out of flow if it is floated, absolutely positioned, or is the root element.An element is called in-flow if it is not out-of-flow.

从定义中我们可以知道只要不是 floatabsolutely positionedroot element 时就是 in flow。

什么时候会发生外边距叠加

外边距叠加存在两种情况:一是父子外边距叠加;二是兄弟外边距叠加。

W3C 对于什么是毗邻的外边距也有定义:

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

从定义中我们可以很清楚的知道要符合哪些情况才会发生外边距折叠:

都属于普通流的块级盒子且参与到相同的块级格式上下文中

没有被padding、border、clear和line box分隔开

都属于垂直毗邻盒子边缘:

盒子的top margin和它第一个普通流子元素的top margin

盒子的bottom margin和它下一个普通流兄弟的top margin

盒子的bottom margin和它父元素的bottom margin

盒子的top margin和bottom margin,且没有创建一个新的块级格式上下文,且有被计算为0的min-height,被计算为0或auto的height,且没有普通流子元素

Demo 1
.parent1 {
    height: 20px;
    background: yellow;
    margin-bottom: 20px;
}
.parent2 {
    margin: 20px 0 30px;
}
.parent3 {
    height: 20px;
    background: green;
    margin-top: 20px;
}
.child {
    background: red;
    height: 20px;
    margin: 40px 0 30px;
}

这个 demo 里的 .parent2 和第一个 .child 的 top margin 叠加,导致 .parent1.parent2 之间的边距为 40px。

Demo 2

还是用上面的代码,.parent2 中的 .child 中的 top margin 和 bottom margin 发生外边距叠加,它们之间的外边距为 40px。

Demo 3

还是上面的代码,.parent2 中的最后一个 .child 发生 bottom margin 叠加,.parent2
.parent3 之间的边距为 30px。

Demo 4
.demo {
    height: 30px;
    background: red;
}
.margin-test {
    margin: 20px 0 30px;
}

这个 demo 是上面的第四种情况,元素自身的外边距 topbottom 发生折叠,我们可以看出 .container 的高度为 90px,这里可以看到 margin-testtopbottom 外边距发生了折叠。

如何避免外边距叠加

上面讲了外边距的叠加,那如何避免呢,其实只要破坏上面讲到的四个条件中的任何一个即可:毗邻、两个或多个、普通流和垂直方向。

W3C也对此做了总结:

Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).

Margins of elements that establish new block formatting contexts (such as floats and elements with "overflow" other than "visible") do not collapse with their in-flow children.

Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).

Margins of inline-block boxes do not collapse (not even with their in-flow children).

The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.

The top margin of an in-flow block element collapses with its first in-flow block-level child"s top margin if the element has no top border, no top padding, and the child has no clearance.

The bottom margin of an in-flow block box with a "height" of "auto" and a "min-height" of zero collapses with its last in-flow block-level child"s bottom margin if the box has no bottom padding and no bottom border and the child"s bottom margin does not collapse with a top margin that has clearance.

A box"s own margins collapse if the "min-height" property is zero, and it has neither top or bottom borders nor top or bottom padding, and it has a "height" of either 0 or "auto", and it does not contain a line box, and all of its in-flow children"s margins (if any) collapse.

翻译一下:

浮动元素不会与任何元素发生叠加,也包括它的子元素

创建了 BFC 的元素不会和它的子元素发生外边距叠加

绝对定位元素和其他任何元素之间不发生外边距叠加,也包括它的子元素

inline-block 元素和其他任何元素之间不发生外边距叠加,也包括它的子元素

普通流中的块级元素的 margin-bottom 永远和它相邻的下一个块级元素的 margin-top 叠加,除非相邻的兄弟元素 clear

普通流中的块级元素(没有 border-top、没有 padding-top)的 margin-top 和它的第一个普通流中的子元素(没有clear)发生 margin-top 叠加

普通流中的块级元素(height为 auto、min-height为0、没有 border-bottom、没有 padding-bottom)和它的最后一个普通流中的子元素(没有自身发生margin叠加或clear)发生 margin-bottom叠加

如果一个元素的 min-height 为0、没有 border、没有padding、高度为0或者auto、不包含子元素,那么它自身的外边距会发生叠加

本文首发于有赞技术博客:http://tech.youzan.com/css-ma...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/112313.html

相关文章

  • 深入CSS外边折叠(margin collapse)详解

    摘要:发生外边距折叠的条件是什么垂直方向上相邻的两个元素这种情况很好理解,就是上面的例子中给出的情况。外边距折叠后的大小两个相同大小的正数取某个外边距的值。即与发生折叠,折叠后的值为。根据块级格式化上下文来阻止外边距折叠。 什么是外边距折叠 准确来说,外边距折叠应该叫垂直外边距折叠,因为只会发生在垂直方向上,而水平方向上不会发生。 对于以下简单的html代码和css代码, 请问top块和bo...

    ctriptech 评论0 收藏0
  • CSS margin合并问题

    摘要:两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。两个外边距一正一负时,折叠结果是两者的相加的和。 在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。 1. 折叠的结果 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。 两个相邻的外边距都是负数时...

    zhongmeizhi 评论0 收藏0
  • 关于CSS里BFC特性的理解和应用

    摘要:它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。而,块级格式化上下文,就是一个块级元素的渲染显示规则。定位和清除浮动的样式规则只适用于处于同一块格式化上下文内的元素。 什么是BFC(Block Formatting Context) Formatting context(格式化上下文) 是 W3C CSS2.1 规范中的一个概念...

    shixinzhang 评论0 收藏0
  • 关于CSS里BFC特性的理解和应用

    摘要:它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。而,块级格式化上下文,就是一个块级元素的渲染显示规则。定位和清除浮动的样式规则只适用于处于同一块格式化上下文内的元素。 什么是BFC(Block Formatting Context) Formatting context(格式化上下文) 是 W3C CSS2.1 规范中的一个概念...

    vspiders 评论0 收藏0
  • CSS规范 > 8 盒模型 Box Model

    摘要:当两个及以上外边距折叠,合并后的外边距宽度是发生折叠的外边距中的最大宽度。如果该元素的外边距同其父元素的上外边距折叠,则该盒的上边框边缘同其父元盒的上边框边缘相同。 2017-07-20: 关于外边距折叠, 推荐问题: https://segmentfault.com/q/10... 8 盒模型 Box Model URL: http://www.w3.org/TR/CSS2/box...

    suemi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<