Flex-Box: Richten Sie die letzte Zeile am Raster aus

378

Ich habe ein einfaches Flex-Box-Layout mit einem Container wie:

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

Jetzt möchte ich, dass die Elemente in der letzten Zeile mit den anderen ausgerichtet werden. justify-content: space-between;sollte verwendet werden, da die Breite und Höhe des Gitters angepasst werden kann.

Derzeit sieht es so aus

Das Element unten rechts sollte sich in der Mitte befinden

Hier möchte ich, dass sich das Element unten rechts in der "mittleren Spalte" befindet. Was ist der einfachste Weg, dies zu erreichen? Hier ist eine kleine jsfiddle , die dieses Verhalten zeigt.

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

Thorben Croisé
quelle
Überprüfen Sie meine Lösung hier Ich denke, es funktioniert gut ohne Hack, nur Mathe: stackoverflow.com/questions/18744164/…
Sebastien Lorber
5
Alternativ könnte das neuere CSS-Grid-Modul verwendet werden - das dieses Problem nicht hat
Danield
1
Ich habe eine generische JS-Lösung für Fälle hinzugefügt, in denen die Breite des untergeordneten Elements variabel ist, wobei die Anzahl der Elemente in der Zeile ebenfalls variabel ist.
Tao

Antworten:

416

Fügen Sie ein hinzu, ::afterdas den Raum automatisch ausfüllt. Sie müssen Ihr HTML nicht verschmutzen. Hier ist ein Codepen, der dies zeigt: http://codepen.io/DanAndreasson/pen/ZQXLXj

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

.grid::after {
  content: "";
  flex: auto;
}
Dan Andreasson
quelle
17
Wäre es möglich, es irgendwie mit Space-Around zum Laufen zu bringen?
Tom
61
@DanAndreasson Es gibt zwei Probleme, es beginnt nicht von links (wie Leerzeichen dazwischen), und auch der Abstand zwischen den Elementen der letzten Zeile unterscheidet sich von dem in der vorherigen Zeile (Simulation einiger Elemente mit fester Breite in "beliebiger Größe"). Gitter - bezieht sich auf beide) ... codepen.io/anon/pen/gPoYZE Ich wollte die "Strategie" (Leerzeichen oder Leerzeichen dazwischen) beibehalten, aber wie in den vorherigen Zeilen von links beginnen ... I. wollte wissen, ob es möglich ist, Ihre erstaunliche Lösung zu verallgemeinern.
Tom
44
Dies funktioniert nur , weil die Elemente Raum haben padding sie und die kombinierten Prozentbreiten gleich 100% für jeden Satz von 4. In dieser codepen ich entfernt justify-content: space-between;von .gridund entfernt .grid:afterund es funktioniert gleich. Nun , wenn Sie etwas versucht , das wie es total bricht. Beachten Sie, dass die Breiten für jeden 4er-Satz nicht 100% ergeben. In der Geige des OP werden die Breiten in px eingestellt, sodass Ihre Lösung in dieser Situation nicht funktioniert .
Jacob Alvarez
22
Beim Versuch dieser Lösung wurden die Elemente, die in der letzten Zeile kurz waren, anfangs nicht richtig verteilt space-between. Wenn jedoch ich das flex-basisder .grid:afterauf die gleiche Dimensionierung wie die anderen Elemente in dem Gitter (pro-Haltepunkt, das Überschreiben den oben default / Basismodul - Code), die letzte Reihe ausgebreitete korrekt. Scheint auf Safari, iOS, Firefox, Chrome zu funktionieren (IE muss getestet werden) und meine größte Zeilengröße ist 3 bei meiner ersten Implementierung.
Webbower
8
Für meine Anforderungen funktionierte dies mit der folgenden Änderung: { content: "";flex: 0 0 32%;max-width: 480px;}und ich habe die maximale Breite mit Änderungen an Medienabfragen geändert, sodass das Raster bei allen Breiten perfekt war.
Colin Wiseman
160

Eine Technik wäre das Einfügen einer Anzahl zusätzlicher Elemente (so viele wie die maximale Anzahl von Elementen, die Sie jemals in einer Reihe erwarten würden), denen eine Höhe von Null zugewiesen wird. Der Raum ist immer noch geteilt, aber überflüssige Zeilen fallen zu nichts zusammen:

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 Zukunft kann dies durch die Verwendung mehrerer erreicht werden ::after(n).

