使弹性项目在一行中具有相等的宽度

Make flex items have equal width in a row

在下面的示例中,我希望 headers (h4.child-title) 在 parent 容器中具有相同的长度。

但是我没有成功实现。

.top-level {
  display: flex;
  flex-flow: row wrap;
}

.section {
  display: flex;
  flex-flow: row nowrap;
  border: 1px solid;
  margin-right: 12px;
  margin-top: 12px;
}

.section-child {
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  flex: 1 1 0;
}

.child-title {
  white-space: nowrap;
}

.vertical-separator {
  width: 1px;
  background-color: rgba(0, 0, 0, 0.3);
  margin: 8px;
}
<div class="top-level">
  <section class="section">
    <div claas="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div claas="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div claas="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
</div>

在你的代码中有好几次,你写了 claas 而不是 class:

<div claas="section-child">
  <h4 class="child-title">Title</h4>
  <!--A lot more content here-->
</div>

那么您应该通过删除 vertical-separator div 并改用 css 边框来简化 html 结构:

.top-level {
  display: flex;
  flex-flow: row wrap;
}

.section {
  display: flex;
  flex-flow: row nowrap;
  border: 1px solid;
  margin-right: 12px;
  margin-top: 12px;
}

.section-child {
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  flex: 1 1 0;
}

.section-child:not(:last-of-type) {
  margin: 8px 0;
  border-right: solid 1px rgba(0, 0, 0, 0.3);
}

.child-title {
  white-space: wrap;
}
<div class="top-level">
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
</div>

我删除了 .child-titlewhite-space: nowrap,因为 flex 值只是提示,如果不换行 "Much much longer title" 会占用太多 space。如果你真的想使用nowrap,你必须确保你的容器足够大,并且可能使用溢出。

Flexbox 方法

为了使文本项 (.section-child) 等宽,您需要使用 flex: 1 1 0,您已经做到了。这与说 flex: 1.

相同

但是,这本身并不能实现目标,原因有二:

  1. .section-child 的父级,一个弹性容器,也是一个更大容器中的弹性项目,默认情况下限制为其内容的宽度。所以它不会展开并且文本会溢出容器。您还需要将 flex: 1 应用到 .section

  2. 默认情况下,弹性项目不能小于其内容的大小。初始设置为 min-width: auto。所以 flex: 1 无法平均分配容器 space,因为 flex 项目不能收缩超过最长的项目。您需要使用 min-width: 0.

  3. 覆盖此行为

.top-level {
  display: flex;
  flex-flow: row wrap;
}

.section {
  display: flex;
  flex-flow: row nowrap;
  border: 1px solid;
  margin-right: 12px;
  margin-top: 12px;
  flex: 1;
  min-width: 0;
}

.section-child {
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.child-title {
  white-space: nowrap;
}

.vertical-separator {
  width: 1px;
  background-color: rgba(0, 0, 0, 0.3);
  margin: 8px;
}
<div class="top-level">
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
</div>

现在所有弹性项目都是等宽的。但是,因为您将文本设置为 nowrap,它可能会溢出其边界。如果你删除 nowrap,一切都很合适。

.top-level {
  display: flex;
  flex-flow: row wrap;
}

.section {
  display: flex;
  flex-flow: row nowrap;
  border: 1px solid;
  margin-right: 12px;
  margin-top: 12px;
  flex: 1;
  min-width: 0;
}

.section-child {
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.child-title {
  /* white-space: nowrap; */
}

.vertical-separator {
  width: 1px;
  background-color: rgba(0, 0, 0, 0.3);
  margin: 8px;
}
<div class="top-level">
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
</div>

更多信息:


CSS网格法

如果您的实际目标是使行中的所有弹性项目都等于最长项目的宽度,那是 flexbox 无法做到的。

flex可以做等宽等高的flex项目,因为它在主轴上提供了flex: 1

Flex也可以做到等宽等高的列/行,因为它在横轴上提供了align-items: stretch

但是 flexbox 规范中没有关于基于特定兄弟大小的相等大小 flex 项目的任何内容。不过flexbox的姊妹技术CSSGrid可以做到。

通过使用 Grid 的 fr 单元,可以将网格中的列宽设置为最长列的宽度。

.top-level {
  display: flex;
  flex-flow: row wrap;
}

.section {
  display: grid;
  grid-template-columns: 1fr 1px 1fr 1px 1fr;
  margin-right: 12px;
  margin-top: 12px;
}

.section-child {
  display: flex;
  justify-content: center;
  align-items: center;
  min-width: 0;
  background-color: green;  
}

.child-title {
  /* white-space: nowrap; */
}

.vertical-separator {
  background-color: rgba(0, 0, 0, 0.3);
  margin: 8px;
}
<div class="top-level">
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title text text text text text text text text text text</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title text text text text text text</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="vertical-separator"></div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
</div>

工作原理如下:

Flexbox 不是 table 类布局的完美选择,但您可以接近:

  • flex: 1 1 100%添加到sectionchild,它会在设置为100%的基础上同样收缩(或增长)

  • 添加overflow: hiddenmin-width,告诉section-child它们可以小于它们的内容

  • flex-basis: 100%flex-grow: 1 添加到 section,它将完全占据其父 top-level

作为 vertical-separator,我在除第一个 section-child 之外的每个 ::after 上使用伪 ::after,因为它使用绝对位置,position: relative section-child.

需要

.top-level {
  display: flex;
  flex-flow: row wrap;
}

.section {
  flex-basis: 100%;              /*  added  */
  display: flex;
  flex-flow: row nowrap;
  border: 1px solid;
  margin-right: 12px;
  margin-top: 12px;
}

.section-child {
  position: relative;             /*  added  */
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  flex: 1 1 100%;                 /*  added  */
  overflow: hidden;               /*  added  */
}

.child-title {
  white-space: nowrap;
}

.section-child + .section-child::after {
  content: '';
  position: absolute;
  left: 0;
  top: 10%;
  height: 80%;
  border-left: 1px solid rgba(0,0,0,0.3);
}
<div class="top-level">
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
  <section class="section">
    <div class="section-child">
      <h4 class="child-title">Title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Longer title</h4>
      <!--A lot more content here-->
    </div>
    <div class="section-child">
      <h4 class="child-title">Much much longer title</h4>
      <!--A lot more content here-->
    </div>
  </section>
</div>