Scatola flessibile: allinea l'ultima riga alla griglia


379

Ho un semplice layout a scatola flessibile con un contenitore come:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

Ora voglio che gli elementi nell'ultima riga siano allineati con l'altro. justify-content: space-between;dovrebbe essere usato perché la larghezza e l'altezza della griglia possono essere regolate.

Attualmente sembra

L'articolo in basso a destra dovrebbe essere nel mezzo

Qui, voglio che l'elemento in basso a destra sia nella "colonna centrale". Qual è il modo più semplice per farlo? Ecco un piccolo jsfiddle che mostra questo comportamento.

.exposegrid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.exposetab {
  width: 100px;
  height: 66px;
  background-color: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
  margin-bottom: 10px;
}
<div class="exposegrid">
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
</div>



Controlla qui la mia soluzione Penso che funzioni bene senza hack, solo matematica: stackoverflow.com/questions/18744164/…
Sebastien Lorber,

5
In alternativa, utilizzare potrebbe utilizzare il più recente modulo griglia CSS - che non presenta questo problema
Danield,


1
Ho aggiunto una soluzione JS generica per i casi in cui la larghezza del figlio è variabile, rendendo variabile anche il numero di elementi sulla riga.
Tao,

Risposte:


417

Aggiungi un ::afterche riempie automaticamente lo spazio. Non è necessario inquinare il tuo HTML. Ecco un codice che lo mostra: http://codepen.io/DanAndreasson/pen/ZQXLXj

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid::after {
  content: "";
  flex: auto;
}

17
Sarebbe possibile farlo funzionare con lo spazio intorno in qualche modo?
Tom,

61
@DanAndreasson Ci sono due problemi, non parte da sinistra (come lo spazio tra) e anche lo spazio tra gli elementi dell'ultima riga è diverso rispetto alla riga precedente (simulando alcuni elementi a larghezza fissa in "qualsiasi dimensione" griglia - riguarda entrambi) ... codepen.io/anon/pen/gPoYZE Quello che volevo è mantenere la "strategia" (spazio intorno o spazio tra) ma iniziare da sinistra come nelle righe precedenti ... I volevo sapere se è possibile generalizzare la tua straordinaria soluzione.
Tom,

44
Questo funziona solo perché gli articoli hanno imbottitura allo spazio loro e le larghezze percentuali combinata uguale al 100% per ciascun set di 4. In questo codepen ho rimosso justify-content: space-between;da .gride rimosso .grid:aftere funziona lo stesso. Ora, se hai provato qualcosa del genere, si è completamente rotto. Notare che le larghezze per ogni set di 4 non si sommano al 100%. Nel violino dell'OP le larghezze sono impostate in px, quindi la tua soluzione non funziona in questa situazione.
Jacob Alvarez,

22
Provando questa soluzione, inizialmente, gli elementi che era a corto nell'ultima riga non erano distribuiti correttamente space-between. Tuttavia, quando imposto flex-basisdi .grid:afterallo stesso dimensionamento degli altri elementi nella griglia (per punto di interruzione, sovrascrivendo il codice del modulo predefinito / di base sopra), l'ultima riga viene distribuita correttamente. Sembra funzionare su Safari, iOS, Firefox, Chrome (è necessario testare IE) e la mia dimensione di riga più grande è 3 sulla mia implementazione iniziale.
webbower

8
Per le mie esigenze, ciò ha funzionato con la seguente modifica: { content: "";flex: 0 0 32%;max-width: 480px;}e ho modificato la larghezza massima con modifiche alla media query in modo che la griglia fosse perfetta a tutte le larghezze.
Colin Wiseman,

160

Una tecnica consisterebbe nell'inserire un numero di elementi extra (fino al numero massimo di elementi che ti aspetti di avere in una riga) a cui viene assegnata un'altezza zero. Lo spazio è ancora diviso, ma le file superflue collassano nel nulla:

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

In futuro, ciò potrebbe diventare realizzabile mediante l'utilizzo di multipli ::after(n).


