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

Posted

技术标签:

【中文标题】使弹性项目在一行中具有相等的宽度【英文标题】:Make flex items have equal width in a row 【发布时间】:2017-11-30 09:22:08 【问题描述】:

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

但我没有成功。

.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>

【问题讨论】:

你的意思是和section-child一样宽高吗? 我需要“标题”、“更长的标题”、“长得多的标题”的容器都具有相同的宽度 即父 section.section 内的所有 div.section-childs 具有相同的宽度 在这个例子中,每个div.section-child的宽度应该等于div.section-child的宽度,内容是Much much longer title 【参考方案1】:

在你的代码中有好几次,你写的是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,因为弹性值只是提示,没有包装“长得多的标题”会占用太多空间。如果你真的想使用nowrap,你必须确保你的容器足够大并且可能使用溢出。

【讨论】:

感谢您指出错字。我知道我可以用边框替换孩子。但我不希望删除 nowrap。否则,节标题将位于多行。溢出也是如此。【参考方案2】:

弹性盒方法

为了使文本项(.section-child)等宽,你需要使用flex: 1 1 0,你已经这样做了。这和说flex: 1是一样的。

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

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

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

.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>

更多信息:

Make flex-grow expand items based on their original size Why doesn't flex item shrink past content size?

CSS 网格方法

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

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

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

但是 flexbox 规范中没有关于基于特定兄弟大小的相等大小的弹性项目。但是,flexbox 的姊妹技术 CSS Grid 可以做到。

通过使用 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>

它是这样工作的:

Equal height rows in CSS Grid Layout

【讨论】:

【参考方案3】:

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

flex: 1 1 100%添加到sectionchild,它会根据设置为100%同等收缩(或增长)

添加overflow: hidden,或min-width,告诉section-child他们可以小于他们的内容

flex-basis: 100%flex-grow: 1 添加到section,它将完全使用其父级top-level

作为vertical-separator,我在每个section-child 上都使用了伪::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>

【讨论】:

以上是关于使弹性项目在一行中具有相等的宽度的主要内容,如果未能解决你的问题,请参考以下文章

具有相等高度的弹性盒子内部项目[重复]

如何使弹性项目以固定宽度包裹

为啥弹性项目的宽度和高度会影响弹性项目的呈现方式?

如何将包装弹性项目显示为最后一行左对齐的空格?

当它的同级具有不同的宽度时,居中一个弹性项目[重复]

如何安排弹性项目以占据容器的整个宽度?