Flexbox Challenge & Limitation
Die Herausforderung besteht darin, eine Gruppe von Flex-Elementen zu zentrieren und sie beim Wickeln linksbündig auszurichten. Dies ist derzeit mit der Flexbox nicht möglich, es sei denn, es gibt eine feste Anzahl von Boxen pro Zeile und jede Box hat eine feste Breite.
Mit dem in der Frage angegebenen Code könnten wir einen neuen Flex-Container erstellen, der den aktuellen Flex-Container ( ul
) umschließt, sodass wir den ul
mit zentrieren können justify-content: center
.
Dann ul
könnten die Flex-Elemente des linksbündig ausgerichtet werden justify-content: flex-start
.
#container {
display: flex;
justify-content: center;
}
ul {
display: flex;
justify-content: flex-start;
}
Dadurch wird eine zentrierte Gruppe von linksbündigen Flex-Elementen erstellt.
Das Problem bei dieser Methode ist, dass bei bestimmten Bildschirmgrößen rechts vom eine Lücke vorhanden ist ul
, die nicht mehr zentriert erscheint.
Dies liegt daran, dass im Flex-Layout (und tatsächlich in CSS im Allgemeinen) der Container:
- weiß nicht, wann ein Element umbrochen wird;
- weiß nicht, dass ein zuvor besetzter Raum jetzt leer ist, und
- berechnet seine Breite nicht neu, um das schmalere Layout zu verkleinern.
Die maximale Länge des Leerzeichens rechts entspricht der Länge des Flex-Elements, das der Container erwartet hatte.
In der folgenden Demo können Sie durch horizontale Größenänderung des Fensters sehen, wie das Leerzeichen kommt und geht.
DEMO
Ein praktischerer Ansatz
Das gewünschte Layout kann ohne Flexbox-Verwendung inline-block
und Medienabfragen erreicht werden .
HTML
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
CSS
ul {
margin: 0 auto;
width: 1200px;
padding-left: 0;
font-size: 0;
}
li {
display: inline-block;
font-size: 18px;
list-style-type: none;
width: 150px;
height: 50px;
line-height: 50px;
margin: 15px 25px;
box-sizing: border-box;
text-align: center;
}
@media screen and (max-width: 430px) { ul { width: 200px; } }
@media screen and (min-width: 431px) and (max-width: 630px) { ul { width: 400px; } }
@media screen and (min-width: 631px) and (max-width: 830px) { ul { width:600px; } }
@media screen and (min-width: 831px) and (max-width: 1030px) { ul { width: 800px; } }
@media screen and (min-width: 1031px) and (max-width: 1230px) { ul { width: 1000px; } }
Der obige Code rendert einen horizontal zentrierten Container mit linksbündigen untergeordneten Elementen wie folgt:
DEMO
Andere Optionen
margin:0 auto
einen übergeordneten Wrapper zu verwenden, damit alles auf der Seite zentriert ist. Ab diesem Zeitpunkt führen alle untergeordneten Komponenten (dh der erste Flex-Container) nur noch den normalen Ablauf der Zeilen aus? Scheint so, als könnte dies einfach gemacht werden.Sie können es mit CSS Grid erreichen, verwenden Sie einfach
repeat(autofit, minmax(width-of-the-element, max-content))
ul { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, max-content)); grid-gap: 16px; justify-content: center; padding: initial; } li { list-style-type: none; border: 1px solid gray; padding: 5px; width: 210px; }
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> </ul>
http://jsfiddle.net/rwa20jkh/
quelle
justify-items: center
zujustify-content:center
, und jetzt ist es die Mitte perfekt.210px
Teil darin nichtminmax
. Wie mache ich das gleiche aber ohne künstliche Einschränkung von210px
? Bei Flexbox gibt es keine solche Einschränkung. Ich möchte genau das gleiche Ergebnis wie bei der Flexbox, aber der Inhaltsbereich muss wie in Ihrer Lösung zentriert sein.width:200px
, und in meinem Beispiel, wie ich es gesetzt habewidth:210px
, muss ich das auch in demminmax
TeilWie @michael vorgeschlagen hat, ist dies eine Einschränkung bei der aktuellen Flexbox. Wenn Sie jedoch weiterhin
flex
und verwenden möchten,justify-content: center;
können Sie dies umgehen, indem Sie ein Dummy-li
Element hinzufügen und zuweisenmargin-left
.const handleResize = () => { const item_box = document.getElementById('parentId') const list_length = item_box.clientWidth const product_card_length = 200 // length of your child element const item_in_a_row = Math.round(list_length/product_card_length) const to_be_added = item_in_a_row - parseInt(listObject.length % item_in_a_row) // listObject is the total number items const left_to_set = (to_be_added - 1 ) * product_card_length // -1 : dummy item has width set, so exclude it when calculating the left margin const dummy_product = document.querySelectorAll('.product-card.dummy')[0] dummy_product.style.marginLeft = `${left_to_set}px` } handleResize() // Call it first time component mount window.addEventListener("resize", handleResize);
Überprüfen Sie diese Geige (Größe ändern und sehen) oder Video als Referenz
quelle
Eine Möglichkeit, den gewünschten Stil mit Rändern zu erhalten, besteht darin, Folgendes zu tun:
#container { display: flex; justify-content: center; } #innercontainer { display: flex; flex: 0.9; -> add desired % of margin justify-content: flex-start; }
quelle
Sie können unsichtbare Elemente mit derselben Klasse wie die anderen platzieren (zum Beispiel zu Ausstellungszwecken entfernt) und die Höhe auf 0 setzen. Auf diese Weise können Sie die Elemente bis zum Anfang des Rasters ausrichten.
Beispiel
<div class="table-container"> <div class="table-content"> <p class="table-title">Table 1</p> <p class="mesa-price">$ 20</p> </div> <!-- Make stuff justified start --> <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div> <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div> <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div> <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div> </div>
Ergebnis
quelle
Beim Codieren mit React Native bin ich auf dieses Problem gestoßen. Es gibt eine elegante Lösung, die Sie mit FlexBox haben können. In meiner speziellen Situation habe ich versucht, drei Flexboxen (Flex: 2) mithilfe von alignItems in einer anderen zu zentrieren. Die Lösung, die ich gefunden habe, bestand darin, zwei leere s mit jeweils Flex: 1 zu verwenden.
<View style={{alignItems: 'center', flexWrap: 'wrap', flexDirection: 'row'}}> <View style={{flex: 1}} /> // Content here <View style={{flex: 1}} /> </View>
Einfach genug, um in Web / CSS zu konvertieren.
quelle