Como tornar os itens flexbox do mesmo tamanho?


186

Eu quero usar o flexbox que possui algum número de itens com a mesma largura. Percebi que o flexbox distribui o espaço uniformemente, e não o próprio espaço.

Por exemplo:

.header {
  display: flex;
}

.item {
  flex-grow: 1;
  text-align: center;
  border: 1px solid black;
}
<div class="header">
  <div class="item">asdfasdfasdfasdfasdfasdf</div>
  <div class="item">z</div>
</div>

O primeiro item é muito maior que o segundo. Se eu tiver 3 itens, 4 itens ou n itens, desejo que todos apareçam na mesma linha com uma quantidade igual de espaço por item.

Alguma ideia?

http://codepen.io/anon/pen/gbJBqM

Respostas:


287

Defina-os de forma que flex-basissejam 0(para que todos os elementos tenham o mesmo ponto de partida) e permita que eles cresçam:

flex: 1 1 0px

Seu IDE ou linter podem mencionar isso the unit of measure 'px' is redundant. Se você deixar de fora (como flex: 1 1 0:), o IE não renderizará isso corretamente. Portanto, pxé necessário dar suporte ao Internet Explorer, conforme mencionado nos comentários do @fabb;


65
Deve-se notar que a flexpropriedade é um atalho para os flex-grow, flex-shrinke flex-basispropriedades. É recomendável usar a abreviação sobre as propriedades individuais, pois ela redefine corretamente qualquer componente não especificado para acomodar usos comuns. O valor inicial é 0 1 auto.
j08691

3
nota que IE11 ignora valores-base flexível sem unidade: github.com/philipwalton/flexbugs#flexbug-4
fabb

9
Eu tive que adicionar min-width: 0para conseguir usar elementos filho com texto transbordando. Veja css-tricks.com/flexbox-truncated-text
Iwazaru 20/10/19

77

Você pode adicionar flex-basis: 100%para conseguir isso.

Exemplo atualizado

.header {
  display: flex;
}

.item {
  flex-basis: 100%;
  text-align: center;
  border: 1px solid black;
}

Pelo que vale, você também pode usar flex: 1os mesmos resultados.

A abreviação de flex: 1é igual a flex: 1 1 0, que é equivalente a:

.item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
  text-align: center;
  border: 1px solid black;
}

1
Isso não está correto. O valor flexível padrão é flex: 0 1 auto. O que significa que a configuração flex: 1resultará em flex: 1 1 auto. Isso não vai funcionar. A resposta correta é flex: 1 1 0como declarado acima por Adam
r.sendecky

17
@ r.sendecky Não, você é quem está incorreto. Como afirmei na minha resposta, a taquigrafia dos flex: 1resultados flex: 1 1 0 não é flex: 1 1 auto como você está reivindicando. Veja a especificação oficial do W3 na seção 'flex shorthand' : quando flex-basisé "omitido da flex shorthand, seu valor especificado é 0", não auto. Obrigado pelo voto aleatório.
Josh Crozier 29/01

2
@ r.sendecky - Além disso, dê uma olhada neste exemplo que criei para visualizar as variações.
Josh Crozier 29/01

1
Companheiro, eu não faço votos aleatórios. Eu testei antes de escrever. E eu testei. Sua resposta não funciona - simples assim. Eu tive exatamente o mesmo problema há não muito tempo com flex: 1e flex-direction: column. A altura das crianças não era a mesma quando outros elementos eram colocados nas crianças. A única coisa que consertou foi definir flex: 1 1 0. Ele ainda permanece hoje com o cromo 55.0.2883.87
r.sendecky

4
@JoshCrozier confirmou que flex: 1tem o mesmo comportamento flex: 1 1 0e flex: 0 1 autotem um comportamento diferente.
Ivan Durst

66

Você precisa adicionar width: 0para tornar as colunas iguais se o conteúdo dos itens aumentar.

.item {
  flex: 1 1 0;
  width: 0;
}