11
Purtroppo questo contamina il markup in modo non semantico, ma funziona totalmente. : Vorrei sapere qualcos'altro per replicare questo comportamento, flexbox o altro, che non richiedeva gli elementi non semantici.
Ryan Norbauer,

33
D'accordo, è sporco, ma funziona ed è meno confuso di molti hack. Dai un'occhiata, lo sto usando, fino a quando :: after (12) ottiene supporto, o aggiungono alcune opzioni di giustificazione aggiuntive. È un vero peccato perché il modo in cui la flexbox giustifica il lavoro al momento è semplicemente sbagliato! Se stavi giustificando un paragrafo di testo non proveresti mai a giustificare l'ultima riga. Avrebbe sicuramente dovuto essere un'opzione, non posso credere che abbiano perso questo.
Codemonkey,

4
Ho escogitato una soluzione solo CSS ... il fatto è che può sempre e solo tenere conto di due elementi mancanti, quindi funzionerà in modo sicuro in una griglia flessibile con un massimo di tre elementi per riga di avvolgimento. Demo: codepen.io/lukejacksonn/pen/dozqVq Il principio qui è usare gli pseudo elementi come figli extra e dare loro la stessa proprietà flessibile degli oggetti nel contenitore.
Lukejacksonn,

8
@Codemonkey Jesus. Ho iniziato a usare Flexbox solo pensando a come sbarazzarmi di tutti questi hack intesi ad allineare quei blocchi inline all'interno di una griglia, e ora si scopre che semplicemente non è possibile! Ho subito colpito quel blocco, raggiungendo i limiti che pensavo non avrei quasi mai raggiunto felicemente risolvendo tutti questi vecchi problemi CSS irrisolvibili. Non così in fretta, immagino. Ci sono voluti solo 20 anni per ottenere un corretto centraggio verticale - sicuramente possiamo aspettare. Gesù, sembra un compito così semplice ...
Andrey,

3
@dalgard Non penso proprio. Vedere il mio commento .
Jacob Alvarez,

109

Come hanno già detto altri poster, non esiste un modo chiaro per allineare a sinistra l'ultima riga con la flexbox (almeno secondo le specifiche attuali)

Tuttavia, per quello che vale: con il CSS Grid Layout Module questo è sorprendentemente facile da produrre:

Fondamentalmente il codice pertinente si riduce a questo:

ul {
  display: grid; /* 1 */
  grid-template-columns: repeat(auto-fill, 100px); /* 2 */
  grid-gap: 1rem; /* 3 */
  justify-content: space-between; /* 4 */
}

1) Trasforma l'elemento contenitore in un contenitore griglia

2) Imposta la griglia con colonne automatiche di larghezza 100px. (Si noti l'uso del riempimento automatico (come allegato auto-fit- che (per un layout a 1 riga) comprime le tracce vuote su 0 - facendo espandere gli oggetti per occupare lo spazio rimanente. Ciò comporterebbe un 'spazio tra "layout quando la griglia ha solo una riga che nel nostro caso non è quella che vogliamo. (guarda questa demo per vedere la differenza tra loro)).

3) Impostare spazi / grondaie per le righe e le colonne della griglia - qui, poiché si desidera un layout "spazio tra" - lo spazio sarà effettivamente uno spazio minimo perché crescerà secondo necessità.

4) Simile a flexbox.

