Textzeilen mit gleicher Breite

Poster-artige Lockups, bei denen jede Zeile so skaliert wird, dass sie die gesamte Breite des Containers einnimmt, können visuell ansprechende Überschriften erzeugen. Mit text-fit skaliert der Browser jede Zeile während des Layouts, sodass sie bei Größenänderungen, Änderungen am Text und beim Laden von Schriftarten korrekt bleibt.

Wenn eine einzelne Zeile den Container füllt (z. B. eine Überschrift oder ein Zitat), wenden Sie text-fit direkt auf dieses Element an. In diesem Leitfaden werden mehrzeilige Lockups behandelt.

Einfache Implementierung

Für erzwungene Zeilen:

  • Setzen Sie jede Zeile in ein <span> mit display: block.
  • Wenden Sie white-space: nowrap auf jede erzwungene Zeile <span> an.

Implementierungsrichtlinien:

  • Verwenden Sie text-fit: grow per-line-all <percentage> für die Überschrift selbst.
  • Verwenden Sie per-line-all, nicht per-line. per-line überspringt die letzte Zeile und alle Zeilen, die mit einem erzwungenen Umbruch enden. Bei einem Block pro Zeile wird also nichts skaliert.
  • grow kann nicht mit shrink kombiniert werden. Legen Sie entweder den Basis-font-size auf ein Maximum oder ein Minimum fest, je nachdem, was ein besserer Fallback oder einfacher zu berechnen wäre, und legen Sie text-fit entsprechend auf shrink oder grow fest. Wenn Sie keinen Grund haben, shrink zu verwenden, sollten Sie grow verwenden und font-size auf ein Minimum beschränken, da dies in den meisten Fällen sicherer ist.
  • Begrenzen Sie das Wachstum oder die Verkleinerung immer mit dem Prozentsatz (z.B. 300%) als Richtwert.
  • Der Container benötigt eine definierte Inline-Größe. text-fit ändert nie die intrinsische Größe, hat also keine Auswirkungen auf fit-content/max-content-Breiten oder Flex-/Grid-Elemente mit inhaltsbasierter Größe.
  • Kürzen Sie den Zeilenabstand über der ersten und unter der letzten Zeile: siehe Präzise Textausrichtung.
  • Halten Sie line-height klein, 1 oder weniger, da sonst die Abstände zwischen Zeilen mit unterschiedlichen Schriftgrößen unübersichtlich werden.
  • WICHTIG: Der berechnete font-size-Wert bleibt unverändert, sodass der em-Abstand nicht skaliert wird.
  • Um versehentlich überbetonte verwaiste Zeilen zu vermeiden, wenden Sie text-wrap: balance oder text-wrap: pretty an, wenn leere Zeilen vorhanden sind.

Abstand

Wenn alle Zeilen erzwungen werden, haben Sie mehr Kontrolle über die Abstände:

  • Wenden Sie text-box: trim-both cap alphabetic auf jeden Zeilenblock an, damit die Box die Glyphen umschließt. Die Kürzung erfolgt anhand der skalierten Messwerte. Weitere Informationen finden Sie unter Präzise Textausrichtung.
  • Verwenden Sie für den Zeilenabstand Flexbox oder Grid + gap für die Überschrift, nicht line-height. Die Abstände sind dann einheitlich, anstatt mit der Schriftgröße der einzelnen Zeilen zu wachsen.

Wenn einige Zeilen leer sind, verwende nicht text-box: Dadurch werden nur die erste und die letzte Zeile gekürzt, sodass die äußeren Zeilen die Glyphen umschließen, während die inneren Abstände ihren Zeilenabstand beibehalten. Lassen Sie alle Abstände von line-height steuern.

