Das Folgende ist ein Gastbeitrag von Manuel Matuzovic. Er veranschaulicht, wie flex-grow funktioniert, mit all seinen seltsamen Eigenheiten. Dann geht er auf verschiedene Beispiele ein, wie gängige Layoutmuster mit flex-grow und flex-basis implementiert werden können.
Als ich von flex-grow erfuhr, erstellte ich ein einfaches Demo, um herauszufinden, was es tat und wie es funktionierte.
Ich dachte, ich hätte alles verstanden, aber als ich es auf einer Website ausprobierte, die ein Kollege kürzlich erstellt hatte, funktionierte nichts wie erwartet. Egal was wir taten, das Layout sah nicht so aus und funktionierte nicht wie in meinem Demo. Das brachte mich zum Nachdenken und ich begann zu zweifeln, ob ich wusste, worum es bei flex-grow ging.
Wie flex-grow nicht funktioniert
Bevor wir uns eingehend mit der Funktionalität von flex-grow beschäftigen, möchte ich Ihnen erklären, was ich anfangs falsch verstanden habe.
Ich dachte, alle Flex-Items mit flex-grow auf 1 gesetzt hätten die gleiche Breite. Wenn eines der Elemente flex-grow auf 2 gesetzt hätte, wäre dieses Element doppelt so groß wie alle anderen.
Das klingt gut. Es scheint, als ob das genau das ist, was in dem Pen, den ich erwähnt habe, passiert. Das Elternelement ist 900 Pixel breit, der Abschnitt mit flex-grow: 2 hat eine berechnete Breite von 600 Pixeln und das Aside-Element mit flex-grow: 1 hat eine berechnete Breite von 300 Pixeln.
Wie Sie sehen können, funktioniert alles perfekt in diesem Demo, aber es funktionierte überhaupt nicht in einem realen Beispiel, obwohl wir genau die gleiche CSS verwendet haben. Wie sich herausstellt, war das Problem nicht die CSS, sondern der Inhalt (oder der Mangel an Inhalt). Das von mir erstellte Demo funktioniert, weil ich durch die Verwendung von nur zwei leeren Elementen einen Testfall erstellt habe, der zu einfach war, um die wichtigen Besonderheiten der Eigenschaft darzustellen.
Wie flex-grow wirklich funktioniert
Ich habe gerade beschrieben, wie flex-grow nicht funktioniert, aber ich habe Ihnen ein Demo gezeigt, das tatsächlich tut, was ich behaupte, dass es nicht tut (Später in diesem Artikel werde ich den Grund dafür erklären).
Um die Dinge zu klären, lassen Sie mich Ihnen einen weiteren Pen zeigen. Wir haben genau die gleiche Einrichtung wie im ersten Pen, aber diesmal sind die Abschnitts- und Aside-Elemente nicht leer. Jetzt ist das Verhältnis nicht mehr 2:1 und das Element mit flex-grow auf 1 ist tatsächlich größer als das Element mit flex-grow auf 2.
Erklärung
Wenn wir display: flex; auf das Elternelement anwenden und nichts weiter ändern, werden die Kindelemente horizontal gestapelt, egal was passiert. Wenn nicht genug Platz vorhanden ist, schrumpfen sie. Wenn andererseits mehr als genug Platz vorhanden ist, wachsen sie nicht, weil Flexbox von uns möchte, dass wir definieren, wie viel sie wachsen sollen. Anstatt dem Browser mitzuteilen, wie breit ein Element sein soll, bestimmt flex-grow, wie der verbleibende Platz unter den Flex-Items verteilt wird und wie groß der Anteil ist, den jedes Item erhält.
Oder anders ausgedrückt
Ein Flex-Container verteilt freien Platz proportional zu seinen Flex-Grow-Faktoren an seine Items, um die Container zu füllen, oder schrumpft sie proportional zu ihren Flex-Shrink-Faktoren, um Überläufe zu verhindern.
https://drafts.csswg.org/css-flexbox/#flexibility
Demonstration
Das Konzept ist viel einfacher zu verstehen, wenn wir es visualisieren.
Zuerst setzen wir die display-Eigenschaft unseres Elternelements auf flex und dadurch werden unsere Kindelemente zu Flex-Items und werden horizontal nebeneinander positioniert.

