Abschnitt 9 · Lektion 6
Wachsen und schrumpfen
Eine Seitenspalte soll 280 Pixel breit sein und wird von einem langen Pfad im Nachbarn zerdrückt. Und der Hauptbereich wächst nicht in den freien Platz. Wie sich Flex-Items den Platz teilen, regeln drei Eigenschaften. Geschrieben werden sie praktisch immer als eine.
Drei Angaben in einem Shorthand
Jedes Flex-Item hat drei Angaben.
flex-basisist die Ausgangsgröße, bevor verteilt wird. Der Standard istauto, also „nimm meinewidth, und ohne sie so groß wie mein Inhalt“.flex-growsagt, welchen Anteil am Überschuss das Item bekommt. Der Standard ist0, es wächst also nicht.flex-shrinksagt, wie stark es den Mangel mitträgt. Der Standard ist1, es schrumpft also mit. Anders als beim Wachsen zählt dabei auch die Ausgangsgröße. Ein breites Item gibt mehr ab als ein schmales.
Damit ist nebenbei klar, warum sich die Karten in 9.2 gequetscht haben. flex-shrink: 1 gilt von Haus aus, und eine Breitenangabe ist für Flexbox ein Vorschlag.
Geschrieben wird das fast immer als Shorthand flex: grow shrink basis.
flex: 1 gegen flex: auto
<p class="titel">ohne Angabe: jeder so breit wie sein Inhalt</p>
<div class="reihe ohne">
<div class="spalte">kurz</div>
<div class="spalte">mittel</div>
<div class="spalte">am längsten</div>
</div>
<p class="titel">flex: 1 an allen: exakt gleich breit</p>
<div class="reihe eins">
<div class="spalte">kurz</div>
<div class="spalte">mittel</div>
<div class="spalte">am längsten</div>
</div>
<p class="titel">flex: auto an allen: der Inhalt zählt mit</p>
<div class="reihe automatisch">
<div class="spalte">kurz</div>
<div class="spalte">mittel</div>
<div class="spalte">am längsten</div>
</div> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
}
.titel {
margin-bottom: 4px;
font-size: 14px;
color: #52525b;
}
.reihe {
display: flex;
gap: 8px;
margin-bottom: 24px;
}
.spalte {
padding: 16px;
color: #ffffff;
background-color: #2563eb;
}
/* flex: 1 setzt die Ausgangsgröße auf 0. Alle drei
starten damit bei nichts, und der ganze Platz wird
zu gleichen Teilen verteilt. */
.eins .spalte {
flex: 1;
}
/* flex: auto lässt die Ausgangsgröße beim Inhalt.
Verteilt wird nur, was darüber hinaus übrig ist. */
.automatisch .spalte {
flex: auto;
} Zwei Shorthands sehen ähnlich aus und tun etwas anderes.
flex: 1bedeutet1 1 0%. Die Ausgangsgröße ist null. Alle Items starten bei nichts, der gesamte Platz ist Überschuss und wird zu gleichen Teilen verteilt. Heraus kommen gleich breite Spalten, solange kein einzelnes Wort breiter ist als sein Anteil. Den Grund dafür findest du weiter unten beimin-width: 0.flex: autobedeutet1 1 auto. Die Ausgangsgröße ist der Inhalt. Verteilt wird nur, was darüber hinaus übrig bleibt, und heraus kommen ungleich breite Spalten, die zusammen die volle Breite füllen.
In Zahlen sieht das so aus. Bei der Breite, mit der die Spalte startet, misst der Inspector ohne Angabe rund 66, 79 und 132 Pixel, also so breit wie ihr Text, und rechts bleibt Platz übrig. Mit flex: 1 sind alle drei exakt 116 breit. Der Text „am längsten“ bricht bei dieser Breite um, und deshalb sind auch alle drei 70 hoch statt 51. Mit flex: auto heißen die Zahlen rund 90, 103 und 156. Das sind die Ausgangsgrößen von oben plus je rund 24 Pixel, denn der Überschuss wird zu gleichen Teilen verteilt, nicht die Gesamtbreite.
Im Streifen fehlen flex-grow, flex-shrink und flex-basis. Dort stehen nur die vier Zeilen des Containers, und diese drei gehören dem Item. Im Streifen steht das Ergebnis, also die Breite. Wie sie zustande kam, steht im Stylesheet.
Werden drei Spalten unerwartet ungleich breit, sehe ich zuerst nach, ob dort 1 oder auto steht. Beides ist richtig, je nachdem, was du willst. Für drei gleich große Kacheln nehme ich flex: 1. Eine Werkzeugleiste, in der jeder Button so breit ist wie seine Beschriftung und sich nur der Rest verteilt, bekommt flex: auto.
flex-shrink: 0 und min-width: 0
<p class="titel">ohne Schutz: die Seitenspalte wird zerdrückt</p>
<div class="layout ohne">
<main>
<p class="pfad">/home/mario/projekte/portfolio/assets/hero-2400.jpg</p>
</main>
<aside>280px breit, angeblich</aside>
</div>
<p class="titel">mit flex-shrink: 0 und min-width: 0</p>
<div class="layout mit">
<main>
<p class="pfad">/home/mario/projekte/portfolio/assets/hero-2400.jpg</p>
</main>
<aside>280px breit, wirklich</aside>
</div> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
}
.titel {
margin-bottom: 4px;
font-size: 14px;
color: #52525b;
}
.layout {
display: flex;
gap: 16px;
margin-bottom: 24px;
}
main {
padding: 16px;
background-color: #f4f4f5;
}
aside {
flex-basis: 280px;
padding: 16px;
color: #ffffff;
background-color: #18181b;
}
.pfad {
margin: 0;
font-family: ui-monospace, monospace;
white-space: nowrap;
}
/* Zwei Angaben, zwei verschiedene Aufgaben. Die eine
verbietet der Seitenspalte das Schrumpfen. Die
andere erlaubt es dem Hauptbereich: ohne sie geht
er nie unter die Breite seines längsten Inhalts. */
.mit aside {
flex-shrink: 0;
}
.mit main {
min-width: 0;
}
/* min-width: 0 erlaubt das Schrumpfen, gekürzt wird
damit nichts. Was übersteht, regelt overflow. */
.mit .pfad {
overflow: hidden;
text-overflow: ellipsis;
} Zwei Werte, die man selten braucht und dann dringend.
flex-shrink: 0 verbietet einem Item das Schrumpfen. Der klassische Fall ist die Seitenspalte, die 280px breit sein und es auch bleiben soll, wenn daneben viel Inhalt steht. Ohne die Angabe schrumpft sie mit, weil 1 der Standard ist.
min-width: 0 ist das Gegenstück und weniger offensichtlich. Ein Flex-Item hat von Haus aus min-width: auto, und damit wird es nie schmaler als sein eigener längster unteilbarer Inhalt. Ein langer Pfad, eine URL, eine breite Tabelle, und der Hauptbereich weigert sich zu schrumpfen. Zerdrückt wird dann der Nachbar. min-width: 0 hebt diese eingebaute Untergrenze auf.
Was min-width: 0 nicht tut, ist kürzen. Der Kasten darf damit schrumpfen, aber der Inhalt darin bleibt so lang, wie er ist, und ragt dann heraus. Was mit dem Überstand passiert, regeln overflow und text-overflow. Im Beispiel steht deshalb noch ein overflow: hidden mit text-overflow: ellipsis am Pfad, sonst sähe die reparierte Reihe kaputter aus als die darüber.
Die beiden zusammen sind das Standardrezept für ein zweispaltiges Layout. Fehlt eines davon, sieht das Ergebnis nach einem Fehler des Browsers aus.
In der Aufgabe verhalten sich beide Spalten einer Projektseite falsch, und beide sind schon Flex-Items.
Zum Mitnehmen
Solange min-width auf auto steht, bleibt ein Flex-Item mindestens so breit wie das längste Wort oder der längste Pfad darin. Das Item, das schrumpfen soll, bekommt min-width: 0, und das, das seine Breite halten muss, flex-shrink: 0.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 2 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.