Come rendere gli articoli flexbox delle stesse dimensioni?


186

Voglio usare la flexbox che ha un certo numero di elementi che hanno tutti la stessa larghezza. Ho notato che flexbox distribuisce lo spazio uniformemente, piuttosto che lo spazio stesso.

Per esempio:

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

Il primo oggetto è molto più grande del secondo. Se ho 3 articoli, 4 articoli o n articoli, voglio che vengano visualizzati tutti sulla stessa riga con lo stesso spazio per articolo.

Qualche idea?

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

Risposte:


287

Impostali in modo che flex-basissiano 0(quindi tutti gli elementi hanno lo stesso punto di partenza) e consenti loro di crescere:

flex: 1 1 0px

Il tuo IDE o linter potrebbe menzionarlo the unit of measure 'px' is redundant. Se lo lasci fuori (come flex: 1 1 0:), IE non lo renderà correttamente. Quindi pxè necessario per supportare Internet Explorer, come menzionato nei commenti di @fabb;


65
Va notato che la flexproprietà è una proprietà abbreviata per flex-grow, flex-shrinke flex-basisproperties. Si consiglia di utilizzare la scorciatoia sulle singole proprietà poiché la stenografia reimposta correttamente tutti i componenti non specificati per gli usi comuni. Il valore iniziale è 0 1 auto.
j08691,

3
notare che IE11 ignora i valori di base flessibile unitless: github.com/philipwalton/flexbugs#flexbug-4
fabb

9
Ho dovuto aggiungere min-width: 0per ottenere utilizzando elementi figlio con testo traboccante. Vedi css-tricks.com/flexbox-truncated-text
Iwazaru

78

Puoi aggiungere flex-basis: 100%per raggiungere questo obiettivo.

Esempio aggiornato

.header {
  display: flex;
}

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

Per quello che vale, puoi anche usare flex: 1gli stessi risultati.

La scorciatoia di flex: 1è la stessa di flex: 1 1 0, che equivale a:

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

1
Questo non è corretto Il valore di flessione predefinito è flex: 0 1 auto. Il che significa che flex: 1risulterà l' impostazione flex: 1 1 auto. Questo non funzionerà. La risposta corretta è flex: 1 1 0come affermato sopra da Adam
r

17
@ r.sendecky No, sei tu quello che non è corretto. Come ho affermato nella mia risposta, la scorciatoia dei flex: 1risultati flex: 1 1 0 non è flex: 1 1 auto come te. Dai un'occhiata alle specifiche ufficiali W3 nella sezione "stenografia flessibile" : quando flex-basis"viene omesso dalla stenografia flessibile, il suo valore specificato è 0", no auto. Grazie per il downvote casuale.
Josh Crozier,

2
@ r.sendecky - Inoltre, dai un'occhiata a questo esempio che ho creato per visualizzare le variazioni.
Josh Crozier,

1
Amico, non faccio un voto negativo casuale. Provo prima di scrivere. E l'ho provato. La tua risposta non funziona - così semplice. Ho avuto esattamente lo stesso problema non molto tempo fa con flex: 1e flex-direction: column. L'altezza dei bambini non era la stessa quando altri elementi venivano posizionati all'interno dei bambini. L'unica cosa che l'ha risolto è stata l'impostazione flex: 1 1 0. Rimane ancora oggi con il cromo 55.0.2883.87
r

4
@JoshCrozier ha confermato che flex: 1ha lo stesso comportamento flex: 1 1 0e flex: 0 1 autoha un comportamento diverso.
Ivan Durst,

66

È necessario aggiungere width: 0per rendere uguali le colonne se il contenuto degli elementi aumenta.

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

5
Ciò sembra essere necessario se il contenuto di .itemesso lo fa allargare di quanto .itemsarebbe naturalmente.
Bungle,

1
Penso che intendi flex: 1 1 0;, invece diflex-grow: 1 1 0;
Chicken Soup, il

3
a proposito, il collegamento è interrotto
Bobby Jack,

l'impostazione del flex-basisto ha 0lo stesso scopo dell'impostazione del widthto 0.
Stephen,

Nel mio caso d'uso, stavo avvolgendo i grafici che si adattavano dinamicamente alle dimensioni dei loro genitori e la larghezza 0 era necessaria per farli funzionare. Non sono sicuro di come stessero determinando la larghezza corretta, ma la base flessibile certamente non ha funzionato su Chrome 72 (rilasciato gennaio 2019).
Andy Groff,

12

La risposta accettata da Adam (flex: 1 1 0 ) funziona perfettamente per i contenitori flexbox la cui larghezza è fissa o determinata da un antenato. Situazioni in cui si desidera che i bambini si adattino al contenitore.

Tuttavia, potresti avere una situazione in cui desideri che il contenitore si adatti ai bambini, con i bambini di dimensioni uguali in base al bambino più grande. Puoi rendere un contenitore flexbox adatto ai suoi figli:

  • impostazione position: absolutee non impostazione widtho right, o
  • metterlo all'interno di un involucro con display: inline-block

Per tali contenitori flexbox, la risposta accettata NON funziona, i bambini non hanno le stesse dimensioni. Presumo che questa sia una limitazione di flexbox, dal momento che si comporta allo stesso modo in Chrome, Firefox e Safari.

La soluzione è utilizzare una griglia anziché una flexbox.

Demo: 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

Non sono un esperto di flex, ma ci sono arrivato impostando la base al 50% per i due articoli con cui avevo a che fare. Passa a 1 e riduci a 0.

Stile in linea: flex: '1 0 50%',

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.