Fileiras de altura igual em um flex container

94

Como você pode ver, list-itemso primeiro rowtem o mesmo height. Mas os itens do segundo rowsão diferentes heights. Quero que todos os itens tenham um uniforme height.

Existe alguma maneira de conseguir isso sem dar altura fixa e usando apenas o flexbox ?

insira a descrição da imagem aqui

Aqui está o meu 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>

Jinu Kurian
fonte
Uma maneira é definir a altura no elemento que pode variar em altura
onmyway133

Respostas:

80

A resposta é não.

O motivo é fornecido na especificação do flexbox:

6. Flex Lines

Em um contêiner flexível com várias linhas, o tamanho cruzado de cada linha é o tamanho mínimo necessário para conter os itens flexíveis na linha.

Em outras palavras, quando há várias linhas em um flex container baseado em linha, a altura de cada linha (o "tamanho cruzado") é a altura mínima necessária para conter os flex items na linha.

Linhas de altura igual, no entanto, são possíveis no layout de grade CSS:

Caso contrário, considere uma alternativa de JavaScript.

Michael Benjamin
fonte
A grade css é segura para usar agora?
Alexander Kim
43

Você pode fazer isso agora com 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>

Embora a grade em si não seja flexbox, ela se comporta de forma muito semelhante a um contêiner flexbox e os itens dentro da grade podem ser flex .

O layout da grade também é muito útil no caso de você desejar grades responsivas. Ou seja, se você quiser que a grade tenha um número diferente de colunas por linha, basta alterar 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

e assim por diante...

Você pode misturá-lo com consultas de mídia e alterar de acordo com o tamanho da página.

Infelizmente, ainda não há suporte para consultas de contêiner / consultas de elemento nos navegadores (pronto para uso) para fazer funcionar bem com a alteração do número de colunas de acordo com o tamanho do contêiner, não para o tamanho da página (isso seria ótimo de usar com componentes da web reutilizáveis).

Mais informações sobre o layout da grade:

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

Suporte do layout de grade em navegadores:

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

Lucas basquerotto
fonte
Este é o tipo de abordagem "posso fazer" de que gosto! Obrigado pelo exemplo de trabalho também
hananamar
isso não implementa o mesmo comportamento que a embalagem flexbox. também a pergunta feita para uma resposta usando o flexbox.
Andy
@Andy Como a resposta aceita já diz, você não pode conseguir isso com flexbox (sem js). Também fiz questão de dizer que não é realmente flexbox ("Embora a grade em si não seja flexbox ..."), e não estou dizendo que o comportamento é exatamente o mesmo do flexbox (o que é óbvio), mas é muito semelhante e resolve o problema solicitado (exceto pelo fato de não ser flexbox) e, mais importante , pode resolver problemas semelhantes para outros usuários que procuram uma abordagem semelhante. Além disso, os itens podem ser flexbox (ao contrário de um layout de tabela, que espera itens de tabela, por exemplo).
Lucas Basquerotto
1

Isso parece estar funcionando em casos com altura parental fixa (testado no Chrome e 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;
}

Se não for possível usar grades por algum motivo, talvez seja a solução.

Stanislav E. Govorov
fonte
0

Se você conhece os itens que está mapeando, pode fazer isso fazendo uma linha de cada vez . Eu sei que é uma solução alternativa, mas funciona.

Para mim, eu tinha 4 itens por linha, então dividi em duas linhas de 4 com cada linha height: 50%, se livrar de flex-grow, ter <RowOne />e <RowTwo />em um <div>com flex-column. Isto irá fazer o truque

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

No seu caso, a altura será calculada automaticamente, então você deve fornecer a altura para
usar este

.list-content{
  width: 100%;
  height:150px;
}
Tom
fonte
Sinto muito, a altura pode variar com o conteúdo. Portanto, não pode dar altura fixa.
Jinu Kurian,
As alturas são calculadas automaticamente, portanto, com o seu conteúdo diferente, as alturas serão diferentes, então você deve usar uma altura fixa, caso contrário, você não pode obter alturas uniformes.
Tom,
-1

Você pode com o flexbox:

ul.list {
    padding: 0;
    list-style: none;
    display: flex;
    align-items: stretch;
    justify-items: center;
    flex-wrap: wrap;
    justify-content: center;
}
li {
    width: 100px;
    padding: .5rem;
    border-radius: 1rem;
    background: yellow;
    margin: 0 5px;
}
<ul class="list">
  <li>title 1</li>
  <li>title 2<br>new line</li>
  <li>title 3<br>new<br>line</li>
</ul>

Hisham Dalal
fonte
Não acho que isso dê altura igual quando os itens são empilhados verticalmente.
workwise
desculpe, mas você pode tentar outra resposta em vez de marcar minha resposta como negativa!
Hisham Dalal
-3

você pode fazer isso fixando a altura da tag "P" ou fixando a altura do "item da lista".

Eu fiz fixando a altura de "P"

e o estouro deve ser escondido.

.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%;
}
p{height: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>

Ajay Malhotra
fonte
Parece não ser a resposta que procuro, se o conteúdo aumentar, ficará oculto.
Jinu Kurian,
@JinuKurian onde estou adicionando overflow: hidden, se você mudar para overflow: auto então scroll aparecerá. então você pode ver o conteúdo completo também
Ajay Malhotra
-6

para a mesma altura, você deve alterar as propriedades de "exibição" do css. Para obter mais detalhes, consulte o exemplo dado.

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

Ankit
fonte
Obrigado, mas quero exibir as listas em várias linhas.
Jinu Kurian,