Dalgard
quelle
11
Leider kontaminiert dies das Markup auf nicht-semantische Weise, aber es funktioniert völlig. : SI wünschte, ich wüsste einen anderen Weg, um dieses Verhalten zu replizieren, Flexbox oder auf andere Weise, der keine nicht-semantischen Elemente erfordert.
Ryan Norbauer
33
Einverstanden, es ist schmutzig, aber es funktioniert und ist weniger hackig als viele Hacks. Feck es, ich benutze es, bis :: after (12) Unterstützung erhält, oder sie fügen einige zusätzliche Rechtfertigungsoptionen hinzu. Es ist eine echte Schande, denn die Art und Weise, wie Flexbox Rechtfertigung im Moment funktioniert, ist einfach falsch! Wenn Sie einen Textabschnitt begründen würden, würden Sie niemals versuchen, die letzte Zeile zu rechtfertigen. Sollte definitiv eine Option gewesen sein, ich kann nicht glauben, dass sie dies verpasst haben.
Codemonkey
4
Ich habe eine reine CSS-Lösung entwickelt. Die Einschränkung besteht darin, dass immer nur zwei fehlende Elemente berücksichtigt werden können. Daher funktioniert dies nur in einem flexiblen Raster mit maximal drei Elementen pro Umbruchreihe sicher. Demo: codepen.io/lukejacksonn/pen/dozqVq Das Prinzip besteht darin, Pseudoelemente als zusätzliche untergeordnete Elemente zu verwenden und ihnen die gleiche Flex-Eigenschaft wie die Elemente im Container zu geben.
Lukejacksonn
8
@ Codemonkey Jesus. Ich habe erst angefangen, Flexbox zu verwenden und darüber nachgedacht, wie ich all diese Hacks loswerden kann, um diese Inline-Blöcke innerhalb eines Gitters auszurichten, und jetzt stellt sich heraus, dass dies einfach nicht möglich ist! Ich habe diesen Block sofort erreicht und die Grenzen erreicht, von denen ich dachte, dass ich sie kaum jemals glücklich erreichen würde, um all diese alten unlösbaren CSS-Probleme zu lösen. Nicht so schnell, denke ich. Es hat nur 20 Jahre gedauert, bis die richtige vertikale Zentrierung erreicht war - wir können es kaum erwarten. Jesus, es scheint so einfach Aufgabe ...
Andrey
3
@dalgard Ich glaube nicht. Siehe meinen Kommentar .
Jacob Alvarez
109

Wie bereits auf anderen Postern erwähnt, gibt es keine saubere Möglichkeit, die letzte Reihe links an der Flexbox auszurichten (zumindest gemäß der aktuellen Spezifikation).

Für das, was es wert ist: Mit dem CSS-Grid-Layout-Modul ist dies überraschend einfach zu erstellen:

Grundsätzlich läuft der relevante Code darauf hinaus:

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

1) Machen Sie das Containerelement zu einem Gittercontainer

2) Stellen Sie das Raster mit automatischen Spalten mit einer Breite von 100 Pixel ein. (Beachten Sie die Verwendung der automatischen Füllung (wie angenommen auto-fit- die (für ein 1-Zeilen-Layout) leere Spuren auf 0 reduziert -, wodurch die Elemente erweitert werden, um den verbleibenden Platz einzunehmen. Dies würde zu einem gerechtfertigten Zwischenraum führen 'Layout, wenn das Raster nur eine Zeile hat, was in unserem Fall nicht das ist, was wir wollen. (Schauen Sie sich diese Demo an, um den Unterschied zwischen ihnen zu sehen.)

3) Legen Sie Lücken / Rinnen für die Rasterzeilen und -spalten fest - da hier ein Zwischenraum-Layout gewünscht wird, ist die Lücke tatsächlich eine minimale Lücke, da sie nach Bedarf wächst.

4) Ähnlich wie bei der Flexbox.

Codepen Demo (Größe ändern, um den Effekt zu sehen)