Codepen Demo (Ridimensiona per vedere l'effetto)


4
Bella soluzione. L'unico problema è che non funziona con IE10 / 11.
zendu,

1
Per quanto riguarda auto-fit, c'era un bug in Chrome 57-60 (e browser basati sul suo motore, come Samsung Internet 6.0) perché le specifiche erano un po 'ambigue al momento. Ora le specifiche sono state chiarite e le nuove versioni di Chrome vengono visualizzate auto-fitcorrettamente, ma i browser con il vecchio motore sono ancora in uso, quindi fai attenzione con questo valore.
Ilya Streltsyn,

4
Alla luce delle attuali possibilità, questa dovrebbe essere la risposta accettata. L'uso di :afterpseudo-elemento può portare a risultati indesiderati in casi limite.
Paul,

2
@ Danield questo suggerimento mi ha aiutato molto, grazie!
Krys,

4
Questa dovrebbe essere la risposta accettata. Lo combinerei con flexbox come fallback, nello spirito di un miglioramento progressivo: i browser che non supportano la griglia visualizzerebbero la versione flexbox, che è abbastanza vicina per me.
Palantir,

27

Senza alcun markup aggiuntivo, solo l'aggiunta ha ::afterfunzionato per me specificando la larghezza della colonna.

.grid {
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
}
.grid::after{
  content: '';
  width: 10em // Same width of .grid__element
}
.grid__element{
  width:10em;
}

Con l'HTML in questo modo:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>

9
questo è interessante, ma non del tutto corretto. il problema si presenta quando hai a che fare con più di due elementi nella riga inferiore: la spaziatura che emerge tra gli elementi delle righe sopra non emerge mai nell'ultima; gli articoli sono imballati insieme, annullando l'utilità originale dello spazio tra.
John Haugeland

ancora meglio se usi flex-basis: 10em invece di larghezza.
beytarovski

14

Non puoi. Flexbox non è un sistema a griglia. Non ha i costrutti del linguaggio per fare ciò che stai chiedendo, almeno non se lo stai usandojustify-content: space-between . Il più vicino che puoi ottenere con Flexbox è usare l'orientamento della colonna, che richiede l'impostazione di un'altezza esplicita:

http://cssdeck.com/labs/pvsn6t4z (nota: prefissi non inclusi)

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}

Tuttavia, sarebbe più semplice utilizzare solo le colonne, che ha un supporto migliore e non richiede l'impostazione di un'altezza specifica:

http://cssdeck.com/labs/dwq3x6vr (nota: prefissi non inclusi)

ul {
  columns: 15em;
}

2
C'è un modo; vedi la mia risposta.
Dalgard,

@dalgard, la tua risposta è una soluzione alternativa, non una vera soluzione. la risposta di cimmanon è corretta.
Giona,

1
@Jonah Penso che "tecnica" sia una buona descrizione della mia risposta. Ha sicuramente funzionato come soluzione per molte persone, incluso il richiedente.
Dalgard

2
@dalgard Non cambia il fatto che Flexbox non fornisce i costrutti del linguaggio per fare ciò che viene chiesto. Inoltre, direi che aggiungere elementi falsi è una pratica estremamente sporca, proprio lì con l'uso di tabelle per il layout.
Cimmanon

4
Non è carino, ma lo sviluppo del front-end è l'arte del possibile; il pragmatismo è una premessa di base. Credo che la parola estrema è fuori luogo, dal momento che gli elementi aggiuntivi vengono utilizzati per lo styling sul 99,9% dei siti web del mondo reale (elementi cfr container Bootstrap).
Dalgard

12

Una possibile soluzione consiste nell'utilizzare justify-content: flex-start;sul .gridcontenitore, le restrizioni di dimensione sui relativi elementi figlio e i margini sugli elementi figlio appropriati , a seconda del numero desiderato di colonne.

Per una griglia a 3 colonne, il CSS di base sarebbe simile al seguente:

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.grid > * {
    flex: 0 0 32%;
    margin: 1% 0;
}

.grid > :nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
}

È un'altra soluzione imperfetta, ma funziona.

http://codepen.io/tuxsudo/pen/VYERQJ


11

So che ci sono molte risposte qui ma .. Il modo più semplice per farlo è con un gridinvece di flexe grid template columnscon repeate auto fills, dove devi impostare il numero di pixel che hai dato a ciascun elemento, 100pxdal tuo codice frammento.

.exposegrid {
     display: grid;
     grid-template-columns: repeat(auto-fill, 100px);
     justify-content: space-between;
}
 .exposetab {
     width: 100px;
     height: 66px;
     background-color: rgba(255, 255, 255, 0.2);
     border: 1px solid rgba(0, 0, 0, 0.4);
     border-radius: 5px;
     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
     margin-bottom: 10px;
}
<div class="exposegrid">
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
</div>


2
Questa è la soluzione corretta per allineare gli elementi dell'ultima riga a sinistra.
a.barbieri,