Visuelles Design

  • Lockups sehen am besten aus, wenn die Schriftgrößen zwischen den Zeilen stark variieren. Vermeiden Sie es, Lockups aus Text mit überwiegend einheitlichen Zeilen zu erstellen, da dies zu Schriftgrößen führt, die weder gleich noch ausreichend unterschiedlich sind. Dies verstößt gegen das Designprinzip des Kontrasts. Das lässt sich durch kurze Zeilen erreichen: Setzen Sie die zu betonenden Wörter in einen Block und lassen Sie den Rest umbrechen, d.h. ein gemischtes Lockup. Das ist besonders wichtig, wenn Sie sie mit text-wrap: balance kombinieren.
  • Bei westlichen Schriften sollte diese Option mit text-transform: uppercase kombiniert werden, da Ober- und Unterlängen dazu neigen, eingeschlossenen Raum zu erzeugen und/oder benachbarte Zeilen zu überlappen, was zu einem weniger ästhetischen Ergebnis führt.
  • Wenn Sie kurze Zeilen erzwingen, wählen Sie Wörter aus, die die Botschaft verstärken, wenn sie betont werden.
  • Einschränkung: Wenn Text vergrößert wird, erhöht sich auch sein visuelles Gewicht und die Striche werden als stärker wahrgenommen. Derzeit gibt es keine Möglichkeit, dies auszugleichen, z.B. durch Reduzieren von font-weight für größeren Text, da es keine Einheit gibt, die in einer Berechnung verwendet werden kann, da sich die Skalierung nicht auf schriftartbezogene Einheiten wie em auswirkt.

Fallback-Strategien

Für text-box

text-box benötigt kein separates Fallback: Behalte das kleine line-height auch bei festen Lockups bei. Unter text-box ist es ein No-Op und sorgt dafür, dass die Lücken dort, wo es nicht unterstützt wird, klein bleiben. Allerdings skalieren die Lücken mit der Schriftgröße der einzelnen Zeilen.

Für text-wrap: balance

Für text-fit

Erzwungene Linien haben einen kurzen, originalgetreuen Fallback: Jede Linie wird in ihrer Basisgröße gemessen und im Verhältnis zum Container skaliert, wobei dieselbe Obergrenze gilt.

@supports not (text-fit: grow) {
  .lockup > span {
    /* Shrink-wrap each line so its width is the text width */
    width: fit-content;
    /* --text-fit-scale is measured by the script; the cap mirrors the text-fit percentage */
    font-size: min(var(--text-fit-scale, 1) * 1em, 300%);
  }
}
if (!CSS.supports('text-fit', 'grow per-line-all')) {
  const fit = lockup => {
    const lines = [...lockup.querySelectorAll(':scope > span')];
    // Unscale first: on a refit, offsetWidth would otherwise include the previous scale
    for (const line of lines) line.style.removeProperty('--text-fit-scale');
    // MANDATORY: all reads, then all writes. Interleaving them (e.g. reading
    // lockup.clientWidth inside the write loop) forces one reflow per line.
    const scales = lines.map(line => lockup.clientWidth / line.offsetWidth);
    lines.forEach((line, i) => line.style.setProperty('--text-fit-scale', scales[i]));
  };
  // Refit on resize and font load
  for (const lockup of document.querySelectorAll('.lockup')) {
    new ResizeObserver(() => fit(lockup)).observe(lockup);
  }
}

Für flexible Zeilen gibt es keinen zuverlässigen Fallback (Zeilenumbrüche sind bis zum Layout unbekannt): progressive Verbesserung zu einer ausgewogenen Überschrift mit einer fließenden Basisgröße wie clamp(2rem, 1rem + 5cqi, 5rem). In einem gemischten Lockup passt das obige Skript immer noch in die erzwungenen Zeilen. Ein umbrechender Block ist so breit wie der Container, sodass er die Skalierung 1 beibehält und nur die flüssige Basisgröße erhält.

Wenn die Textanpassung wichtig ist, können Sie eine JS-Bibliothek (z.B. fitty) verwenden, die nur dann bedingt geladen wird, wenn text-fit nicht unterstützt wird.