Danield
quelle
4
Schöne Lösung. Das einzige Problem ist, dass es mit IE10 / 11 nicht funktioniert.
Zendu
1
In Bezug auto-fitauf Chrome 57-60 (und Browser, die auf der Engine basieren, wie Samsung Internet 6.0) gab es einen Fehler, da die Spezifikation zu diesem Zeitpunkt etwas mehrdeutig war. Jetzt wurde die Spezifikation geklärt und die neuen Versionen von Chrome werden auto-fitkorrekt gerendert , aber Browser mit alter Engine werden weiterhin verwendet. Seien Sie also vorsichtig mit diesem Wert.
Ilya Streltsyn
4
Angesichts der aktuellen Möglichkeiten sollte dies nun die akzeptierte Antwort sein. Die Verwendung von :afterPseudoelementen kann in Randfällen zu unerwünschten Ergebnissen führen.
Paul
2
@ Danield dieser Vorschlag hat mir sehr geholfen, danke!
Krys
4
Dies sollte die akzeptierte Antwort sein. Ich würde es im Sinne einer progressiven Verbesserung als Fallback mit Flexbox kombinieren: Browser, die das Raster nicht unterstützen, würden die Flexbox-Version anzeigen, die nah genug für mich ist.
Palantir
27

Ohne zusätzliches Markup hat das Hinzufügen ::afterfür mich funktioniert , indem ich die Breite der Spalte angegeben habe.

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

Mit dem HTML wie folgt:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>
Nicolás Arévalo
quelle
9
das ist interessant, aber nicht ganz richtig. Das Problem tritt auf, wenn Sie mit mehr als zwei Elementen in der unteren Reihe arbeiten. Der Abstand zwischen den Elementen in den oberen Reihen tritt in der letzten Reihe nie auf. Die Gegenstände sind fest zusammengepackt, wodurch der ursprüngliche Nutzen des Zwischenraums zunichte gemacht wird.
John Haugeland
noch besser, wenn Sie flex-basis: 10emanstelle von Breite verwenden.
Beytarovski
14

Das kannst du nicht. Flexbox ist kein Rastersystem. Es verfügt nicht über die Sprachkonstrukte, um das zu tun, wonach Sie fragen, zumindest nicht, wenn Sie es verwenden justify-content: space-between. Mit Flexbox können Sie am ehesten die Spaltenausrichtung verwenden, für die eine explizite Höhe festgelegt werden muss:

http://cssdeck.com/labs/pvsn6t4z (Hinweis: Präfixe nicht enthalten)

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

Es wäre jedoch einfacher, nur Spalten zu verwenden, die eine bessere Unterstützung bieten und keine bestimmte Höhe festlegen müssen:

http://cssdeck.com/labs/dwq3x6vr (Hinweis: Präfixe nicht enthalten)

ul {
  columns: 15em;
}
Cimmanon
quelle
2
Da ist ein Weg; siehe meine Antwort.
Dalgard
@dalgard, Ihre Antwort ist eine Problemumgehung, keine echte Lösung. Die Antwort von Cimmanon ist richtig.
Jonah
1
@ Jonah Ich denke, "Technik" ist eine faire Beschreibung meiner Antwort. Es hat sicherlich als Lösung für viele Menschen funktioniert, einschließlich des Fragestellers.
Dalgard
2
@dalgard Es ändert nichts an der Tatsache, dass Flexbox nicht die Sprachkonstrukte bereitstellt, um das zu tun, was gefragt wird. Darüber hinaus würde ich argumentieren, dass das Hinzufügen gefälschter Elemente eine extrem schmutzige Praxis ist, genau dort oben, wo Tabellen für das Layout verwendet werden.
Cimmanon
4
Es ist nicht schön, aber Front-End-Entwicklung ist die Kunst des Möglichen; Pragmatismus ist eine Grundvoraussetzung. Ich denke, das Wort ist extrem falsch, da auf 99,9% der realen Websites zusätzliche Elemente für das Styling verwendet werden (vgl. Bootstrap-Containerelemente).
Dalgard
12

Eine mögliche Lösung besteht darin, justify-content: flex-start;für den .gridContainer Größenbeschränkungen für seine untergeordneten Elemente und Ränder für die entsprechenden untergeordneten Elemente zu verwenden - abhängig von der gewünschten Anzahl von Spalten.

Für ein dreispaltiges Raster würde das grundlegende CSS folgendermaßen aussehen:

.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%;
}

Es ist eine andere unvollkommene Lösung, aber es funktioniert.

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

Jared
quelle
11

