弹性容器中的等高行

Posted

技术标签:

【中文标题】弹性容器中的等高行【英文标题】:Equal height rows in a flex container 【发布时间】:2016-06-30 12:25:30 【问题描述】:

如您所见,第一个row 中的list-items 具有相同的height。但是第二个row 中的项目有不同的heights。我希望所有项目都有统一的height

有没有什么方法可以在不提供 fixed-height 并且只使用 flexbox 的情况下实现这一点?

这是我的code

.list 
  display: flex;
  flex-wrap: wrap;
  max-width: 500px;

.list-item 
  background-color: #ccc;
  display: flex;
  padding: 0.5em;
  width: 25%;
  margin-right: 1%;
  margin-bottom: 20px;

.list-content 
  width: 100%;
<ul class="list">
  <li class="list-item">
    <div class="list-content">
      <h2>box 1</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
  </li>
  <li class="list-item">
    <div class="list-content">
      <h3>box 2</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
  </li>

  <li class="list-item">
    <div class="list-content">
      <h3>box 2</h3>
      <p>Lorem ipsum dolor</p>
    </div>
  </li>

  <li class="list-item">
    <div class="list-content">
      <h3>box 2</h3>
      <p>Lorem ipsum dolor</p>
    </div>
  </li>
  <li class="list-item">
    <div class="list-content">
      <h1>h1</h1>
    </div>
  </li>
</ul>

【问题讨论】:

一种方法是在可以改变高度的元素上设置高度 【参考方案1】:

对于相同的高度,您应该更改您的 css“显示”属性。有关更多详细信息,请参见给出的示例。

.list
  display: table;
  flex-wrap: wrap;
  max-width: 500px;


.list-item
  background-color: #ccc;
  display: table-cell;
  padding: 0.5em;
  width: 25%;
  margin-right: 1%;
  margin-bottom: 20px;

.list-content
  width: 100%;
<ul class="list">
  <li class="list-item">
    <div class="list-content">
    <h2>box 1</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
    </div>
  </li>
  <li class="list-item">
    <div class="list-content">
    <h3>box 2</h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
  </li>
  
    <li class="list-item">
    <div class="list-content">
    <h3>box 2</h3>
    <p>Lorem ipsum dolor</p>
    </div>
  </li>
  
    <li class="list-item">
    <div class="list-content">
    <h3>box 2</h3>
    <p>Lorem ipsum dolor</p>
    </div>
  </li>
  <li class="list-item">
    <div class="list-content">
      <h1>h1</h1>
    </div>
  </li>

【讨论】:

谢谢,但我想在多行中显示列表。【参考方案2】:

在您的情况下,高度将自动计算,因此您必须提供高度 用这个

.list-content
  width: 100%;
  height:150px;

【讨论】:

对不起,高度可能因内容而异。所以不能给出固定的高度。 高度是自动计算的,所以随着你的内容不同,高度会有所不同,所以你必须使用固定高度,否则你不能得到统一的高度。【参考方案3】:

你可以通过固定“P”标签的高度或固定“list-item”的高度来做到这一点。

我已经通过固定“P”的高度来完成

并且溢出应该被隐藏。

.list
  display: flex;
  flex-wrap: wrap;
  max-width: 500px;


.list-item
  background-color: #ccc;
  display: flex;
  padding: 0.5em;
  width: 25%;
  margin-right: 1%;
  margin-bottom: 20px;

.list-content
  width: 100%;

pheight:100px;overflow:hidden;
<ul class="list">
  <li class="list-item">
    <div class="list-content">
    <h2>box 1</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
    </div>
  </li>
  <li class="list-item">
    <div class="list-content">
    <h3>box 2</h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
  </li>
  
    <li class="list-item">
    <div class="list-content">
    <h3>box 2</h3>
    <p>Lorem ipsum dolor</p>
    </div>
  </li>
  
    <li class="list-item">
    <div class="list-content">
    <h3>box 2</h3>
    <p>Lorem ipsum dolor</p>
    </div>
  </li>
  <li class="list-item">
    <div class="list-content">
      <h1>h1</h1>
    </div>
  </li>
</ul>

【讨论】:

好像不是我要找的答案,如果内容变大就隐藏了。 @JinuKurian 我在其中添加溢出:隐藏,如果将其更改为溢出:自动,则会出现滚动。然后你也可以看到完整的内容【参考方案4】:

不,如果不设置固定高度(或使用脚本),您将无法实现。


这是我的 2 个答案,展示了如何使用脚本来实现类似的目标:

How to get header from cards or similar to have the same height with flex box?

Same height for flex items in the flex-direction column flex container

【讨论】:

【参考方案5】:

答案是否定的。

flexbox 规范中提供了原因:

6. Flex Lines

在多行弹性容器中,每行的交叉尺寸是包含该行上的弹性项目所需的最小尺寸。

换句话说,当基于行的弹性容器中有多行时,每行的高度(“交叉大小”)是包含该行上的弹性项目所需的最小高度。

然而,在 CSS 网格布局中,等高的行是可能的:

Equal height rows in CSS Grid Layout

否则,请考虑使用 javascript 替代方案。

【讨论】:

css 网格现在可以安全使用吗?【参考方案6】:

如果您知道要映射的项目,您可以通过一次执行一行来完成此操作。我知道这是一种解决方法,但它确实有效。

对我来说,我每行有 4 个项目,所以我把它分成两行,每行 4 个,每行 height: 50%,去掉 flex-grow,在 &lt;div&gt; 中有 &lt;RowOne /&gt;&lt;RowTwo /&gt; flex-column。这样就可以了

