【问题标题】:Why does a negative bottom margin on an element decrease the height of parent of that element?为什么元素上的负下边距会降低该元素父级的高度?
【发布时间】:2012-10-23 19:29:52
【问题描述】:

这可能是由于边距折叠造成的,我知道边距折叠,至少它如何影响相邻元素,但我不明白当涉及负边距时它如何作用于嵌套元素。

例如,在此标记和随附的 CSS 中:

标记

<div class="parent">
  <div class="child">
    Child 1
  </div>
</div>

<div class="parent">
  <div class="child negative">
    Child 1
  </div>
</div>

CSS

body {
  background: white;
  padding: 45px;
}

.parent {
  border: 1px solid black;
  margin-bottom: 10px;
}

.negative {
  margin-bottom: -1px;
}

现场示例here

当我检查第二个 .parent div 的高度时,我注意到它比第一个小 1 个像素。之所以发生这种情况,是因为其中的 .negative 元素有负边距。我快速浏览了 W3C,但找不到这种行为的解释。

有人可以解释一下这里发生了什么,并为我提供一个指向 W3C 规范部分的链接吗?

【问题讨论】:

    标签: html css margin


    【解决方案1】:

    这可能是由于边距折叠造成的,我知道边距折叠,至少它如何影响相邻元素,但我不明白当涉及负边距时它如何作用于嵌套元素。

    Section 8.3.1 包含所有详细信息。它还涵盖了嵌套框之间相邻边距的行为,以及负边距。

    但是,您在此处看到的不是边距折叠的影响,因为您在 .parent 规则中使用 border: 1px solid black 声明否定了它。这意味着那里有一个边框可以防止您的 .parent 边距与您的 .child.negative 边距完全折叠。

    相反,这就是负边距的工作原理。这在可视化格式化模型的各个部分都有介绍,但在 Section 11 的开头最简洁直接地解决了这一点,总结如下:

    通常,块框的内容被限制在框的内容边缘。在某些情况下,盒子可能会溢出,这意味着它的内容部分或全部位于盒子之外,例如:

    所以这里发生的事情是:

    1. .child.negative 元素的负边距的绝对值从.parent 元素的实际高度中减去(1px)。

    2. 因此,.child.negative 元素本身会溢出.parent(因为它自己的高度没有改变,并且任何div 的默认overflowvisible)。

    3. 由于此处的边距折叠不生效,因此您的.parent 中的margin-bottom: 10px 不受影响。请注意,虽然正常流中的任何后续元素都将向上移动1px,这主要是由于您的.child.negative 元素的负边距;换句话说,步骤 1 的副作用。

    仅此而已。

    【讨论】:

    • 感谢您的回答。我曾经不时使用这种技术,我从经验中了解到它有效,但今天我注意到我不知道为什么。感谢您提供指向规范的链接,但我仍然看不到规则 #1 写在规范中的哪个位置(我看到“后代框有负边距,导致它部分位于框外。”但不是事实上,父母的身高应该减少。我认为这是唯一可能的结论,因为负边距通常是如何工作的,但它在某处有更详细的解释吗?)
    • 另外,您是否知道 W3C CSS 邮件列表中的电子邮件。这应该如何实现?
    • @Bill Jobs:是的,这就是一般负边距的工作方式。正边距将一个盒子推离其他盒子,并且 - 如果边距折叠没有到位 - 会导致其父盒子扩大,而负边距将其他盒子向内拉并另外导致其父盒子缩小。
    • @Bill Jobs:任何 CSS 问题的一般邮件列表是 www-style@w3.org。欢迎提出实施问题;一些工作组成员也是实施者,这可能会有所帮助:)
    【解决方案2】:

    当您使用.negative { margin-bottom: -1px; } 时,它将移动到顶部。看这个例子。

    请参考您容易理解的以下链接。 http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/

    body {
      background: white;
      padding: 45px;
    }
    
    .parent {
      border: 1px solid black;
      margin-bottom: 10px;
      min-height: 30px;
    }
    
    .negative {
      margin-bottom: 20px;
    }
    

    结论:

    例如在您的情况下,我必须将min-height:30px 添加到父类,以便它保持fix。仅当您将 positive margins 添加到负类时才移动。仅仅因为您可以在上图中看到结果,就说明了您所需要的一切。

    查看 cssdesk 链接click here cssdesk

    希望对您有所帮助。干杯。 !!

    【讨论】:

    • 边距通常用于定位,请考虑top: 50%; height: 100px; margin-top: -50px; centering hack。
    【解决方案3】:

    当外部元素没有边框、填充和内容时,第一个和最后一个元素的边距将应用于外部元素,而不是自身。

    在您的情况下,父节点有边框,因此在这种情况下边距折叠将不适用。由于内部子节点的 margin-bottom = -1px ,当计算子节点的外部高度时,它将是其内容的高度 + 填充 + 边框宽度 + 边距。因此,从外部测量时会减少 1px。这就是为什么父节点的高度会比上面的例子少 1px。为了看得更清楚,你可以给子节点加一个背景,比如说黄色,你会发现子节点会和父节点的边框重叠。

    但是如果去掉父节点的边框,情况就完全不同了。

    例如解释边距折叠,说你有

    <div style="background-color:black">
      <div style="height:10px; background-color:white; margin-top: 10px"></div>
    </div>
    

    您不会看到 10px 高度的黑框,因为外部节点将被视为顶部有 10px 的边距,而内部节点的边距将被忽略。而对于负数情况,外边距会减小。

    引用spec:

    当两个或多个边距折叠时,产生的边距宽度是折叠边距宽度的最大值。在负边距的情况下,从正相邻边距的最大值​​中减去负相邻边距的绝对值的最大值。如果没有正边距,则从零中减去相邻边距绝对值的最大值。

    更多信息: https://developer.mozilla.org/en-US/docs/CSS/margin_collapsing

    【讨论】:

    • @BoltClock 我认为我不需要解释为什么 10-1 是 9。投票所有人都没有帮助。
    • 在这种情况下,您的回答完全无关紧要。当答案错误或不相关时,我会投票否决……这就是拥有否决按钮的全部意义。
    • 怎么不相关?这是对问题的正确解释。
    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多