5
Isso parece ser necessário se o conteúdo de .itemfazê-lo crescer mais do que .itemseria naturalmente.
Bungle 15/12

1
Eu acho que você quer dizer flex: 1 1 0;, em vez deflex-grow: 1 1 0;
Chicken Soup

3
fyi, ligação é interrompida
Bobby Jack

A configuração de flex-basispara 0serve para o mesmo propósito que a configuração widthde 0.
19419 Stephen

No meu caso de uso, eu estava agrupando gráficos que se ajustam dinamicamente ao tamanho dos pais e a largura 0 era necessária para que eles funcionassem. Não tenho certeza de como eles estavam determinando a largura adequada, mas a base flexível certamente não funcionou no chrome 72 (lançado em janeiro de 2019).
Andy Groff

12

A resposta aceita por Adam ( flex: 1 1 0) funciona perfeitamente para contêineres flexbox cuja largura é fixa ou determinada por um ancestral. Situações em que você deseja que as crianças encaixem no recipiente.

No entanto, você pode ter uma situação em que deseja que o contêiner caiba nas crianças, com as crianças do mesmo tamanho com base na criança maior. Você pode fazer com que um contêiner flexbox se adapte a seus filhos:

  • configuração position: absolutee não configuração widthou right, ou
  • coloque-o dentro de um invólucro com display: inline-block

Para esses recipientes flexbox, a resposta aceita NÃO funciona, as crianças não têm o mesmo tamanho. Presumo que essa seja uma limitação do flexbox, pois se comporta da mesma maneira no Chrome, Firefox e Safari.

A solução é usar uma grade em vez de uma caixa flexível.

Demonstração: https://codepen.io/brettdonald/pen/oRpORG

<p>Normal scenario — flexbox where the children adjust to fit the container — and the children are made equal size by setting {flex: 1 1 0}</p>

<div id="div0">
  <div>
    Flexbox
  </div>
  <div>
    Width determined by viewport
  </div>
  <div>
    All child elements are equal size with {flex: 1 1 0}
  </div>
</div>

<p>Now we want to have the container fit the children, but still have the children all equally sized, based on the largest child. We can see that {flex: 1 1 0} has no effect.</p>

<div class="wrap-inline-block">
<div id="div1">
  <div>
    Flexbox
  </div>
  <div>
    Inside inline-block
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
</div>

<div id="div2">
  <div>
    Flexbox
  </div>
  <div>
    Absolutely positioned
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>

<br><br><br><br><br><br>
<p>So let's try a grid instead. Aha! That's what we want!</p>

<div class="wrap-inline-block">
<div id="div3">
  <div>
    Grid
  </div>
  <div>
    Inside inline-block
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
</div>

<div id="div4">
  <div>
    Grid
  </div>
  <div>
    Absolutely positioned
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
body {
  margin: 1em;
}

.wrap-inline-block {
  display: inline-block;
}

#div0, #div1, #div2, #div3, #div4 {
  border: 1px solid #888;
  padding: 0.5em;
  text-align: center;
  white-space: nowrap;
}

#div2, #div4 {
  position: absolute;
  left: 1em;
}

#div0>*, #div1>*, #div2>*, #div3>*, #div4>* {
  margin: 0.5em;
  color: white;
  background-color: navy;
  padding: 0.5em;
}

#div0, #div1, #div2 {
  display: flex;
}

#div0>*, #div1>*, #div2>* {
  flex: 1 1 0;
}

#div0 {
  margin-bottom: 1em;
}

#div2 {
  top: 15.5em;
}

#div3, #div4 {
  display: grid;
  grid-template-columns: repeat(3,1fr);
}

#div4 {
  top: 28.5em;
}

0

Não sou especialista em flex, mas cheguei lá definindo a base para 50% para os dois itens com os quais estava lidando. Aumente para 1 e diminua para 0.

Estilo embutido: flex: '1 0 50%',

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.