Wenn eine Zeile nicht umbricht

Avatar of Welling Guzman
Welling Guzman am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Wir erwarten, dass eine Zeile umbricht, wenn der Text auf dieser Zeile die Grenzen des übergeordneten Elements erreicht. Wir sehen das jedes Mal, wenn wir einen Absatz erstellen, genau wie diesen. Wenn der übergeordnete Container nicht genug Platz für das nächste Wort in einer Zeile hat, wird es umgebrochen und auf die nächste Zeile verschoben, und dieser Prozess wiederholt sich.

Nun, so funktioniert es, wenn Wörter durch Leerzeichen oder andere Whitespaces getrennt sind. Was CSS betrifft, gibt es fünf (!) Eigenschaften, die beeinflussen können, wie und wann eine Zeile umbricht. Lassen Sie uns das aber nicht noch einmal aufgreifen. Betrachten wir stattdessen eine Situation, in der es so aussieht, als würde eine Zeile umbrechen, es aber nicht tut, als Anlass, etwas über Zeilenumbrüche zu lernen.

Was passiert in einer Situation, in der der Browser nicht weiß, wann ein Umbruch in Ordnung ist?

Bringen wir uns mit einer "Tag-Liste" in eine schlechte Situation und kommen dann wieder daraus heraus. Hier ist unser Markup

<ul>
  <li>PHP</li>
  <li>JavaScript</li>
  <li>Rust</li>
  <!-- etc. -->
</ul>

Als Nächstes wenden wir CSS an, das den Standardlistenstil von seiner Standard-Vertikalorientierung auf Horizontal umschreibt, indem wir die Listenelemente `inline` anzeigen lassen.

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}


li {
  display: inline;
  padding-right: 5px;
}

Die Liste sieht genau so aus, wie wir sie wollen. Ich habe ein wenig Abstand zwischen den Listenelementen eingefügt, damit sie nicht zu gedrängt aussehen.

Fügen wir nun ein Wrapper-Element hinzu. Das ist im Wesentlichen ein `div` um die ungeordnete Liste. Wir können ihm eine Klasse geben, z. B. .tags.

<div class="tags">
  <ul>
    <li>PHP</li>
    <li>JavaScript</li>
    <li>Rust</li>
  </ul>
</div>

Nehmen wir an, wir möchten dem Wrapper eine feste Breite von 200 Pixeln geben. Dort sollten wir erwarten, dass Zeilenumbrüche auftreten, wenn die ungeordnete Liste an die Grenzen des Wrappers stößt.

.tags {
  width: 200px;
}

Hier kommt der interessante Teil. Viele Leute verwenden Minifier in ihrem Build-Prozess, um die Dateigrößen durch Entfernen unnötiger Werte zu reduzieren. Einige dieser Werte sind Whitespaces, einschließlich Leerzeichen, Tabs und Zeilenumbrüche (wie Wagenrücklauf und Zeilenvorschub) Zeichen, die zur Formatierung verwendet werden, aber von Minifiern als für das Endergebnis irrelevant angesehen werden.

Wenn wir unser HTML durch Entfernen von Zeilen "minifizieren", erhalten wir Folgendes:

<div class="tags"><ul><li>PHP</li><li>JavaScript</li><li>Rust</li></ul></div>

OH NEIN. Wie Sie sehen können, bricht die Liste nicht mehr am 200-Pixel-Rand um. Warum? Was ist jetzt anders? Persönlich dachte ich, HTML kümmere sich nicht um Whitespaces. Was ist an der minifizierten Version vom ursprünglichen Markup so anders?

Der Browser kümmert sich *tatsächlich* um Whitespaces ... aber nur *manchmal*. Und das ist eine dieser Gelegenheiten. Wenn die Seite geparst wird, sieht der Parser diese Liste als ein langes Wort, weil aus seiner Sicht keine Zeichen vorhanden sind, die eines vom anderen unterscheiden.

Man könnte denken, der Abstand beeinflusse die Dinge. Aber wenn wir den Abstand von unseren Listenelementen entfernen, erhalten wir immer noch das gleiche Ergebnis ... nur ohne Abstand zwischen den Elementen.

Der Browser sieht die gesamte Liste als ein einziges Wort.

Wir können natürliche Zeilenumbrüche aus Sonderzeichen erhalten

Abgesehen von Leerzeichen, mit Ausnahme von geschützten Leerzeichen (`&nbsp;`), gibt es einige andere Zeichen, die einen Zeilenumbruch erzwingen, darunter:

  • Nach Bindestrich (`-`)
  • Nach Halbgeviertstrich (`–`)
  • Vor und nach Gedankenstrich (`—`)
  • Nach Fragezeichen (`?`)
  • Nullbreiten-Whitespace (`U+200B` oder `&#8203;`)