Als Nächstes entscheiden wir, wie viele Anteile des zusätzlichen Platzes jedes Element erhält. In unserem vorherigen Beispiel erhält das erste Element 2/3 des verbleibenden Platzes (flex-grow: 2) und das zweite Element 1/3 (flex-grow: 1). Wenn wir wissen, wie viele flex-grow-Werte wir insgesamt haben, wissen wir, durch welche Zahl der verbleibende Platz geteilt werden muss.

Zuletzt haben wir die Anzahl der verteilbaren Stücke. Jedes Element erhält die entsprechende Anzahl von Stücken basierend auf seinem flex-grow-Wert.

Berechnung
Theorie und visuelle Darstellungen sind schön, aber lassen Sie uns ins Detail gehen und die Mathematik für das obige Beispiel durchführen.
Für unsere Berechnung benötigen wir 4 Zahlen: Die Breite des Elternelements, die Anfangsbreite unseres Abschnitts und unseres Aside-Elements und die Gesamtzahl der flex-grow-Werte, die wir verwenden werden.
Elternbreite: 900px
Abschnittsbreite: 99px
Aside-Breite: 623px
Gesamte flex-grow-Werte: 3
1. Zuerst müssen wir den verbleibenden Platz berechnen
Das ist ziemlich einfach. Wir nehmen die Breite des Elternelements und ziehen die gesamte Anfangsbreite jedes Kindelements ab.
900 - 99 - 623 = 178
Elternbreite – Anfangsbreite des Abschnitts – Anfangsbreite des Asides = Verbleibender Platz
2. Als Nächstes müssen wir bestimmen, wie viel ein flex-grow ist
Jetzt, da wir den verbleibenden Platz haben, müssen wir bestimmen, in wie viele Teile wir ihn schneiden wollen. Wichtig ist hier, dass wir den verbleibenden Platz nicht durch die Anzahl der Elemente teilen, sondern durch die Gesamtzahl der flex-grow-Werte. In unserem Fall sind das 3 (flex-grow: 2 + flex-grow: 1)
178 / 3 = 59.33
Verbleibender Platz / Gesamte flex-grow-Werte = "Ein flex-grow"
3. Schließlich wird der zerteilte verbleibende Platz zwischen allen Elementen verteilt
Basierend auf ihren flex-grow-Werten erhält der Abschnitt 2 Stücke (2 * 59,33) und der Aside 1 (1 * 59,33). Diese Zahlen werden zur Anfangsbreite jedes Elements addiert.
99 + (2 * 59.33) = 217.66 (≈218px)
Anfangsbreite des Abschnitts + (flex-grow-Wert des Abschnitts * "Ein flex-grow") = Neue Breite
und
623 + (1 * 59.33) = 682.33 (≈682px)
Anfangsbreite des Asides + (flex-grow-Wert des Asides * "Ein flex-grow") = Neue Breite
Kinderleicht, oder?
Okay, aber warum funktioniert das erste Demo?
Wir haben die Formel, nun finden wir heraus, warum wir tatsächlich die Zahlen bekommen haben, die wir in dem ersten Pen wollten, obwohl wir nicht wussten, was wir taten.
Elternbreite: 900px
Abschnittsbreite: 0px
Aside-Breite: 0px
Gesamte flex-grow-Werte: 3
1. Berechnen Sie den verbleibenden Platz
900 - 0 - 0 = 900
2. Bestimmen Sie, wie viel ein flex-grow ist
900 / 3 = 300
3. Verteilen Sie den zerteilten verbleibenden Platz
0 + (2 * 300) = 600
0 + (1 * 300) = 300
Wenn die Breite jedes Elements 0 ist, entspricht der verbleibende Platz der tatsächlichen Breite des Elternelements und daher sieht es so aus, als ob flex-grow die Breite des Elternelements in proportionale Teile teilt.
flex-grow und flex-basis
Nur eine kurze Zusammenfassung: flex-grow nimmt den verbleibenden Platz und teilt ihn durch die Gesamtmenge der flex-grow-Werte. Der resultierende Quotient wird mit dem jeweiligen flex-grow-Wert multipliziert und das Ergebnis wird zur Anfangsbreite jedes Kindelements addiert.
Aber was, wenn kein Platz mehr übrig ist oder was, wenn wir uns nicht auf die Anfangsbreite der Elemente verlassen wollen, sondern auf einen von uns gesetzten Wert? Können wir flex-grow immer noch verwenden?
Natürlich können wir das. Es gibt eine Eigenschaft namens flex-basis, die die anfängliche Größe eines Elements definiert. Wenn Sie flex-basis zusammen mit flex-grow verwenden, ändert sich die Art und Weise, wie die Breiten berechnet werden.
<‘flex-basis’>Diese Komponente setzt die Langformflex-basisund definiert die Flex-Basis: die anfängliche Hauptgröße des Flex-Items, bevor der freie Platz gemäß den Flex-Faktoren verteilt wird.
https://drafts.csswg.org/css-flexbox/#valdef-flex-flex-basis
Der große Unterschied, wenn wir flex-basis auf ein Element anwenden, ist, dass wir seine Anfangsbreite nicht mehr in unserer Berechnung verwenden, sondern den Wert seiner flex-basis-Eigenschaft.
Ich habe unser vorheriges Beispiel angepasst, indem ich flex-basis zu jedem Element hinzugefügt habe. Hier ist der Pen für Sie.
Elternbreite: 900px
Abschnittsbreite: 400px (flex-basis-Wert)
Aside-Breite: 200px (flex-basis-Wert)
Gesamte flex-grow-Werte: 3
1. Berechnen Sie den verbleibenden Platz
900 - 400 - 200 = 300
2. Bestimmen Sie, wie viel ein flex-grow ist
300 / 3 = 100
3. Verteilen Sie den zerteilten verbleibenden Platz
400 + (2 * 100) = 600
200 + (1 * 100) = 300
Nur zur Vollständigkeit: Sie müssen nicht unbedingt Pixelwerte verwenden und hoffen, dass es klappt. Prozentwerte funktionieren auch.
Arbeiten mit dem Box-Modell
Um also alles abzudecken, schauen wir uns an, was passiert, wenn wir Padding und Margin hinzufügen. Nichts Besonderes eigentlich. Im ersten Schritt der Berechnung müssen Sie nur daran denken, auch die Margins abzuziehen.
Das Einzige, was zu beachten ist, ist, dass sich flex-basis in Bezug auf box-sizing wie die width-Eigenschaft verhält. Das bedeutet, dass sich die Berechnung und die Ergebnisse ändern, wenn sich die box-sizing-Eigenschaft ändert. Wenn box-sizing auf border-box gesetzt wäre, würden Sie in Ihrer Berechnung nur mit den Werten für flex-basis und margin arbeiten, da das padding bereits in der Breite enthalten ist.
Einige nützliche Beispiele
Okay, genug der Mathematik. Lassen Sie mich Ihnen einige Beispiele geben, wie Sie flex-grow effektiv in Ihren Projekten einsetzen können.
Kein width: [ x ]% mehr
Da der verbleibende Platz automatisch verteilt wird, müssen wir uns keine Gedanken mehr über Breitenwerte machen, wenn wir möchten, dass unsere Kindelemente das Elternelement ausfüllen.
Siehe den Pen QyWEBb von Manuel Matuzoc (@matuzo) auf CodePen.
Das "Heilige Gral"-3-Spalten-Liquid-Layout mit Pixelbreiten
Das Mischen von festen und flüssigen Breiten in Spaltenlayouts ist mit Float möglich, aber es ist weder intuitiv noch einfach, noch flexibel. Natürlich ist das mit Flexbox und etwas flex-grow und flex-basis-Magie ein Kinderspiel.
Siehe den Pen jbRjMG von Manuel Matuzoc (@matuzo) auf CodePen.
Füllen des verbleibenden Platzes mit beliebigen Elementen
Wenn Sie zum Beispiel neben einem Label ein Eingabefeld haben und möchten, dass das Eingabefeld den restlichen Platz ausfüllt, benötigen Sie keine hässlichen Hacks mehr.
Siehe den Pen eJYdWV von Manuel Matuzoc (@matuzo) auf CodePen.
Weitere Beispiele finden Sie auf Philip Waltons Solved by Flexbox.
Den Spezifikationen lauschen
Laut den Spezifikationen sollten wir die flex-Kurzschreibweise anstelle von flex-grow direkt verwenden.
Autoren werden ermutigt, die Flexibilität über die
flex-Kurzschreibweise zu steuern, anstatt direkt überflex-grow, da die Kurzschreibweise nicht spezifizierte Komponenten korrekt zurücksetzt, um gängige Verwendungen zu ermöglichen.
https://drafts.csswg.org/css-flexbox/#flex-grow-property
Aber Vorsicht! Wenn Sie nur flex: 1; verwenden, werden einige der obigen Beispiele nicht mehr funktionieren, da die Werte, die für die gängigen Verwendungen festgelegt sind, nicht den Standardwerten entsprechen und somit unseren Bedürfnissen entgegenwirken.
Wenn Sie flex für unseren Anwendungsfall verwenden möchten, sollten Sie es wie folgt definieren
flex: 2 1 auto; /* (<flex-grow> | <flex-shrink> | <flex-basis>) */
Flexbox lernen
Wenn Sie mehr über Flexbox erfahren möchten, schauen Sie sich bitte diese großartigen Ressourcen an
- Ein vollständiger Leitfaden zu Flexbox von Chris Coyier
- Flexbox-Abenteuer von Chris Wright
- Flexbox Froggy von Thomas Park
- What the Flexbox? von Wes Bos
- flexboxin5
- Flexbox Tester von Mike Riethmuller
Zusammenfassung und Lektionen
Ist flex-grow seltsam? Nein, gar nicht. Wir müssen nur verstehen, wie es funktioniert und was es tut. Wenn ein Element flex-grow auf 3 gesetzt hat, bedeutet das nicht, dass es dreimal so groß ist wie ein Element mit flex-grow auf 1, sondern dass ihm dreimal mehr Pixel zu seiner Anfangsbreite hinzugefügt werden als dem anderen Element.
Ich habe meine Lektion gelernt, indem ich flex-grow mit zwei leeren Elementen getestet habe, was mir ein völlig anderes Verständnis davon vermittelt hat, was die Eigenschaft tatsächlich tut, und das führte natürlich zu falschen Schlussfolgerungen. Man sollte neue Dinge in einer möglichst realistischen Umgebung testen, um den besten Eindruck davon zu bekommen, wie sie wirklich funktionieren und sich verhalten.
Danke fürs Teilen, es ist sehr verlockend, Flex-CSS zu verwenden, aber gibt es eine Garantie, dass es in allen Browsern unterstützt wird?
Gibt es ein Ende all der Hacks ;)
Es gibt seit Jahren Unterstützung in allen modernen Browsern. Das bedeutet nicht, dass Hacks nicht mehr nötig sind, da Flexbox ziemlich fehleranfällig sein kann.
Gern geschehen! Wenn Sie Ihre Websites progressiv verbessern und Modernizr zur Feature-Erkennung verwenden, sind Sie meiner Meinung nach auf der sicheren Seite (http://caniuse.com/#search=Flexbox). Mit der aktuellen Version von Modernizr können Sie die Unterstützung für die aktuelle Implementierung von Flexbox, die alte und diejenige, die keine Unterstützung für
flex-wraphat, erkennen.Danke für diesen Beitrag, Manuel!
Eine weitere fantastische Möglichkeit, alles über Flexbox zu lernen, ist das eBook von Landon Schopp, Unraveling Flexbox.
Gern geschehen! Danke, es sieht vielversprechend aus, ich werde es mir ansehen.
Toller Beitrag, danke!
Danke, ich weiß es zu schätzen!
Hallo,
Schön erklärter Artikel,
Etwas, das Sie vielleicht korrigieren möchten, ist, dass Sie einen ähnlichen Fehler wie ursprünglich in Ihrem "Heiliger Gral"-Layout gemacht haben (zum zweiten Mal, dass CSS Tricks das falsch gemacht hat ;)), indem Sie nicht genug Inhalt in Ihr Abschnittselement eingefügt haben, um den vollen Effekt zu sehen.
Sie werden feststellen, dass Ihre 150-Pixel-Aside-Spalten nicht 150 Pixel bleiben, sondern sich zusammenschieben, wenn die mittlere Spalte mehr Inhalt hat. Sie müssen
flex-shrinkauf null setzen.”’aside {
flex-basis: 150px;
flex-shrink:0;
}
”’
Ansonsten gute Arbeit.
Da haben Sie mich erwischt ;) Danke für Ihr Feedback! Ich habe den Pen aktualisiert.
Hallo,
Im 3-Spalten-Liquid-Layout-Beispiel, gibt es einen Unterschied zwischen der Verwendung von "flex-basis:150px" und der einfachen Verwendung von "width:150px"?
Danke und tolle Artikel übrigens ;)
Flex-basis ist immer entlang der Hauptachse des Flex-Containers anwendbar, width nur für die horizontale Achse des Elements. Sie könnten den Unterschied bei der Eigenschaft 'flex-direction: column;' sehen. http://codepen.io/anon/pen/zroYEP?editors=110
Wenn Sie "flex-basis: 0" einstellen, sollte der Inhalt nicht interessant sein, Flexbox verwendet einfach die Flex-Grow- oder Flex-Shrink-Eigenschaften, um die Breite wie in Ihrem ersten Beispiel zu berechnen.
Versuchen Sie also den folgenden Code im zweiten Beispiel mit mehr Inhalt im Aside und das Ergebnis sollte dasselbe sein wie in Beispiel 1
Hier ist das Beispiel
http://codepen.io/oliver41/pen/MKbwyd
Ja, natürlich. Es ist im Grunde die gleiche Berechnung wie in der Erklärung des ersten Beispiels (in "Okay, aber warum funktioniert das erste Demo?"), aber mit explizit gesetzter Breite. Danke, dass Sie darauf hingewiesen haben.
Wie in Ihrem Demo zu sehen ist, könnten Sie tatsächlich einfach
flex: 2undflex: 1schreiben, da die Kurzschreibweiseflex-basisauf null setzt.Nein, wir sprechen über das 2. Beispiel, wo Sie den Inhalt darin haben. Sie müssen
flex-basisauf 0px setzen, sonst ist es auf auto gesetzt und das Aside nimmt viel mehr Breite ein, wie Sie in Ihrem 2. Beispiel sehen können und wie Sie im Artikel erklärt haben.Wir berechnen hier nichts und setzen überhaupt keine Breite. Wir verwenden nur das Verhältnis der
flex-grow- undflex-shrink-Eigenschaften (auf die gleiche Weise wie Sie in Beispiel 1 und in Beispiel 2 versucht haben, indem Sie nurflex-basis: 0pxgesetzt haben, und der Inhalt spielt keine Rolle).Ja, ich verstehe, wir sprechen hier über dasselbe. ;) Ich habe die Erklärung und Sie eine mögliche Lösung bereitgestellt. Die Berechnung erklärt mein erstes Beispiel sowie Ihr Beispiel mit
flex-basis: 0;.Übrigens, da wir in diesem Beispiel auf der x-Achse arbeiten, setzen wir tatsächlich die (anfängliche) Breite mit
flex-basis.> Diese Komponente setzt die Langform
flex-basisund definiert die Flex-Basisdie anfängliche Hauptgröße des Flex-Items, bevor der freie Platz gemäß den Flex-Faktoren verteilt wird.
https://drafts.csswg.org/css-flexbox/#valdef-flex-flex-basis
Großartiger Beitrag, Mann! Wir verwenden Flexbox für einige große Apps und dieser Beitrag hat mir einige schöne Einblicke gegeben, da ich das gleiche Problem mit
flex-growhatte, aber nicht genau wusste, wie es bis jetzt funktioniert.Danke! Freut mich zu hören.
Danke! Es dauert auch bei mir lange, all diese Dinge zu verstehen.
In der Praxis sehe ich auch, dass es zwei Fälle gibt, die ich oft verwendet habe
Danke fürs Teilen!
Toller Beitrag. Danke Manuel!
Danke, Pawel!
Großartig! Gut erklärt. Das war eine große Hilfe, danke.
Danke, freut mich zu hören!
Schöner Artikel. Flex grow, shrink und basis können einen wirklich stolpern lassen, wenn man nicht vorsichtig ist. Der Schlüssel zum Verständnis von Flexbox ist das Verständnis von Achsen, Linien und wie Flex-Items sehr anpassungsfähig sind und versuchen, freien Weißraum intelligent zu nutzen. Flexbox funktioniert nicht immer so, wie man es erwartet, aber oft sind die Achsen oder der Weißraum die Ursache für die Verwirrung. Über ein Jahr nach der Verwendung von Flexbox lerne ich immer noch dazu. Artikel wie Ihre sind super hilfreich :)
Danke! Wir sind hier alle im selben Boot. Flexbox bietet so viele neue Eigenschaften und Kombinationsmöglichkeiten, dass es irgendwann ziemlich einschüchternd sein kann. Wir müssen diese neuen Eigenschaften einfach weiter verwenden und von ihnen lernen. ;)
Absolut brillante Erklärung!
Ich habe in letzter Zeit viel Flexbox verwendet und in dem Moment, als ich Ihr Diagramm zur Raumteilung sah, habe ich 'flex-grow' endlich verstanden.
Dieses Verständnis ermöglicht es Ihnen, es mit viel mehr Selbstvertrauen in mehr Situationen zu verwenden.
Danke für das nette Feedback. Ich bin froh, dass mein Artikel geholfen hat!