Ich weiß, dass es hier viele Antworten gibt, aber ... Der einfachste Weg, dies zu tun, ist mit einem gridanstelle von flexund grid template columnsmit repeatund auto fills, wobei Sie die Anzahl der Pixel festlegen müssen, die Sie jedem Element gegeben haben, 100pxaus Ihrem Snippet-Code.

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

Silberner Surfer
quelle
2
Dies ist die richtige Lösung, um die Elemente der letzten Zeile linksbündig auszurichten.
a.barbieri
Ich stimme zu, der richtige Weg ist die Verwendung von Raster. Es kann mit Flexbox erreicht werden, aber viel sauberer, Gitter zu verwenden.
nbarth
6

Ja.! Wir können aber mit einigen Medienabfragen & Maximum keine Spalten vordefiniert .

Hier verwende ich 4 Spalten. Überprüfen Sie meinen Code:

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

HINWEIS
1) Es ist nicht erforderlich, eine untergeordnete Div zu erstellen. Es kann sich um ein beliebiges anderes Tag wie "img" handeln, was auch immer Sie möchten.
2) Wenn Sie mehr Spalten wünschen, passen Sie die Medienabfragen und die maximale Anzahl von Spalten an.

Mohamed Mohaideen AH
quelle
Dies schafft nur 3 im neuesten IE
Akxe
6

Wenn Sie ein Raster mit einem gewissen Abstand zwischen den Elementen und den Elementen wünschen, der ohne anfängliches Leerzeichen beginnt, funktioniert diese einfache Lösung:

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

Wenn Sie den anfänglichen 5px-Speicherplatz möchten, entfernen Sie einfach den negativen Rand :) Einfach.

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

Die akzeptierte Antwort ist zwar gut, führt jedoch dazu, dass zwischen den Elementen in der zweiten Zeile kein Leerzeichen vorhanden ist.

OZZIE
quelle
1
Überrascht hat dies keine Stimmen mehr. Dies ist ein wunderschöner Ansatz, der in das Flex-Museum gehört.
Eduardo La Hoz Miranda
1
@EduardoLaHozMiranda danke! Aber warum "Museum"? IE11 unterstützt kein CSS-Grid und die meisten Websites müssen dies noch unterstützen. + Einige große Timer in der Frontend-Entwicklung behaupten immer noch, dass es unterschiedliche Anwendungsfälle für Grid und Flexbox gibt. Aber vielleicht haben Sie nur gemeint, dass dies ein wichtiger Teil des
Webprotokolls sein sollte
1
Lol ja. Ich war damals aufgeregt. Bedeutete nur, dass es eine großartige und minimale Lösung für dieses Problem war.
Eduardo La Hoz Miranda
@dencey Sie müssen nicht wissen, dass für diese Lösung, es 25%, also maximal 4 pro Zeile, aber Sie können verwenden, wie
viel
@OZZIE Ich meine, die Elementbreite ist fest (wie 100 Pixel), aber die Containerbreite ist dynamisch, sodass Elemente pro Zeile dynamisch sind.
Dencey
4

Wenn Sie das letzte Element am Raster ausrichten möchten, verwenden Sie den folgenden Code:

Gitterbehälter

.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%;
}

Element im Raster

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

}

Der Trick besteht darin, die maximale Breite des Elements gleich der maximalen Breite des Kartenrasters zu setzen: after.

Live-Demo auf Codepen

Frank Spin
quelle
Cthulu segnet Sie und Ihren Computer
L422Y
3
Dieser Ansatz funktioniert nicht, wenn die Kartengröße festgelegt ist und die Anzahl der Karten in jeder Zeile unbekannt ist. codepen.io/zendu/pen/WXNGvo
zendu
3

Es ist möglich, "Flex-Start" zu verwenden und die Ränder manuell hinzuzufügen. Es erfordert einige Mathe-Hacking, ist aber definitiv einfach zu machen und macht es einfach, mit einem CSS-Präprozessor wie LESS zu verwenden.

Siehe zum Beispiel dieses WENIGER 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;
  }
}

Und dann kann es einfach verwendet werden, um ein ansprechendes Rasterlayout anzuzeigen:

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;
}

Hier ist ein Beispiel von

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

Sebastien Lorber
quelle
Sie verwenden niemals @contentPercent. Wolltest du das?
Neverfox
width: @ contentPercent / @ columnNumber;
Realtebo
WOW ! Diese Lösung beeindruckt mich sehr. Ich werde versuchen, mich an meine Situation anzupassen
Realtebo
3