<div class='flexbox flex-column height-100-percent'>
   <RowOne class='flex height-50-percent' />
   <RowTwo class='flex height-50-percent' />
</div>

【讨论】:

【参考方案7】:

这似乎适用于固定父级高度的情况(在 Chrome 和 Firefox 中测试):

.child 
        height    : 100%;
        overflow  : hidden;


.parent 
        display: flex;
        flex-direction: column;
        height: 70vh; // ! won't work unless parent container height is set
        position: relative;

如果由于某种原因无法使用网格,也许这就是解决方案。

【讨论】:

【参考方案8】:

您现在可以使用display: grid 完成此操作

.list 
  display: grid;
  overflow: hidden;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr;
  grid-column-gap: 5px;
  grid-row-gap: 5px;
  max-width: 500px;

.list-item 
  background-color: #ccc;
  display: flex;
  padding: 0.5em;
  margin-bottom: 20px;

.list-content 
  width: 100%;
<ul class="list">
  <li class="list-item">
    <div class="list-content">
      <h2>box 1</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
  </li>
  <li class="list-item">
    <div class="list-content">
      <h3>box 2</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
  </li>

  <li class="list-item">
    <div class="list-content">
      <h3>box 2</h3>
      <p>Lorem ipsum dolor</p>
    </div>
  </li>

  <li class="list-item">
    <div class="list-content">
      <h3>box 2</h3>
      <p>Lorem ipsum dolor</p>
    </div>
  </li>
  <li class="list-item">
    <div class="list-content">
      <h1>h1</h1>
    </div>
  </li>
</ul>

虽然网格本身不是 flexbox,但它的行为非常类似于 flexbox 容器,并且网格内的项目可以是 flex

如果您需要响应式网格,网格布局也非常方便。也就是说,如果您希望网格每行具有不同数量的列,则只需更改 grid-template-columns:

grid-template-columns: repeat(1, 1fr); // 1 column
grid-template-columns: repeat(2, 1fr); // 2 columns
grid-template-columns: repeat(3, 1fr); // 3 columns

等等……

您可以将其与媒体查询混合使用,并根据页面大小进行更改。

遗憾的是,浏览器中仍然不支持container queries / element queries(开箱即用),使其能够很好地根据容器大小而不是页面大小更改列数(这对与可重用的网络组件一起使用)。

有关网格布局的更多信息:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout

支持跨浏览器的网格布局:

https://caniuse.com/#feat=css-grid

【讨论】:

这是我喜欢的那种“可以做”的方法!也感谢您的工作示例 这并没有实现与 flexbox 包装相同的行为。这个问题也要求使用 flexbox 回答。 @Andy 正如已接受的答案所说,您无法使用 flexbox(没有 js)实现这一目标。我还确定说它真的不是 flexbox(“虽然网格本身不是 flexbox...”),我并不是说行为与 flexbox 完全相同(这很明显),但它非常类似并解决了所提出的问题(除了它不是 flexbox 的事实),更重要的是,它可能会为其他搜索类似方法的用户解决类似的问题。此外,这些项目可以是 flexbox(例如,与需要表格项目的表格布局相反)。【参考方案9】:

您可以使用 flexbox 解决水平问题:

.flex-list 
    padding: 0;
    list-style: none;
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;

.flex-list li 
    width: 120px;
    padding: .5rem;
    border-radius: 1rem;
    background: yellow;
<ul class="flex-list">
  <li>title 1</li>
  <li>title 2</li>
  <li>title 3<br>new line</li>
  <li>title 4<br>new line</li>
  <li>title 5<br>new<br>line</li>
  <li>title 6</li>
</ul>

或者使用网格来解决水平和垂直问题:

.grid-list 
   padding: 0;
   list-style: none;
   display: grid;
   grid-auto-columns: 1fr;
   grid-auto-rows: 1fr;
   grid-template-columns: repeat(3, 1fr);
   gap: .5rem;

    
.grid-list li 
   padding: .5rem;
   border-radius: 1rem;
   background: yellow;
   

.grid-list li:last-child 
   grid-column-start: 2;
  
<ul class="grid-list">
    <li>title 1</li>
    <li>title 2<br>new<br>line</li>
    <li>title 3<br>new line</li>
    <li>title 4<br>new line</li><li>title 5</li>
    <li>title 6<br>new<br>line</li>
    <li>title 7</li>
   </ul>

【讨论】:

我认为当项目垂直堆叠时,这给出的高度不相等。【参考方案10】:

你应该为你的 flex 显示使用 justify-content:stretchalign-items:stretch 属性,我认为这会使每个元素的高度在 flex 中相等

【讨论】:

在我的 Ubuntu 18.04.x 版本的 Chrome 中不是这样。高度不同。 可能适用于更高版本的 chrome mine 是 93.0.0【参考方案11】:

您可以通过以下方式实现:

align-items: stretch;

这会将每个项目拉伸到 flex 中具有最大高度的元素的高度。

【讨论】:

【参考方案12】:

Flexbox:让所有的 flexitem 高度相同?

n 子项

align-self: stretch;

或在父容器中 justify-content: stretch;

【讨论】:

以上是关于弹性容器中的等高行的主要内容,如果未能解决你的问题,请参考以下文章

缩放弹性容器中的子元素[重复]

弹性布局

Flex 弹性布局

弹性布局

弹性容器中的文本不会在 IE11 中换行

弹性容器中的文本不会在 IE11 中换行