为什么 flexbox 中的内容会溢出?

Why is content overflowing in flexbox?

我遇到了一些我不理解的行为。当我设置一个徽章列表时,列表中的最大高度和列表项上的边距然后列表项的内容按边距按比例溢出它们的容器。

.badgers {
  display: flex;
  flex-direction: column;
  max-height: 10em;
  overflow: auto;
  border: 1px dashed red;
}

.badge, .title, .location, .timestamp {
  display: flex;
}

.badge {
  flex-direction: column;
  border: 1px solid black;
  margin: 1em 0;
}
<div class="badgers">
  <div class="badge">
      <span class="title">Title</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
  <div class="badge">
      <span class="title">Title 2</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
  <div class="badge">
      <span class="title">Title 3</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
</div>
  

如果我删除边距就不会溢出。

.badgers {
  display: flex;
  flex-direction: column;
  max-height: 10em;
  overflow: auto;
  border: 1px dashed red;
}

.badge, .title, .location, .timestamp {
  display: flex;
}

.badge {
  flex-direction: column;
  border: 1px solid black;
}
<div class="badgers">
  <div class="badge">
      <span class="title">Title</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
  <div class="badge">
      <span class="title">Title 2</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
  <div class="badge">
      <span class="title">Title 3</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
</div>
  

如果我将包装器更改为 display: block 并保留边距,那么列表看起来就是我想要的。

.badgers {
  max-height: 10em;
  overflow: auto;
  border: 1px dashed red;
}

.badge, .title, .location, .timestamp {
  display: flex;
}

.badge {
  flex-direction: column;
  border: 1px solid black;
  margin: 1em 0;
}
<div class="badgers">
  <div class="badge">
      <span class="title">Title</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
  <div class="badge">
      <span class="title">Title 2</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
  <div class="badge">
      <span class="title">Title 3</span>
      <span class="location">Location</span>
      <span class="timestamp">Timestamp</span>
  </div>
</div>
  

那为什么列表在display: flex; flex-direction: column的时候会溢出,而在display: block的时候不会呢?

默认情况下,弹性项目设置为 flex-shrink: 1 (source)。

这意味着它们可以缩小以避免溢出容器。

禁用此功能。制作你的弹性项目 flex-shrink: 0.


更新(基于评论):

  • 它在 Firefox 中不起作用。

    实际上,上述解决方案已在 Chrome、Firefox 和 Edge 中进行了测试。它有效(fiddle demo)。

  • 删除 flex-shrink: 0 后它在 Firefox 中仍然有效。

    这是因为在 Firefox 中另一个默认设置正在发挥作用:min-height: auto。这意味着弹性项目不能收缩到其内容的高度以下。 Chrome 对此做了 "intervention",它覆盖了规范设置。

    查看此 post 以获得完整解释:

    flex-shrink: 0 方法是可靠的跨浏览器解决方案。

  • 最后一项的页边距折叠。

    这可能是因为包含块是 "over-constrained"。

    查看此 post 以获得完整的解释和解决方案:Last margin / padding collapsing in flexbox