Gängige CSS-Flexbox-Layoutmuster mit Beispielcode

Theoretisch ist es ziemlich einfach, mit flexbox (Flexible Box Module) komplexe Layouts zu erstellen, aber ich habe oft festgestellt, dass ich display: flexeinem Element etwas hinzugefügt und dann eine Ewigkeit lang versucht habe, herauszufinden, wie sich etwas so verhält, wie ich es erwarte . Wenn Sie etwas wie ich sind: Hier ist eine Liste von 10 Beispiel-Flexbox-Layouts mit CSS, die Sie kopieren und einfügen können, um mit Ihren eigenen Layouts zu beginnen. Wir werden diese grundlegenden Layoutmuster durchgehen (klicken, um zu einem Beispiel zu springen):

Alles strecken
Strecke in der Mitte
Wechselndes Gitter
3x3 Gitter
3x3 (1: 1)
3x3 (16: 9)
Horizontale Balken
Vertikale Balken
Vertikaler Stapel
Mauerwerk

In jedem Beispiel wird davon ausgegangen, dass Ihr HTML-Code ein Element enthält, dessen Klasse containerdann mehrere untergeordnete Elemente enthält, die alle eine Klasse von haben item(die Anzahl der untergeordneten Elemente variiert je nach Beispiel):


 class="container">
 class="item">

Dehnen Sie alle festen Abstände

Das grundlegendste Flexbox-Muster: Ein paar Boxen müssen gestreckt werden, damit sie die gesamte Breite des übergeordneten Elements ausfüllen. Alles, was Sie tun müssen, ist display: flex, einen flex-growWert für den Container und einen Wert 0für die untergeordneten Objekte festzulegen:

.container {
  display: flex;
}

.item {
  flex-grow: 1;
  height: 100px;
}

.item + .item {
  margin-left: 2%;
}

Wir verwenden einen +Selektor, um nur Lücken zwischen Elementpaaren hinzuzufügen (im Wesentlichen überspringen wir nur den linken Rand für das erste Element in der Liste).

Durch Erhöhen flex-growwird der Platz vergrößert, den ein Element im Vergleich zu anderen Elementen beanspruchen darf. Wenn wir setzen flex-growauf 2auf dem mittleren Elemente hier, würden wir im Grunde teilen den verfügbaren Platz in 6 Stücke bis (1 Brocken für jedes Element plus 1 extra für das mittlere Element, 1 + 1 + 2 + 1 + 1). Das mittlere Element erhält zwei Chunks ( flex-grow: 2) und alle anderen Elemente einen Chunk ( flex-grow: 1).

Mittleren, festen Abstand dehnen

Ein gängiges App- und Webmuster besteht darin, eine obere Leiste zu erstellen, in der nur das mittlere Element gestreckt werden soll, das rechte und das linke Element jedoch unverändert bleiben sollen. Wenn nur ein Element gedehnt werden soll, können wir eine feste Breite (z. B. 100px) für ein Element festlegen , das statisch bleiben soll, und flex-grow: 1für das Element, das gedehnt werden soll:

.container {
  display: flex;
}

.item {
  height: 100px;
  width: 100px; /* A fixed width as the default */
}

.item-center { 
  flex-grow: 1; /* Set the middle element to grow and stretch */
}

.item + .item { 
  margin-left: 2%; 
}

Auch wenn das mittlere Element hier ein definiertes widthvon hat 100px, flex-growwird es gedehnt, um den gesamten verfügbaren Platz einzunehmen.

Alternierendes Gitter

Ein Layoutmuster, das ich in meiner ist das Erstellen eines Rasters mit einigen Variationen: Nach jeder Reihe von zwei gleich großen Elementen gibt es ein Element, das eine ganze Reihe einnimmt:

Um dies zu erreichen, müssen wir:

  1. Setzen Sie flex-wrap: wrapauf den Behälter (oder alle itemsin einer einzigen Zeile dargestellt werden würden)
  2. Eingestellt justify-content: space-betweenauf den Behälter, um nur Raum zwischen den Elementen zu erstellen (und nicht zwischen dem Rande des übergeordneten Elements und Titel)
  3. Setze jeden Gegenstand widthauf 49%(oder etwas Ähnliches, das gleich oder kleiner ist als 50%)
  4. Setzen Sie jedes dritte Element auf width, 100%damit es die gesamte Zeile ausfüllt. Wir können jeden dritten Punkt in der Liste mit dem nth-child()Selektor anvisieren .
.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.item {
  width: 48%;
  height: 100px;
  margin-bottom: 2%;
}

.item:nth-child(3n) {
  width: 100%;
}

