【问题标题】:Margin collapsing in flexbox弹性框中的边距折叠
【发布时间】:2018-12-12 14:47:28
【问题描述】:

通常,在 CSS 中,当父级及其最后一个子级有边距时,边距会折叠以创建单个边距。例如

article {
  margin-bottom: 20px
}

main {
  background: pink;
  margin-bottom: 20px;
}

footer {
  background: skyblue;
}
<div id="container">
  <main>
    <article>
      Item 1
    </article>
    <article>
      Item 2
    </article>
  </main>
  <footer>Footer</footer>
</div>

如您所见,即使在articlemain 标签上都指定了20px 的边距,您也只能在最后一篇文章之间获得20px 边距和页脚

然而,当使用 flexbox 时,我们在最后一个 articlefooter 之间得到一个 40px 边距 — 一个完整的 20px从文章到 main 的页边距,以及从 main 到 footer 的另一个 20px

#container {
  display: flex;
  flex-direction: column;
}

article {
  margin-bottom: 20px
}

main {
  background: pink;
  margin-bottom: 20px;
}

footer {
  background: skyblue;
}
<div id="container">
  <main>
    <article>
      Item 1
    </article>
    <article>
      Item 2
    </article>
  </main>
  <footer>Footer</footer>
</div>

有没有办法让 flexbox 边距的行为与非 flexbox 的一样?

【问题讨论】:

    标签: css flexbox


    【解决方案1】:

    边距折叠是block formatting context 的一个功能。

    flex formatting context 中没有边距折叠。

    3. Flex Containers: the flex and inline-flex display values

    一个 flex 容器为其创建一个新的 flex 格式化上下文 内容。这与建立块格式化上下文相同, 除了使用 flex 布局而不是块布局。例如, 浮动不会侵入 flex 容器,并且 flex 容器的边距不会与其内容的边距一起折叠。

    【讨论】:

    • nnnnnooooooooooooooo 不要告诉我这个!如何摆脱模块之间的多余空间?
    • @TomRoggero 可能会为该内容添加一个包装器以在块格式化上下文中工作?然后包装器存在于 flex 格式化上下文中,但不存在于它的内容中——我猜。然而,换行往往会破坏好的、漂亮的语义标记。
    • 太烦人了,我们无法按照我们认为合适的方式打开/关闭边距折叠
    • 澄清一些我不清楚的事情:它是 flex 项目(而不是 flex 容器本身)没有得到崩溃的边距。这是一个示例:jsfiddle.net/tup8nxqo 您会注意到弹性项目 A、B、C 各有 50 像素的边距,但相距 100 像素。两个 flex 容器每个都有 100px 的边距,这些边距会塌陷。
    • @HenrikN,为了清楚起见——因为你提到了 A、B 和 C 的相对边距——边距折叠仅适用于垂直边距。 Horizontal margins never collapse.
    【解决方案2】:

    虽然 flexbox 无法实现边距折叠,但您可以使用 gap 来实现相同的结果:

    .parent {
        display: flex;
        flex-wrap: wrap;
        flex-direction: row;
        column-gap: 5px;
        row-gap: 15px;
          
        max-width: 70px;
        outline: 1px solid #440;
    }
    
    .parent > div {
        background: #8ff;
        width: 20px;
        height: 20px;
    }
    <div class="parent">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
    </div>

    https://coryrylan.com/blog/css-gap-space-with-flexbox

    【讨论】:

    【解决方案3】:

    注意:这不是让边距在弹性盒布局中的行为方式与在块布局中相同的方式;但是,在某些情况下,这可能有助于解决边距问题。

    您可以使用伪选择器来获得您想要的效果,而不是依赖折叠边距:

    main{
      display: flex;
      flex-direction: column;
      margin-bottom: 20px;
    }
    
    article{
      margin-bottom: 20px;
      background: #eee;
    }
    
    article:last-child{
      margin-bottom: 0;
    }
    
    footer{
      background: #eef;
    }
    <main>
      <article>
        This is article number 1
      </article>
      <article>
        This is article number 2
      </article>
      <article>
        This is article number 3
      </article>
    </main>
    <footer>
      This is the footer of the page
    </footer>

    【讨论】:

      【解决方案4】:

      接受的答案解释了为什么它不起作用,但没有提供解决方案。这是一种让 flexbox 元素像非 flexbox 示例一样对齐的方法。

      #container {
        display: flex;
        flex-direction: column;
      }
      
      main {
        background: pink;
        margin-bottom: 20px;
      }
      
      main > article + article {
        margin-top: 20px
      }
      
      footer {
        background: skyblue;
      }
      <div id="container">
        <main>
          <article>
            Item 1
          </article>
          <article>
            Item 2
          </article>
        </main>
        <footer>Footer</footer>
      </div>

      【讨论】:

      • 这不适用于包装元素
      【解决方案5】:

      margin-trim 很可能会添加到 css 规范中,它将处理这些类型的情况。更多详情请参阅https://developer.mozilla.org/en-US/docs/Web/CSS/margin-trim。浏览器支持可以看这里:https://caniuse.com/mdn-css_properties_margin-trim

      【讨论】:

        猜你喜欢
        • 2017-02-16
        • 2017-07-09
        • 2010-09-11
        • 2011-02-09
        • 1970-01-01
        • 2017-07-27
        • 1970-01-01
        相关资源
        最近更新 更多