Izak Filmalter schrieb mir
Auf der Website, an der ich arbeite, gibt es eine Navigationsleiste mit einigen Elementen: ein Suchfeld, der vollständige Name des Benutzers und einige Symbole. Die Symbole haben eine feste Breite, der Name des Benutzers variiert und das Suchfeld soll den Rest des nutzbaren Platzes einnehmen.
Egal, was ich versuche, ich schaffe es nicht, dass das Suchfeld den gesamten verfügbaren Platz und nicht mehr nutzt, wenn die Länge des Benutzernamens dynamisch ist.
Ich habe Izak bereits eine Antwort gesendet, aber ich werde diese Lösung hier teilen. Flexbox! Ich bin mir sicher, dass es keine Überraschung ist, dass Flexbox ein wunderbares Werkzeug für Layouts ist. Ich habe hier einen Leitfaden zu Flexbox, der als gute Referenz dient.
Die gute Nachricht ist, dass dies mit Flexbox-Layout eine ziemlich einfache Sache ist. Wir werden detaillierter darauf eingehen, aber diese wenigen Codezeilen erledigen im Grunde die Arbeit.
.bar {
display: flex;
}
.search {
flex: 1;
}
Schritt für Schritt
Nehmen wir Markup wie dieses an. Nichts Überraschendes hier wirklich. Ich habe das Suchfeld in ein <div> eingeschlossen, hauptsächlich weil ich mich vor einem Eingabefeld, das zu einem Flex-Element wird, unwohl fühle. Aber man möchte wahrscheinlich sowieso ein umschließendes Element (wie ein <form>), da man wahrscheinlich ein <label> und so weiter hätte.
<div class="bar">
<div class="icon icon-1"></div>
<div class="icon icon-2"></div>
<div class="icon icon-3"></div>
<div class="username">
Emily Blunt
</div>
<div class="search">
<input type="search" placeholder="search..." />
</div>
</div>

Um sie horizontal auszurichten und zu zentrieren
.bar {
display: flex;
align-items: center;
}

Stellen wir sicher, dass die Leiste so breit wie das Browserfenster ist. Das können wir leicht mit 100% Breite einstellen. Aber jedes Mal, wenn ich das tue, erinnere ich mich, dass wir box-sizing: border-box; verwenden sollten – sonst wäre bei jedem Padding oder jeder Border auf diesem Container die Breite größer als 100% und das ist das Schlimmste.
*, *:before, *:after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
.bar {
display: flex;
align-items: center;
width: 100%;
background: #eee;
padding: 20px;
}

Für den letzten Trick
.search {
/* take up the rest of the remaining space */
flex: 1;
}
.search input {
width: 100%;
}

Es funktioniert dann so

Jetzt, wo wir im Flexbox-Land sind, können wir sogar die Reihenfolge der Elemente beliebig tauschen und die gleiche gute Abstandsaktion erzielen. Die `order`-Eigenschaft ist standardmäßig 0, sodass jeder positive Wert dieses Flex-Element am Ende platziert und jeder negative Wert am Anfang. Und dann in der Reihenfolge, genau wie `z-index`.
.bar-2 .username {
order: 2;
}
.bar-2 .icon-3 {
order: 3;
}
.bar-3 .search {
order: -1;
}
.bar-3 .username {
order: 1;
}

Bonus RWD!
Flexbox ist super freundlich zu responsivem Design, da wir die Reihenfolge und Größe und sogar das Umbrechen wirklich einfach ändern können. Machen wir unsere Demo umbrechend und geben wir der Suche und dem Benutzernamen volle Breite.
@media (max-width: 650px) {
.bar {
flex-wrap: wrap;
}
.icon {
order: 0 !important;
}
.username {
order: 1 !important;
width: 100%;
margin: 15px;
}
.search {
order: 2 !important;
width: 100%;
}
}