Dieses Problem wurde für mich mithilfe des CSS-Rasters gelöst.

Diese Lösung ist nur anwendbar, wenn Sie eine feste Anzahl von Spalten haben, dh nein. von Elementen, die in einer einzelnen Zeile angezeigt werden sollen

-> Wenn Sie das Raster verwenden, aber nicht die Anzahl der Zeilen angeben, da die Anzahl der Elemente zunimmt, wird es in Spalten umgebrochen und Zeilen dynamisch hinzugefügt. In diesem Beispiel habe ich drei Spalten angegeben

-> Sie müssen Ihrem Kind / Ihren Zellen keine Position geben, da dies zu einer Korrektur führt, die wir nicht wollen.

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

Ashwin
quelle
1

Diese Version ist der beste Weg für Blöcke mit fester Breite:

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

In anderen Fällen - Version von 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>

Znacovean Simion
quelle
0

Es gibt einen Weg ohne Flexbox, obwohl Sie die folgenden Bedingungen erfüllen müssen. 1) Der Behälter ist gepolstert. 2) Artikel haben die gleiche Größe und Sie wissen genau, wie viele Sie pro Zeile möchten.

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

Die kleinere Polsterung auf der rechten Seite des Containers ermöglicht die zusätzliche Polsterung rechts von jedem Listenelement. Angenommen, andere Elemente im selben übergeordneten Element wie das Listenobjekt werden mit 0 bis 5% aufgefüllt, ist es bündig mit ihnen. Sie können die Prozentsätze auch an den gewünschten Spielraum anpassen oder px-Werte berechnen verwenden.

Natürlich können Sie dasselbe auch ohne Auffüllen des Containers tun, indem Sie mit dem n-ten Kind (IE 9+) den Rand jeder dritten Box entfernen.

ansorensen
quelle
0

Mit Flexbox und ein paar Medienabfragen habe ich diese kleine Problemumgehung durchgeführt : http://codepen.io/una/pen/yNEGjv (es ist ein bisschen hackig, funktioniert aber):

.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;
  }
}
Una Kravets
quelle
0

Ich habe ein SCSS-Mixin dafür gemacht.

@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;
    }
  }
}

Dies ist der Codepen-Link: http://codepen.io/diana_aceves/pen/KVGNZg

Sie müssen nur die Elementbreite in Prozent und Anzahl der Spalten festlegen.

Ich hoffe das kann dir helfen.

Diana
quelle
0

Hier sind noch ein paar scss-Mixins.

Diese Mixins setzen voraus, dass Sie keine js-Plugins wie Isotope verwenden (sie respektieren die HTML-Markup-Reihenfolge nicht und bringen daher die n-ten CSS-Regeln durcheinander).

Sie können sie auch in vollem Umfang nutzen, insbesondere wenn Sie Ihre reaktionsschnellen Haltepunkte zunächst mobil schreiben. Idealerweise verwenden Sie flexbox_grid () für den kleineren Haltepunkt und flexbox_cell () für die folgenden Haltepunkte. flexbox_cell () sorgt dafür, dass zuvor festgelegte Ränder zurückgesetzt werden, die bei größeren Haltepunkten nicht mehr verwendet werden.

Übrigens, solange Sie die Flex-Eigenschaften Ihres Containers korrekt eingerichtet haben, können Sie bei Bedarf auch nur flexbox_cell () für die Elemente verwenden.

Hier ist der Code:

// 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;
      }
    }
  }
}

Verwendungszweck:

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);
}

Natürlich liegt es an Ihnen, die Polsterung / den Rand / die Breite des Containers und die unteren Ränder der Zelle und dergleichen festzulegen.

Ich hoffe es hilft!

Luca Reghellin
quelle
0

Das ist ziemlich hackig, aber es funktioniert bei mir. Ich habe versucht, konsistente Abstände / Ränder zu erzielen.

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

RustyDev
quelle
0

Es scheint, als hätte niemand die Flex-Grow-Lösung für den letzten Punkt vorgeschlagen. Die Idee ist, dass Ihr letzter Flex-Gegenstand mit flex-grow so viel Platz wie möglich einnimmt: 1.

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

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