Sono d'accordo, il modo corretto è usare la griglia. Può essere realizzato con flexbox ma molto più pulito per usare la griglia.
nbarth,

6

Sì.! Possiamo ma con alcune query multimediali e il numero massimo di colonne è predefinito .

Qui sto usando 4 colonne. Controlla il mio codice:

.container {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
  -moz-flex-flow: row wrap;
}

.container .item {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  justify-content: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  flex-basis: 25%; //max no of columns in %, 25% = 4 Columns
}

.container .item .item-child {
  width: 130px;
  height: 180px;
  background: red;
  margin: 10px;
}

@media (max-width: 360px) {
  .container .item {
    flex-basis: 100%;
  }
}

@media (min-width:360px) and (max-width: 520px) {
  .container .item {
    flex-basis: 50%;
  }
}

@media (min-width:520px) and (max-width: 680px) {
  .container .item {
    flex-basis: 33.33%;
  }
}
<div class="container">

  <div class="item">
    <div class="item-child">1</div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>

</div>

NOTA
1) Non è necessario creare div bambini. Può essere qualsiasi altro tag come 'img' r quello che vuoi ..
2) Se vuoi più colonne regola le media query e il numero massimo di colonne.


Questo crea solo 3 nell'ultimo IE
Akxe il

6

Se desideri una griglia con dello spazio tra gli elementi e gli elementi che iniziano senza uno spazio iniziale, questa semplice soluzione funziona:

.grid {
    display: flex;
    flex-flow: row wrap;
    margin: 0 -5px; // remove the inital 5px space
    width: auto;
}
.grid__item {
    width: 25%;
    padding: 0 5px; // should be same as the negative margin above.
}

Se vuoi lo spazio iniziale di 5px, rimuovi semplicemente il margine negativo :) Semplice.

https://jsfiddle.net/b97ewrno/2/

La risposta accettata, sebbene buona, fa sì che non ci sia spazio tra gli elementi nella seconda riga.


1
Sorpreso, questo non ha più voti positivi. Questo è un bellissimo approccio che appartiene al museo Flex.
Eduardo La Hoz Miranda,

1
@EduardoLaHozMiranda grazie! Ma perché "museo"? Internet Explorer 11 non supporta la griglia CSS e la maggior parte dei siti deve ancora supportarlo. + Alcuni timer importanti nello sviluppo di frontend sostengono che esistono diversi casi d'uso per grid e flexbox. Ma forse intendevi solo che questa dovrebbe essere una parte importante della storia del web: D
OZZIE il

1
Lol, si. Ero eccitato in quel momento. Volevo solo dire che era un ottimo e minimale approccio a questo problema.
Eduardo La Hoz Miranda,

@dencey non hai bisogno di sapere che per questa soluzione, è il 25%, quindi un massimo di 4 per riga, ma puoi usare qualunque percentuale tu voglia
OZZIE

@OZZIE Intendo che la larghezza dell'elemento è fissa (come 100px), ma la larghezza del contenitore è dinamica, quindi gli elementi per riga sono dinamici.
Dencey

4

Se si desidera allineare l'ultimo elemento alla griglia, utilizzare il seguente codice:

Grid container

.card-grid {
  box-sizing: border-box;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  justify-content: space-between;
  align-items: stretch;
  align-content: stretch;
  -webkit-box-align: stretch;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
}

.card-grid:after {
  content: "";
  flex: 1 1 100%;
  max-width: 32%;
}

Articolo nella griglia

.card {
  flex: 1 1 100%;
  box-sizing: border-box;
  -webkit-box-flex: 1;
  max-width: 32%;
  display: block;
  position: relative;

}

Il trucco è impostare la larghezza massima dell'articolo uguale alla larghezza massima della griglia .card: after.

Demo live su Codepen


cthulu benedice te e il tuo computer
L422Y

3
Questo approccio non funziona quando la dimensione della carta è fissa e il numero di carte in ogni riga è sconosciuto. codepen.io/zendu/pen/WXNGvo
zendu

3

