Situation: Sie haben eine einzelne Textzeile in einem Flex-Kind-Element. Sie möchten nicht, dass dieser Text umbricht, sondern abgeschnitten wird (mit Auslassungspunkten) oder einfach überläuft und versteckt wird. Aber das Schlimmste passiert. Das Undenkbare! Das Layout bricht und erzwingt, dass das gesamte Flex-Elternelement zu breit wird. Flexbox soll doch eigentlich dabei *helfen*, das Layout *einfacher* zu gestalten!
Glücklicherweise gibt es eine (standardisierte) Lösung. Sie müssen nur eine Nicht-Flexbox-Eigenschaft/einen Nicht-Flexbox-Wert verwenden, um dies zu erreichen.
Was wir wollen

Das potenzielle Problem

Dies kann nicht nur verhindern, dass ein Container schmaler wird, sondern einen Container auch extrem breit machen.
Kindelemente (des Flex-Kindes) sind das Problem
Um die Sache etwas zu verwirren... wenn sich der betreffende Text direkt im Flex-Kind befindet, funktioniert es einwandfrei
<div class="flex-parent">
<div class="flex-child">
Text to truncate here.
</div>
<div class="flex-child">
Other stuff.
</div>
</div>
/* Text is directly within flex child,
so doing the wrapping here */
.flex-child {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Das Problem tritt auf, wenn Kindelemente vorhanden sind, wie z. B.:
<div class="flex-parent">
<div class="flex-child">
<h2>Text to truncate here.</h2>
</div>
<div class="flex-child">
Other stuff.
</div>
</div>
/* Text is a header now,
so need to truncate there for it to work */
.flex-child > h2 {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Die Lösung ist min-width: 0; auf dem Flex-Kind
Oder min-width mit einem tatsächlichen Wert. Ohne dies wird das Flex-Kind, das die anderen Textelemente enthält, nicht über die "implizite Breite" dieser Textelemente hinaus schmaler.
Als ich zum ersten Mal auf dieses Problem stieß, fand ich die Lösung über einen Pen von AJ Foster. Er schreibt:
Laut einem Entwurf der Spezifikation sollte sich der obige Text beim Verkleinern des Flex-Containers nicht vollständig zusammenklappen. Da .subtitle eine Breite von 100 % hat, besagt die min-width: auto-Berechnung, die Flexbox durchführt, dass sein Container größer sein sollte, als wir wollen.
Ich fand dieses Verhalten konsistent über Chrome, Opera und Firefox. Safari schrumpfte/schnitt sogar ohne die min-width ab (meiner Meinung nach gegen die Spezifikation).
Demo
Sehen Sie den Pen Thing you gotta know about flexbox von Chris Coyier (@chriscoyier) auf CodePen.
- Funktioniert: Text befindet sich direkt im Flex-Kind
- Fehlerhaft: Text befindet sich in einem
<h2>innerhalb des Flex-Kindes - Funktioniert: Text befindet sich in
<h2>, abermin-widthist auf das Flex-Kind gesetzt
overflow: hidden;scheint auch zu funktionieren, was meiner Meinung nach mehr Sinn ergibt alsmin-width(was wahrscheinlichflex-shrinkauslöst).Es ist gut zu sehen, dass das Verhalten jetzt (etwas mehr) konsistent über die Browser hinweg ist. Das war damals wirklich frustrierend. Danke für das Teilen!
Das ist eigentlich viel einfacher als das. Sie brauchen den
min-widthHack nicht, damit das funktioniert. Alles, was Sie tun müssen, ist das Folgende auf das Flex-Kind und sein direktes Kind anzuwenden.Sie können den Pen Flexbox und abgeschnittener Text (kein min-width Hack) von Larry Gordon (@psyrendust) auf CodePen ansehen.
Ich denke, das Anwenden einer Eigenschaft auf ein Element ist ziemlich einfach. Ich denke, Ihr obiges Beispiel funktioniert, weil overflow hidden auf das Flex-Kind angewendet wird, was auch funktioniert (wie zzzzBov oben bemerkt hat).
Chris, könntest du einen CodePen des ursprünglichen Problems erstellen, das du zu lösen versucht hast?
Ein cooler kleiner Trick. Ich stimme zu, es ist viel schöner, nur eine Regel festzulegen, als sich mit den Kindern zu befassen und Selektoren hinzuzufügen. Danke, Chris!
Und wo ist der Tooltip mit verstecktem Text?
+1 Herausforderung zu lösen.
Danke, aber wann wäre das nützlich? Gibt es eine Möglichkeit, ein Wort statt Text abzuschneiden? So dass die Auslassungspunkte nach einer Wortgrenze erscheinen? Danke.
Es funktioniert sogar ohne Flex, kein Grund, Flex zu verwenden, nehme ich an.
min-width: 0ist kein Hack, es ist per Spezifikation. Flex-Elemente haben als implizitesmin-widthdie Inhaltsbreite, um Überläufe zu vermeiden (mehr dazu unter https://bugzilla.mozilla.org/show_bug.cgi?id=1108514#c5)Ältere Versionen von Chrome folgten der Spezifikation nicht und setzten 0 als
min-width.Der Artikel verlinkt und referenziert die relevanten Teile der Spezifikation. Ich habe nichts hierzu gesagt oder implizieren wollen. Interessant, dass dies etwas ist, das sich im Laufe der Zeit in Chrome geändert hat.
Entschuldige @Chris, als ich von "Hack" sprach, bezog ich mich auf den Satz von @LarryGordon.
Das eigentliche Problem mit Textüberlauf und Flexbox ist, dass ein Element mit
display:flexkeine Auslassungspunkte unterstützt, Sie müssen den Text in eine zusätzliche Div einwickeln.Ich denke, Sie irren sich da. #1 im Demo hat Auslassungspunkte direkt auf dem Flex-Kind.
@chris, ich bezog mich auf diesen http://codepen.io/FezVrasta/pen/BKedgY
Ich stoße ständig auf dieses Problem!! Aber ich kämpfe immer noch ein wenig.
Was, wenn sich 2 Textknoten im Flex-Kind befinden? Ich muss das tun, aber nur den ersten Textknoten abschneiden. Schauen Sie sich diesen Pen an, um eine Vorstellung davon zu bekommen, was ich zu erreichen versuche: http://codepen.io/tgallimore/pen/aNqQzR
Wenn mir jemand helfen kann, dies mit der zweiten DOM-Struktur im Pen zu tun, werde ich Sie ewig lieben!
Der Grund, warum ich die zweite DOM-Struktur verwenden muss, ist, dass wir dies auch für Nicht-Flexbox-Browser funktionsfähig machen müssen (mit einigen akzeptablen Unterschieden). Und es ist einfach, dies mit der zweiten DOM-Struktur zu tun, indem Elemente absolut positioniert und Breiten usw. gesetzt werden.
Ernsthaft... Kann niemand helfen?
Sie können einfach
display: flex;in.container2 .left-wrapeinfügen.Es ist das, wonach Sie suchen, wenn ich Sie richtig verstehe.
http://codepen.io/long-lazuli/pen/YqbvaE?editors=0100
Das ist genau das, was ich brauchte, vielen Dank.
Ich bin sicher, ich habe schon etwas Ähnliches versucht. Muss aber etwas übersehen haben.
Danke trotzdem.
Chris,
Hier ist ein Flexbox-Problem, mit dem ich kämpfe.
Zwei Kindelemente sind gestreckt und beide werden selbst als Flexbox-Wrapper verwendet. Das erste Kindelement ist wie folgt gestylt...
Hier ist die Sache, die ich nicht begreifen kann.
Da der Container vertikal gestreckt ist und die gleiche Höhe wie sein Nachbar behält, warum wird dann, wenn ich das letzte Element im Unter-Flexbox-Element des Kind-Elements auf { align-self: flex-end; } setze, dieses Element nach rechts (horizontal) verschoben und nicht an das Ende des gestreckten Flexbox (vertikal), wenn die Elemente in Spalten gestapelt sind?
Es widerspricht der Logik.
Beispiel: „Schauen Sie uns bei Retro-Stand B24-25 an“ auf http://epsilonlocal.com/retro/
Im Moment benutze ich Polsterung, um diesen Satz ans Ende der Flexbox zu schieben, aber ich dachte, ich könnte ihn dort in der Flexbox einstellen.
Beste Grüße
@Ansel: Entfernen Sie die align-self aus der linken Spalte und verwenden Sie dann einfach margin-top:auto auf dem Element, das nach unten geschoben werden soll.
z.B.
Das
margin-top:autoschiebt das Element ganz nach unten.Hier ist ein ähnliches Beispiel:
http://codepen.io/paulobrien/pen/rxMPVB
Danke, Herr O'Brien!
Das hat mich weitergebracht... aber warum funktioniert margin-top: auto; auf diese Weise? Ich bin etwas verwirrt, wie das die Lösung ist. Trotzdem danke, danke, danke!
Viele Grüße,
Ansel
@Ansel: Ja, Auto-Ränder bei Flex-Elementen sind ein kleines Geheimnis und sie verteilen jeden freien Platz in dieser Richtung.
z. B. Ein Flex-Element mit fester Breite und Höhe wird einfach vertikal und horizontal zentriert, indem auf allen 4 Seiten Auto-Ränder verwendet werden.
https://www.w3.org/TR/css-flexbox-1/#auto-margins
Marcin Mendlik hat mit einer potenziellen Lösung für IE 11 geschrieben.
Ich habe in meiner eigenen Demo nur "0" verwendet.