Hinweis: Diese Lösung ist nicht perfekt, insbesondere wenn Sie Elemente in Ihren Flex-Elementen zentriert haben, da sie sich auf das möglicherweise große letzte Flex-Element konzentrieren.

Dionys
quelle
0

Dies ist eine Kombination aus vielen Antworten, aber es macht genau das, was ich brauchte - das heißt, das letzte Kind in einem Flex-Container links auszurichten und dabei das Zwischenraumverhalten beizubehalten (in diesem Fall ist es dreispaltig) Layout).

Hier ist das Markup:

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

.flex-container:after {
  content: "";
  flex-basis: 30%;
}
Margaret
quelle
1
Um allgemeiner zu sein: Die Größe der Flex-Basis muss der Größe der Kinder entsprechen.
Christian Toffolo
1
Ich habe flex-grow: 0.9statt flex-basisWerke für beliebig viele Spalten gefunden. Getestet in einer Reihe moderner Browser - es funktioniert in allen, aber die Auffüllung ist im IE defekt (funktioniert aber in Edge0
Patabugen
0

Angenommen:

  • Sie möchten ein 4-Spalten-Raster mit Umbruch
  • Die Anzahl der Elemente ist nicht unbedingt ein Vielfaches von 4

Stellen Sie einen linken Rand für jedes Element außer dem 1., 5. und 9. Element usw. ein. Wenn der linke Rand 10 Pixel beträgt, hat jede Zeile einen Rand von 30 Pixel, der auf 4 Elemente verteilt ist. Die prozentuale Breite für den Artikel wird wie folgt berechnet:

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

Dies ist eine anständige Problemumgehung für Probleme mit der letzten Reihe der 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>

Salman A.
quelle
0

Wenn Sie die Breite der Leerzeichen zwischen Elementen in der Zeile und die Anzahl der Elemente in einer Zeile kennen, funktioniert dies wie folgt:

Beispiel: 3 Elemente in einer Reihe, 10 Pixel Abstand zwischen den Elementen

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

Verwenden Sie einfach den Jquery / Javascript-Trick, um ein leeres div hinzuzufügen:

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

Oh Mann, ich denke, ich habe eine gute Lösung mit minimalem CSS und ohne JS gefunden. Hör zu:

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>

Der Schlüssel hier ist, sich daran zu erinnern, dass das, was wir erreichen wollen, genau das ist, was wir tun text-align: justify!

Die leeren Elemente im HTML-Code dienen dazu, die letzte Zeile perfekt anzuzeigen, ohne das Erscheinungsbild zu ändern. Sie werden jedoch möglicherweise nicht benötigt, wenn Sie das erreichen möchten. Für eine perfekte Balance in jeder Situation benötigen Sie mindestens x-4 leere Elemente, wobei x die Anzahl der anzuzeigenden Elemente oder n-2 die Anzahl der anzuzeigenden Spalten ist.

Sharcoux
quelle
-1

Fügen Sie einfach einige gefälschte Elemente mit denselben Eigenschaften hinzu, mit Ausnahme der Höhe, die bis zum Ende auf 0 Pixel eingestellt ist.

Erik Parso
quelle
Das Hinzufügen von gefälschten Gegenständen ist in jeder Hinsicht eine schlechte Praxis. Du sollst das DOM nicht mit Sachen füllen, nur um CSS zu hacken, es sei denn, es ist obligatorisch. Aus vielen Gründen, von der Barrierefreiheit über das Überfluten der Codebasis mit seltsamen Dingen bis hin zum komplexeren Verstehen und Auflisten der Logik. Empfehlen Sie keine Hacks, es sei denn, Sie sagen ausdrücklich, dass dies eine schlechte Lösung sein könnte oder dass es dafür einen Sonderfall gibt.
Eksapsy
-4

Sie möchten ausrichten

verwenden align-content: flex-start;stattjustify-content: space-between;

Dadurch werden die Elemente in der letzten Zeile nach links gezogen und der Platz gleichmäßig verteilt.

.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


danAnderson-Lösung ist NICHT DYNAMISCH .PERİOD !!

Wenn die Artikelbreite von 25 auf 28 geändert wurde, versagt dan anderson zwischen den Bildern

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

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

Das habe ich versucht zu sagen. dans ist hacky .....

bh_earth0
quelle
-7

Ich konnte es justify-content: space-betweenauf dem Container machen

chovy
quelle