<hr> 带有显示 flex 的内部容器损坏

<hr> inside container with display flex become corrupted

这种行为有点古怪。如果有一个容器,其 display 属性 设置为 flexflex-direction 设置为 column,则其中 <hr> 元素的方向将更改并变为垂直,其高度将减小以适应线条的高度。

html, body {
  height: 100%;
}
body {
  font-family: sans-serif;
}
.container {
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}
<div class="container">
  <h3>Title</h3>
  <hr/>
  <div class="content">
    <p>This is some content</p>
  </div>
</div>

查看 this pen

此行为已在 Firefox 和 Chrome 上得到确认。我没有找到任何解释。我该如何解决?

我发现将 <hr> 的宽度也设置 100% 可以解决问题。还是很奇怪,我不知道为什么会这样。

Here is a pen

根据HTML5 Rendering - The hr element,预计是这样渲染的:

hr { color: gray; border-style: inset; border-width: 1px; margin: 0.5em auto; }

具体来说,请注意 margin-left: automargin-right: auto

这些样式用于使块元素水平居中。根据Calculating widths and margins - Block

If both margin-left and margin-right are auto, their used values are equal. This horizontally centers the element with respect to the edges of the containing block.

在块布局中,只有当块具有明确的宽度时,此效果才会明显,否则块将增长以覆盖其所有包含块。

在 Flexbox 中它是相似的:默认 align-self: auto and align-items: stretch make flex items grow to cover the flex line in the cross axis (horizontal one in column layout), and auto margins can also be used to center.

然而,有一个很大的区别:根据 Cross Size Determinationalign-self: stretch 不会影响具有 auto 边距的弹性项目:

If a flex item has align-self: stretch, its computed cross size property is auto, and neither of its cross-axis margins are auto, the used outer cross size is the used cross size of its flex line, clamped according to the item’s min and max cross size properties. Otherwise, the used cross size is the item’s hypothetical cross size.

然后,您可以通过删除 auto 页边距来解决此问题:

hr {
  margin-left: 0;
  margin-right: 0;
}

.container {
  padding: 20px;
  display: flex;
  flex-direction: column;
}
hr {
  margin-left: 0;
  margin-right: 0;
}
<div class="container">
  <h3>Title</h3>
  <hr />
  <div class="content">
    <p>This is some content</p>
  </div>
</div>

或者,通过 widthmin-width 强制一定的宽度会抵消由 auto 边距引起的收缩(从技术上讲,缺乏拉伸)。

尝试将您的 hr 包含在另一个 flex-item 中(例如 divspan 或其他),如下所示。这将解决您的问题。

之所以可行,是因为弹性盒容器的所有子容器都是 flex-item。所以在你的例子中 hr 是 flex-item。这就是它的样式受到影响的原因。当您将此 hr 设为弹性盒容器的 grand-child 时,它将不再影响其样式。

这就是我们添加 <div> 作为 <hr/> 的父项的原因。 <div> 成为 flex 容器的 flex-item。 <hr> 不再是 flex-item。

html, body {
  height: 100%;
}
body {
  font-family: sans-serif;
}
.container {
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}
<div class="container">
  <h3>Title</h3>
  <div><hr/></div>
  <div class="content">
    <p>This is some content</p>
  </div>
</div>

进一步阅读(强烈推荐):