【问题标题】:The impact of 'overflow' values other than 'visible' on the block formatting context'visible' 以外的 'overflow' 值对块格式化上下文的影响
【发布时间】:2014-07-24 07:58:15
【问题描述】:

这个问题类似于this one(答案很好),虽然我的问题与浮动问题无关。

我最近在尝试对块级元素的唯一子元素应用边距时遇到了一些麻烦:

#parent {
    background: rgba(255, 0, 0, 0.1);
}

#child {
    margin: 30px 0;
    padding: 20px;
    background: rgba(0, 255, 0, 0.1);
}
<div id="parent">
    <div id="child">Foo</div>
</div>

虽然应用了边距,但没有应用父级的背景。除非在#child 之前和之后添加兄弟姐妹,或者(在我看来更有趣)设置了除visible 之外的任何值的overflow,否则这仍然是正确的。这是相同的示例,但具有溢出值:

#parent {
    background: rgba(255, 0, 0, 0.1);
    overflow: auto;
}

#child {
    margin: 30px 0;
    padding: 20px;
    background: rgba(0, 255, 0, 0.1);
}
<div id="parent">
    <div id="child">Foo</div>
</div>

CSS2.1 Section 9.4.1 - Block Formatting Contexts,我发现了以下内容:

浮动、绝对定位元素、不是块框的块容器(例如内联块、表格单元格和表格标题),以及具有“溢出”而不是“可见”的块框(该值除外已传播到视口)为其内容建立新的块格式化上下文。

在这种情况下,我真的很难理解“可见之外的溢出”逻辑背后的基本原理。在这种情况下,边缘似乎没有被剪裁,因为唯一需要改变的是背景。有人能证明为什么 overflow: visible 的值会造成这种情况吗?

【问题讨论】:

  • 我相信(从记忆中)除了“可见”之外的任何东西都会形成一个新的子布局(最明显的效果通常是块内的 z 索引是自包含的)。没有这个,你就会有边距折叠的效果,使你的背景变小(内部孩子的边距与盒子之一和它接触的任何东西合并)。
  • 我想知道边距是否默认不透明,除非强制不折叠。此外,它不仅仅是overflowjsfiddle.net/TylerH/u6tQj/1 border 也会让它出现。好问题。
  • 至于为什么在正常情况下边距合并,这是因为通常这是您想要的(例如,段落边距与页眉边距合并,导致两者之间的最大边距而不是附加边距)。 TylerH(以及在外部元素上设置填充)在两个边距之间放置一些东西的边框效果,迫使它们不合并。
  • 哦,我了解边距裁剪的正常情况:)

标签: html css


【解决方案1】:

正如我在对您链接到的问题的回答中所涵盖的那样,overflow 值而不是 visible 导致新块格式化上下文的主要原因是由于与浮点数相关的实现限制,即使概念of overflow 似乎并没有立即与浮点数有关系。

虽然浮动和折叠边距之间的关系非常简单(它从不发生),但边距不能通过具有overflow 值的元素的边界折叠的事实很少不仅仅是此更改的副作用,因为边距被定义为不会折叠任何建立块格式上下文的框,如section 8.3.1 中所述。我引用:

  • 建立新块格式上下文的元素(例如浮动和具有“溢出”而不是“可见”的元素)的边距不会与其流入的子级一起折叠。

这包括浮点数和具有overflow 值的元素。溢出本身实际上对边距没有任何直接影响。

当父子元素都是参与同一个块格式化上下文的块级元素时,它们会默认折叠,除非有什么阻碍:

  • 如果元素没有上边框、没有上边距且子元素没有间隙,则流入块元素的上边距与其第一个流入块级子元素的上边距一起折叠。

  • 如果盒子没有底部,则“height”为“auto”且“min-height”为零的流入块框的下边距折叠为其最后一个流入块级子元素的底部边距padding 并且没有下边框,并且孩子的下边距不会与具有间隙的上边距折叠。

这解释了为什么在您尝试阻止边距折叠之前父级的背景不会扩展。

【讨论】:

  • 你是怎么找到这些问题的!谢谢你,正计划在某个时候进行跟进,并在 W3C/Moz 列表上询问这个问题,如果有机会我可能还会这样做
  • @Ian Clark:作为标签维护的一部分,我正在处理一些 CSS2.1 规范问题,碰巧偶然发现了你的问题 :)
  • @Ian Clark:是的,这绝对值得问他们,因为只有 CSSWG 才能回答为什么确切地说建立一个新的 BFC 会阻止保证金以这种方式崩溃。见stackoverflow.com/questions/19756678/…
【解决方案2】:

在您的第一个示例中,父项和子项的顶部和底部边距是折叠的。粗略地说,child 的 30px 边距与 parent 的 0 边距相结合,两者中较大的边距应用于父级。 Quote:

在 CSS 中,两个或多个框的相邻边距(可能或 可能不是兄弟姐妹)可以组合形成一个边距。边距 据说以这种方式组合会崩溃,并且由此产生的组合 边距称为折叠边距。

在同一个文档中,解释了溢出的影响(如您的第二个示例):

建立新块格式化上下文的元素的边距(例如 因为浮动和具有“溢出”而不是“可见”的元素)不 和他们流入的孩子一起崩溃。

【讨论】:

    【解决方案3】:

    这澄清了我偶尔遇到的高度问题。看起来父元素的高度不是根据子元素的边距计算的。

    调整你的小提琴:http://jsfiddle.net/u6tQj/2/

    #parent { background: #555;}
    #child { margin:200px; background: #ccc; }
    

    边距应用于子级,但父级的高度不受影响。添加溢出或边框会导致高度调整。我有时会为为什么父元素并不总是扩展以包含子元素而感到困惑。

    看起来很奇怪,但是……

    在父身高方面有冲突的规则可能会很复杂。它会影响许多浏览器布局,例如相对于子级设置为绝对的父级位置,或溢出自动/隐藏,以及可能的许多其他布局算法。我想这会不必要地使浏览器的布局引擎复杂化,就像 css 选择器的特殊性有时会给我们带来很大的痛苦一样。

    您可以向父级添加填充以调整其高度,这更直观(不是吗?)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-14
      • 2016-05-08
      • 1970-01-01
      • 2019-07-29
      • 2016-04-05
      相关资源
      最近更新 更多