È possibile utilizzare "flex-start" e aggiungere manualmente i margini. Richiede un po 'di hacking matematico, ma è sicuramente facile da fare e lo rende facile da usare con un preprocessore CSS come LESS.

Vedi ad esempio questo MENO mixin:

.flexboxGridMixin(@columnNumber,@spacingPercent) {
  @contentPercent: 100% - @spacingPercent;
  @sideMargin: @spacingPercent/(@columnNumber*2);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  > * {
    box-sizing: border-box;
    width: @contentPercent/@columnNumber;
    margin-left: @sideMargin;
    margin-right: @sideMargin;
  }
}

E quindi può essere facilmente utilizzato per visualizzare un layout di griglia reattivo:

ul {
  list-style: none;
  padding: 0;
  @spacing: 10%;
  @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
  @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
  @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
  @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
  @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
}

li {
  background: pink;
  height: 100px;
  margin-top: 20px;
}

Ecco un esempio di

http://codepen.io/anon/pen/YyLqVB?editors=110


Non usi mai @contentPercent. Hai intenzione di farlo?
Neverfox,

larghezza: @ contentPercent / @ columnNumber;
realtebo,

WOW ! Sono davvero colpito da questa soluzione. Proverò ad adattarmi alla mia situazione
realtebo il

3

Questo problema è stato risolto per me utilizzando la griglia CSS,

Questa soluzione è applicabile solo se si dispone di un numero fisso di colonne, cioè no. di elementi da visualizzare in una singola riga

-> utilizzando la griglia ma non specificando il numero di righe, poiché il numero di elementi aumenta si avvolge in colonne e aggiunge righe in modo dinamico, in questo esempio ho specificato tre colonne

-> non devi dare alcuna posizione al tuo bambino / cellule, in quanto lo risolverà, cosa che non vogliamo.

.grid-class{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 80px;
}


1

Questa versione è il modo migliore per blocchi con larghezza fissa:

http://codepen.io/7iomka/pen/oxxeNE

In altri casi - versione di dalgard

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
justify-content:center;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  max-width:200px;
  min-width:200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>


0

C'è un modo senza flexbox, anche se dovresti soddisfare le seguenti condizioni. 1) Il contenitore ha imbottitura. 2) Gli articoli hanno le stesse dimensioni e sai esattamente quanti ne vuoi per riga.

ul {
  padding: 0 3% 0 5%;
}
li {
  display: inline-block; 
  padding: 0 2% 2% 0;
  width: 28.66%;
}

L'imbottitura più piccola sul lato destro del contenitore consente l'imbottitura aggiuntiva a destra di ciascun elemento dell'elenco. Supponendo che altri elementi nello stesso genitore dell'oggetto elenco siano riempiti con 0 5%, sarà a filo con loro. Puoi anche adattare le percentuali al margine che desideri o utilizzare i valori di px px.

Ovviamente, puoi fare lo stesso senza l'imbottitura sul contenitore usando nth-child (IE 9+) per rimuovere il margine su ogni terza casella.


0

Usando flexbox e alcune domande sui media, ho fatto questo piccolo trucco: http://codepen.io/una/pen/yNEGjv (è un po 'confuso ma funziona):

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  max-width: 1200px;
  margin: 0 auto;
}

.item {
  background-color: gray;
  height: 300px;
  flex: 0 30%;
  margin: 10px;

  @media (max-width: 700px) {
     flex: 0 45%;
  }

  @media (max-width: 420px) {
    flex: 0 100%;
  }

  &:nth-child(3n-1) {
    margin-left: 10px;
    margin-right: 10px;
  }
}

0

Ho fatto un mix SCSS per questo.

@mixin last-row-flexbox($num-columns, $width-items){

  $filled-space: $width-items * $num-columns;
  $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1));

  $num-cols-1 : $num-columns - 1;

  &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & {
    margin-left: $margin;
  }
  @for $i from 1 through $num-columns - 2 { 
    $index: $num-columns - $i;
    &:nth-child(#{$num-columns}n+#{$index}):last-child{
      margin-right: auto;
    }
  }
}

Questo è il link codepen: http://codepen.io/diana_aceves/pen/KVGNZg