Wenn Sie möchten, dass die erste Zeile die volle Breite hat und die beiden folgenden Elemente eine Zeile gemeinsam nutzen, können Sie nicht schreiben. .item:nth-child(1n) { width: 100% }Dies würde alle Elemente zum Ziel haben. Sie haben das erste Element zum Ziel durch jedes dritte Element auswählen und dann zwei Elemente ein Schritt zurück: .item:nth-child(3n-2) { width: 100% }.

3x3-Raster

Wir können durch das Setzen eines 3x3 Raster erstellen flex-growzu 0und flex-basis(hier geschieht mit Hilfe der für alle Kinder auf die bevorzugte Breite flexKurz Hand: flex: 0 32%). Die Ränder zwischen den Elementen sind die Reste aus jeder Zeile, dh (100% -32x3) / 2 = 2%. Ich habe den Rand ( margin-bottom: 2%) angepasst , um einen gleichmäßigen Abstand zwischen allen Elementen zu erzielen:

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

.item {
  flex: 0 32%;
  height: 100px;
  margin-bottom: 2%; /* (100-32*3)/2 */
}

Sie können den ändern flex-basis, um die Anzahl der Elemente in jeder Zeile zu erhöhen oder zu verringern. flex: 0 24%würde 4 Elemente in jede Zeile einfügen, flex: 0 19%würde 5 Elemente in jede Zeile einfügen und so weiter und so fort.

3x3-Raster, eingeschränkte Proportionen (1: 1)

Wir können ein Raster voller Elemente mit eingeschränkten Proportionen erstellen, indem wir einen etwas hackigen paddingCSS-Trick anwenden . Wenn wir %bei der Einstellung paddingfür ein Element verwenden , wird in diesem Fall paddingdas relativ zu dem übergeordneten Element des Elements festgelegt . Wir können diesen Effekt verwenden, um ein Quadrat zu erstellen, indem wir die Werte eines Elements und auf denselben Wert setzen (und das Element effektiv durch setzen ):width.containerwidthpadding-bottomheightpadding-bottom

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

.item {
  width: 32%;
  padding-bottom: 32%; /* Same as width, sets height */
  margin-bottom: 2%; /* (100-32*3)/2 */
  position: relative;
}

Da wir ein Element erstellt haben , die effektiv aus nur padding gemacht wird, und es gibt keinen Platz für den Inhalt verlassen, müssen wir Satz position: relativeauf dem .itemin diesem Beispiel und fügen Sie mit einem untergeordneten Element position: absolute, und dieses Element verwenden , um „Reset“ die Leinwand und Inhalte hinzufügen.

3x3-Raster, eingeschränkte Proportionen (16: 9)

Um die Proportionen der Objekte zu ändern, müssen Sie nur die Proportionen der widthund padding-bottomauf der ändern .item. Ändern des widthwürde die Anzahl der Elemente in jeder Reihe beeinflussen, so dass nicht die Gitterstruktur beeinflussen wir beispielsweise ändern kann , padding-bottomum 18%16 zu erzeugen: 9 (entspricht 32:18) Rechtecke.

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

.item {
  width: 32%;
  padding-bottom: 18%; /* 32:18, i.e. 16:9 */
  margin-bottom: 2%; /* (100-32*3)/2 */
}

Grafik: vertikale Balken

Wenn Sie mit flexbox eine einfache Grafikvisualisierung erstellen möchten, müssen Sie lediglich align-itemsden Container auf flex-endeinen heightfür jeden Balken festlegen und diesen definieren . flex-endDamit stellen Sie sicher, dass die Balken am unteren Rand des Diagramms verankert sind.

.container {
  display: flex;
  height: 300px;
  justify-content: space-between;
  align-items: flex-end;
}

.item { width: 14%; }
.item-1 { height: 40%; }
.item-2 { height: 50%; }
.item-3 { height: 60%; }
.item-4 { height: 20%; }
.item-5 { height: 30%; }

Grafik: horizontale Balken

Mit der gleichen Technik wie für vertikale Balken können wir einfach flex-directionden containerWert mit dem Wert hinzufügen column, um einen Satz horizontaler Balken zu erstellen. flex-directionkann den Wert row(Standard) oder haben column, wobei a rowhorizontal (→) und a columnvertikal (↓) verläuft. Sie können die Richtung von beiden auch umkehren, indem Sie row-reverse(←) bzw. column-reverse(↑) verwenden.

.container {
  display: flex;
  height: 300px;
  justify-content: space-between;
  flex-direction: column;
}

.item { height: 14%; }
.item-1 { width: 40%; }
.item-2 { width: 50%; }
.item-3 { width: 60%; }
.item-4 { width: 20%; }
.item-5 { width: 30%; }

Vertikaler Stapel (zentriert)

Um einen vertikalen Stapel zu erstellen und die Elemente von oben nach unten laufen zu lassen, müssen wir nur flex-directionden Standardwert von rowin ändern column:

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.item {
  height: 40px;
  margin-bottom: 10px;
}