Demo
Hier geht's los
Siehe den Stift Flexbox reordering von Chris Coyier (@chriscoyier) auf CodePen.
Browser-Unterstützung
Man kann heutzutage nicht über Flexbox reden, ohne etwas Gerede über Browserunterstützung. Wie immer können Sie Can I Use konsultieren. IE 9 ist die große Einschränkung, die noch übrig ist. Wenn Sie das unterstützen müssen, müssen Sie einen anderen Weg finden. Ansonsten, zwischen alten / neuen / mittleren Synthesen, werden Sie gut zurechtkommen. Wir verwenden hier nichts Seltsames.
Der Trick besteht einfach darin, Autoprefixer zu verwenden, das Flexbox wunderbar handhabt. Wenn Sie das verwenden, werden die Flexbox-Eigenschaften/Werte in dieser Demo zu
.bar {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
.search {
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
.bar-2 .username {
-webkit-order: 2;
-ms-flex-order: 2;
order: 2;
}
Aber ich brauche einen besseren Fallback!
Eine Möglichkeit ist die Verwendung von Modernizr, um die Flexbox-Unterstützung zu erkennen. Es fügt dem html-Element eine Klassenbezeichnung hinzu, wie z.B.
<html class="no-flexbox">
Sie können das verwenden, um eine andere Layout-Technik zu verwenden
.no-flexbox .bar {
display: table;
border-spacing: 15px;
padding: 0;
}
.no-flexbox .bar > * {
display: table-cell;
vertical-align: middle;
white-space: nowrap;
}
.no-flexbox .username {
width: 1px;
}
Funktioniert ziemlich gut

Es ist nicht der einzige mögliche Weg. Man könnte mit `inline-block` oder `float` experimentieren und Dinge mit JavaScript messen. Oder man könnte eine tatsächliche Tabelle verwenden. Das Web, yo, es gibt immer einen Weg.
Ich sehe eine Idee für ein JavaScript-Plugin! Flexbox-Syntax, aber wenn es erkennt, dass Sie auf einem alten Browser sind, übersetzt es automatisch Flexbox in Tabellenlayout.
James, du siehst aus wie Mark Zuckerberg
*gibt Flexbox eine große Umarmung dafür, dass sie so nett ist*
Also, meine Frage ist dann: In 99% der Fälle behält man die Reihenfolge der Elemente bei... Warum also Flexbox mit seiner begrenzten Unterstützung verwenden, wenn man das Gleiche mit `table-cell` mit viel mehr Browserunterstützung erreichen kann?
Das scheint eine wirklich legitime Frage zu sein. Ich warte auch auf weitere Erklärungen hierzu.
Ich glaube nicht, dass die Bedeutung dieses Beitrags darin besteht, Leute zu zwingen, Flexbox zu verwenden. Sondern ihnen eine modernere Lösung als den "hacky way" mit `table-cell` zu bieten. Persönlich würde ich Flexbox implementieren und dabei lernen. Und einen Fallback über Modernizr bereitstellen.
Ich stimme zu, dass man daraus lernen kann, ich habe nie gesagt, dass man es nicht könnte. Aber ich widerspreche dem Wort "hacky" für `table-cell`-Display, es ist eine durchaus gangbare und nicht-hacky Methode, das tatsächlich zu tun...
Ja, du hast Recht, es ist nicht hacky, habe das falsche Wort benutzt :) Sagen wir einfach, es ist eine weniger bekannte / Außenseiter-Art des Layoutens. (Ich benutze es übrigens immer)
Hier sind ein paar Dinge, die mir in den Sinn kommen
Hallo Chris, ich stimme Ihrem Punkt 1 zu, obwohl es üblich ist, dies zu tun. Zu Ihrem Punkt 2 ist das richtig, obwohl ich, wie erwähnt, meine Frage bezüglich der meisten Fälle habe, in denen Sie all diese Flexibilität NICHT benötigen werden. Zu Ihrem Punkt 3 würde ich IE6/7 nicht in die Tabelle aufnehmen, aber Flexbox wird von IE9 nicht unterstützt, das immer noch viele Benutzer im Vergleich zu den von Ihnen erwähnten hat.
Ich würde argumentieren, dass alles, was auf eine Weise verwendet wird, für die es nicht bestimmt ist, von Natur aus eine hacky Verwendung ist. `display: table-cell` ist nur für Tabellenzellen gedacht; es ist hacky einfach, weil eine Symbolleiste keine Tabelle ist. Ich würde sogar sagen, dass die Verwendung von Floats für Layouts ein Hack ist, obwohl es seit Jahren der De-facto-Standard ist – es ist einfach nicht das, wofür es bestimmt war, weshalb es so unintuitiv funktioniert. Lange Zeit gab es einfach keine nicht-hacky Möglichkeit, das zu tun.
Das soll nicht heißen, dass hacky immer falsch ist. Manchmal sind Hacks weitaus praktischer, auch wenn es einen "korrekten" Weg gibt, Dinge zu tun. Aber es sind immer noch Hacks, und man sollte sich immer bewusst sein, dass sie in schwer zu findenden Szenarien unvorhersehbar reagieren können.
Hallo Javier, nur eine Sache zur Flexibilität, ich glaube nicht, dass du dir da so sicher sein kannst, ob du sie brauchst oder nicht, da sich Dinge mit der Zeit ändern. Daher denke ich, es ist besser, eine Option zur Anordnung von Dingen mit reinem CSS zu haben.
Mir sind die Kompatibilitätsprobleme mit älteren Browsern bewusst, aber das Gleiche hättest du auch früher über das Modell "box-sizing: border-box;" sagen können, das wir heute viel verwenden.
Ich dachte, es wäre Schmidt. John Jacob Jingleheimer Schmidt.
Das ist es... es ist Schmidt. Aber jetzt zeige ich nur mein Alter. Aber hey, Schmidt passiert, richtig?
Der Hauptgrund, warum ich zu Flexbox gewechselt bin anstelle von `display:table`, ist, dass letzteres jede Verwendung von `positioning` ausschließt.
Zum Beispiel benötigte ich kürzlich eine Suchleiste (sehr ähnlich dem hier gegebenen Beispiel) mit Dropdown-/Flyout-Menüs... sehr, sehr schwierig mit `display:table`. Mit Flexbox, ein Kinderspiel.
Funktioniert einwandfrei: http://davidwalsh.name/table-cell-position-absolute
Das nenne ich nicht einwandfrei. Die Notwendigkeit, `height: 100%` auf einem Elternteil anzugeben, um es in FF zum Laufen zu bringen, wird allerlei Schwierigkeiten verursachen.
Ich bin verliebt in Flex <3
Funktioniert Flexbox in IE9+ oder IE10+?
Hat jemand Fallbacks für Flexbox in alten Browsern zum Laufen gebracht? Ich glaube, es gibt keine Lösung = (
Nun, das ist eine knifflige Sache. Ich denke, der beste Weg ist so etwas wie eine kombinierte Methode aus Modernizr und `table-cell` anstelle von Flexbox.
Warum wird hier ein `!important` verwendet?
Wegen Spezifität. Ich empfehle nicht, was Chris hier tut, wenn `!important` verwendet wird, aber ich verstehe, warum er es tut.
Wenn Sie sich die vorherigen Codeblöcke ansehen, sehen Sie Nachfahrenselektoren wie ".bar-3 .username"... Um diese zu überschreiben, hat er sich entschieden, es einfach mit nur ".username" in den MQ-Stilen zu halten. Aber das überschreibt den vorherigen Selektor nicht. Also verwendet er `!important`, um ihn zu überschreiben.
Nochmal, ich empfehle das nicht, denn man kann einfach den Selektor wiederholen und alles ist gut... aber wenn Sie alleine arbeiten und verstehen, was Sie tun, dann ist es wohl eine Möglichkeit, es zu tun. Ich sehe einfach nicht, wie das Hinzufügen von `!important` anders ist, als einfach den Selektor zu wiederholen.
Hauptsächlich, weil es so alle drei Balken trifft. Nur ein billiger Weg, um nicht drei Selektoren in einem zusammengesetzten Selektor zu schreiben, um sie alle zu überschreiben.
Es wird definitiv nicht für eine große Produktionsanwendung empfohlen. Aber ich ziehe es dem künstlichen Erhöhen der Spezifität vor. Zumindest mit `!important` weiß man, dass es ein Problem ist, das man beheben muss.
Schöner Artikel... Leicht verständlich
Guter Beitrag, danke Chris, Flex ftw :)
Sehr schön Chris.
Perfektes Timing wie immer.
Beginne gerade mit einem Website-Rewrite nach 7 Jahren, Gott, sie sieht sooo veraltet aus.
Ich gehe derzeit davon aus, dass es weitere 7 Jahre dauern wird, bis ich es wieder tue.
Dieser Artikel hat mich überzeugt.
Puristisches HTML 5, mit Flexbox, das gefloatete Divs ersetzt, ist der Weg, den ich rocken werde.
Danke, Alter.