Devi solo impostare la larghezza degli elementi in percentuale e numero di colonne.

Spero che ciò possa aiutarti.


0

Ecco un'altra coppia di mixs scss.

Questi mixin presumono che non userete plugin js come Isotope (non rispettano l'ordine di markup html, confondendo così le regole css nth).

Inoltre, sarai in grado di trarne il massimo vantaggio soprattutto se stai scrivendo i tuoi breakpoint reattivi in ​​un primo modo mobile. Idealmente userete flexbox_grid () sul breakpoint più piccolo e flexbox_cell () sui breakpoint seguenti. flexbox_cell () si occuperà di ripristinare i margini precedentemente impostati non più utilizzati su punti di interruzione più grandi.

Inoltre, purché tu abbia impostato correttamente le proprietà flex del tuo contenitore, puoi anche usare solo flexbox_cell () sugli oggetti, se necessario.

Ecco il codice:

// apply to the container (for ex. <UL> element)
@mixin flexbox_grid($columns, $gutter_width){

  display: flex;
  flex-direction:row;
  flex-wrap:wrap;
  justify-content: flex-start;

  > *{
    @include flexbox_cell($columns, $gutter_width);
  }
}

// apply to the cell (for ex. a <LI> element)
@mixin flexbox_cell($columns, $gutter_width){
  $base_width: 100 / $columns;
  $gutters: $columns - 1;
  $gutter_offset: $gutter_width * $gutters / $columns;

  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: auto; // IE10 doesn't support calc() here

  box-sizing:border-box; // so you can freely apply borders/paddings to items
  width: calc( #{$base_width}% - #{$gutter_offset} );

  // remove useless margins (for cascading breakponts)
  &:nth-child(#{$columns}n){
    margin-right: 0;
  }

  // apply margin
  @for $i from 0 through ($gutters){
    @if($i != 0){
      &:nth-child(#{$columns}n+#{$i}){
        margin-right: $gutter_width;
      }
    }
  }
}

Uso:

ul{
   // just this:
   @include flexbox_grid(3,20px);
}

// and maybe in following breakpoints, 
// where the container is already setted up, 
// just change only the cells:

li{
   @include flexbox_cell(4,40px);
}

Ovviamente, spetta a te infine impostare il riempimento / margine / larghezza del contenitore e i margini inferiori della cella e simili.

Spero che sia d'aiuto!


0

Questo è piuttosto confuso, ma funziona per me. Stavo cercando di ottenere spazi / margini coerenti.

.grid {
  width: 1024px;
  display: flex;
  flex-flow: row wrap;
  padding: 32px;
  background-color: #ddd;  

  &:after {
    content: "";
    flex: auto;
    margin-left:-1%;
  }

  .item {
    flex: 1 0 24.25%;
    max-width: 24.25%;
    margin-bottom: 10px;
    text-align: center;
    background-color: #bbb;

    &:nth-child(4n+2),
    &:nth-child(4n+3),
    &:nth-child(4n+4) {
      margin-left: 1%;
    }

    &:nth-child(4n+1):nth-last-child(-n+4),
      &:nth-child(4n+1):nth-last-child(-n+4) ~ .item {
        margin-bottom: 0;
    }    

  }
}

http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/


0

Sembra che nessuno abbia proposto la soluzione flex-grow sull'ultimo elemento. L'idea è di avere il tuo ultimo oggetto flex per occupare tutto il posto che può usare flex-grow: 1.

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid > *:last-child {
  flex-grow: 1;
}

Nota: questa soluzione non è perfetta, specialmente se hai elementi centrati all'interno dei tuoi oggetti flessibili poiché si centrerà sull'ultimo oggetto flessibile possibilmente enorme.


0

Questa è una combinazione di molte risposte, ma fa esattamente ciò di cui avevo bisogno, ovvero allineare l'ultimo figlio in un contenitore flessibile a sinistra mantenendo il comportamento spazio-tra (in questo caso è a tre colonne disposizione).

Ecco il markup:

.flex-container {
  display: flex;
  justify-content: space-between;
  flex-direction: row;
}

.flex-container:after {
  content: "";
  flex-basis: 30%;
}

1
Per essere più generico: la dimensione della base flessibile deve essere uguale alla dimensione dei bambini.
Christian Toffolo,

1
Ho trovato flex-grow: 0.9invece di flex-basisfunzionare per qualsiasi numero di colonne. Testato su un sacco di browser moderni - funziona in tutti ma il riempimento è rotto in IE (ma funziona in Edge0
Patabugen,

0

assumendo:

  • Volete un layout a griglia a 4 colonne con avvolgimento
  • Il numero di articoli non è necessariamente un multiplo di 4

Imposta un margine sinistro su ogni elemento tranne 1, 5 e 9 e così via. Se il margine sinistro è 10px, ogni riga avrà un margine di 30px distribuito tra 4 elementi. La larghezza percentuale per l'articolo viene calcolata come segue:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

Questa è una soluzione decente per problemi che riguardano l'ultima fila di flexbox.

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0 3em;
  background-color: peachpuff;
}

.item {
  margin-left: 10px;
  border: 1px solid;
  padding: 10px;
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
  background-color: papayawhip;
}

.item:nth-child(4n + 1) {
  margin-left: 0;
}

.item:nth-child(n + 5) {
  margin-top: 10px;
}
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>


0

Se conosci la larghezza degli spazi tra gli elementi nella riga e la quantità di elementi in una riga, questo funzionerebbe:

Esempio: 3 elementi di fila, 10px di spazio tra gli elementi

div:last-child:nth-child(3n+2) {
  flex-grow: 1
  margin-left: 10px
}

0

Usa semplicemente il trucco Jquery / Javascript per aggiungere un div vuoto:

if($('.exposegrid').length%3==2){
 $(".exposegrid").append('<div class="exposetab"></div>');
}

-1

Oh ragazzo, penso di aver trovato una buona soluzione con CSS minimo e senza JS. Controlla:

img {width:100%;}
li {
  display: inline-block;
  width:8em;
  list-style:none;
}
ul {text-align: justify;}
<ul>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

La chiave qui è ricordare che ciò che stiamo cercando di ottenere è esattamente cosa text-align: justify fa!

Gli elementi vuoti nell'HTML sono lì per rendere perfettamente visibile l'ultima riga senza cambiare l'aspetto, ma potrebbe non essere necessario dato ciò che stai cercando di ottenere. Per un equilibrio perfetto in ogni situazione, sono necessari almeno x-4 elementi vuoti, x è il numero di elementi da visualizzare o n-2, n il numero di colonne che si desidera visualizzare.


-1

Aggiungi solo alcuni elementi falsi con le stesse proprietà, tranne per l'altezza impostata su 0 px alla fine.


L'aggiunta di articoli falsi è una cattiva pratica in ogni singolo modo. Non dovresti riempire il DOM con roba solo per hackerare css a meno che non sia obbligatorio. Per molte ragioni, dall'accessibilità, all'inondazione della base di codice con cose strane, a rendere la logica più complessa da capire e l'elenco continua. Non raccomandare gli hack a meno che tu non dica esplicitamente che potrebbe essere una cattiva soluzione o c'è un caso speciale per quello.
Eksapsy

-4

vuoi allineare

usare align-content: flex-start;invece dijustify-content: space-between;

questo tira gli oggetti nell'ultima riga a sinistra e distribuisce lo spazio in modo uniforme,

.container {
  display: flex;
  flex-flow: row wrap;
  align-content: flex-start;
  /*justify-content: space-between; remove this line!!!! */ 
}

https://codepen.io/anon/pen/aQggBW?editors=1100


La soluzione di DanAnderson NON È DINAMICA .PERİOD !!

quando la larghezza dell'elemento è cambiata da 25 a 28 dan anderson non riesce a spaziare tra le immagini

danAnderson: https://codepen.io/anon/pen/ZwYPmB?editors=1100

dinamico: https://codepen.io/anon/pen/aQggBW?editors=1100

questo è quello che stavo cercando di dire. dans è hacky .....


-7

Sono stato in grado di farlo con justify-content: space-betweensul contenitore

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.