Mauerwerk (oder Mosaik)

1
2
3
4
5
6
7
8
9
10

Sie haben wahrscheinlich im gesamten Internet Mauerwerk- (oder Mosaik-) Layouts gesehen, aber es ist wahrscheinlich, dass sie alle von Masonry oder einer ähnlichen JavaScript-Bibliothek betrieben wurden. Flexbox scheint ein großartiger Kandidat zu sein, dieses Layout endlich nur mit CSS zu erstellen, und es ist sicherlich möglich, aber es ist überraschend schwierig.

Eine der Hauptherausforderungen bei der Erstellung eines Mauerwerkslayouts mit Flexbox besteht darin, dass ein Element die Positionierung eines Elements über und unter flex-directiondem Container beeinflussen muss column, sodass die Elemente von oben nach unten verlaufen. Dadurch wird ein Layout erstellt, das gut aussieht und dem Mauerwerkseffekt ähnelt, für die Benutzer jedoch verwirrend sein kann. es entsteht eine unerwartete Reihenfolge der Elemente. Wenn Sie von links nach rechts lesen, werden die Elemente scheinbar gemischt und in einer scheinbar zufälligen Reihenfolge angezeigt, z. B. 1, 3, 6, 2, 4, 7, 8 usw.

Glücklicherweise können wir die orderEigenschaft verwenden, um zu ändern, in welcher Reihenfolge Elemente gerendert werden. Wir können diese Eigenschaft mit einer geschickten Verwendung des nth-child()Selektors kombinieren, um Elemente abhängig von ihrer ursprünglichen Reihenfolge dynamisch zu ordnen. Wenn wir ein Mauerwerkslayout mit drei Spalten erstellen möchten, können wir alle Elemente wie folgt in drei „Gruppen“ unterteilen:

/* Re-order items into rows */
.item:nth-child(3n+1) { order: 1; }
.item:nth-child(3n+2) { order: 2; }
.item:nth-child(3n)   { order: 3; }

/* Force new columns */
.container::before,
.container::after {
  content: "";
  flex-basis: 100%;
  width: 0;
  order: 2;
}

Dies wird das Set orderan 1für das erste Element, 4. Element, 7. Element usw. Elemente mit dem gleichen orderWert auf aufsteigende Reihenfolge bestellt werden nach dem Quellcode Ordnung oder wurde , welcher Wert gesetzt zuerst, so in diesem Beispiel wir sind Produzieren von drei so geordneten Sätzen: 1, 4, 7, 10(3n + 1) mit order: 1, 2, 5, 8(3n + 2) mit order: 2und 3, 6, 9(3n) mit order: 3. Diese drei Gruppen repräsentieren unsere drei Spalten. Zusammen wird die Reihenfolge 1, 4, 7, 10, 2, 5, 8, 3, 6, 9.

Wenn wir sicherstellen, dass jede dieser Gruppen als eine Spalte dargestellt wird (nicht mehr und nicht weniger), entsteht die Illusion, dass die Elemente in ihre ursprüngliche Reihenfolge zurückgekehrt sind, wenn Sie von links nach rechts lesen. Wenn wir das Raster visuell als Zeilen analysieren, enthält die erste Zeile das erste Element aus jeder Gruppe ( 1, 2, 3), die zweite Zeile das zweite Element aus jeder Gruppe ( 4, 5, 6) usw. Anschließend fügen wir Elemente zwischen die Spalten ein, die 100% der Höhe des übergeordneten Elements einnehmen,wodurch die Spalten zum Zeilenumbruch gezwungen werden und nicht versehentlich mit benachbarten Spalten zusammengeführt werden. Hier ist das vollständige CSS-Snippet:

.container {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 580px;
}

.item {
  width: 32%;
  margin-bottom: 2%; /* (100-32*3)/2 */
}

/* Re-order items into rows */
.item:nth-child(3n+1) { order: 1; }
.item:nth-child(3n+2) { order: 2; }
.item:nth-child(3n)   { order: 3; }

/* Force new columns */
.container::before,
.container::after {
  content: "";
  flex-basis: 100%;
  width: 0;
  order: 2;
}

Optisch wird so etwas erreicht, das dem Mauerwerkseffekt sehr nahe kommt. Wie ist die Tab-Reihenfolge beeinflusst? Zum Glück überhaupt nicht. orderÄndert nur die visuelle Darstellung von Objekten, nicht die Aktivierreihenfolge. Das Durchlaufen des Rasters funktioniert also wie vorgesehen.

Wenn Sie ein Mauerwerkslayout mit mehr als drei Spalten erstellen möchten (oder besser verstehen möchten, wie dies funktioniert), lesen Sie den entsprechenden Beitrag zum Erstellen von Mauerwerkslayouts mit CSS .