Diese Zeilenumbrüche erfolgen zur Rendering-Zeit, was bedeutet, dass der Browser dies immer noch als ein langes Wort betrachtet. Das Hinzufügen eines neuen Listenelements zur Tag-Liste mit einem dieser Zeichen erzwingt einen Zeilenumbruch. Fügen wir "Objective-C" zur Liste hinzu. Sein Name enthält einen Bindestrich, den wir verwenden können, um zu sehen, wie sich dies auswirkt.

Aus Gründen der besseren Lesbarkeit wird der Code mit Einrückungen und neuen Zeilen versehen.

<div class="tags">
  <ul>
    <li>PHP</li>
    <li>JavaScript</li>
    <li>Rust</li>
    <li>Objective-C</li>
  </ul>
</div>

Das ist gut. Betrachten wir drei Lösungen für unsere nicht-umbruchbare Liste in diesem Sinne.

Lösung 1: Hinzufügen eines der Umbruchzeichen

Wir können weiterhin Zeilenumbrüche mit diesen Umbruchzeichen erzwingen, wie wir es gerade getan haben. Denken Sie jedoch daran, wenn Sie einen Minifier verwenden, werden die Leerzeichen oder nach dem schließenden Tag nicht garantiert entfernt, da nicht alle Minifier auf die gleiche Weise funktionieren.

<div class="tags">
  <ul>
    <li>PHP </li>
    <li>JavaScript </li>
    <li>Rust </li>
    <li>Objective-C </li>
  </ul>
</div>

Lösung 2: Verwendung von Pseudo-Elementen

Das Umbruchzeichen kann auch über die Pseudo-Elemente `::before` und `::after` in CSS hinzugefügt werden. Was diese Lösung effektiv macht, ist, dass sie nicht von einem HTML-Minifier beeinflusst wird, da der Whitespace beim Anwenden des CSS hinzugefügt wird.

Aber bevor wir weitermachen, sprechen wir kurz über kollabierende Whitespaces.

Der Browser kollabiert Whitespace vor und nach einem Zeichen, das einen Zeilenumbruch innerhalb von Inline-Elementen erzwingt. Mit diesem Wissen gibt es einen kleinen Trick bei der Verwendung von `::after` und der `content`-Eigenschaft mit Whitespace und `display: inline-block`. Das `inline-block`-Element fügt am Ende des Textes ein Umbruchzeichen hinzu. Dann kommt der Leerzeicheninhalt der `content`-Eigenschaft nach dem durch das `inline-block`-Element erzeugten Umbruchzeichen, was dazu führt, dass der Leerzeichen zur Renderzeit entfernt wird. Das heißt, es sei denn, die `white-space`-Eigenschaft ist auf `pre` gesetzt.

Lösung 3: Verwenden Sie stattdessen `inline-block`

Vielleicht haben Sie sich schon einmal mit dem Kampf mit Leerzeichen zwischen `inline-block`-Elementen in CSS auseinandergesetzt. Wir können den `inline-block`-Wert für die `display`-Eigenschaft verwenden, um einen Zeilenumbruch zu erzwingen, da das `inline-block`-Element bereits den zusätzlichen Whitespace hat, den wir benötigen. Dies funktioniert ähnlich wie das Hinzufügen eines Nullbreiten-Leerzeichenzeichens, aber die Listenelemente haben keine visuelle Trennung.

Lösung 4: Verwenden Sie `flex` oder `inline-flex`

Eine weitere Lösung besteht darin, die ungeordnete Liste als Flex-Container zu definieren, was uns ermöglicht, `flex-flow` zu verwenden, um die Ausrichtung der Liste festzulegen und sicherzustellen, dass sie bei Bedarf auf mehrere Zeilen umbricht.

Wir können uns auch an die Lösung `display: inline-flex` anstelle von `inline-block` wenden. Die Idee hier ist, dass der gesamte flexible Container inline angezeigt wird.


Wir haben diesen Beitrag mit einer Situation begonnen, die beim Verwenden eines Minifier auftreten kann. Das gesagt, Minifier – und viele Bibliotheken dafür – sind schlau und werden versuchen, dieses Problem mit dem Zeilenumbruch zu vermeiden.

Sicher, es ist keine extrem häufige Situation, auf die man stößt. Es ist wirklich eines dieser Dinge, die unbemerkt bleiben können, wenn wir nicht aufpassen, aber wenn es doch passiert, wissen wir zumindest, dass es Wege gibt, es zu umgehen.