Wiersze tekstu o jednakowej szerokości

Funkcje internetowe: text-fit text-wrap: balance text-box

Kompozycje w stylu plakatu, w których każdy wiersz jest skalowany tak, aby obejmował całą szerokość kontenera, mogą tworzyć efektowne wizualnie nagłówki. Dzięki text-fit przeglądarka skaluje każdy wiersz podczas układania, dzięki czemu pozostaje on prawidłowy po zmianie rozmiaru, zmianie tekstu i załadowaniu czcionki.

W przypadku pojedynczego wiersza wypełniającego kontener (np.nagłówka lub cytatu) zastosuj text-fit bezpośrednio do tego elementu. Ten przewodnik dotyczy wielowierszowych kompozycji.

Implementacja podstawowa

W przypadku linii wymuszonych:

  • Umieść każdy wiersz w elemencie <span> z atrybutem display: block.
  • Zastosuj white-space: nowrap do każdego wymuszonego wiersza <span>.

Wskazówki dotyczące implementowania:

  • Użyj text-fit: grow per-line-all <percentage> w samym nagłówku.
  • Użyj per-line-all, a nie per-line. per-line pomija ostatni wiersz i każdy wiersz kończący się wymuszonym podziałem, więc przy jednym bloku na wiersz nic nie skaluje.
  • Nie można połączyć grow z shrink. Ustaw wartość bazową font-size na maksymalną lub minimalną w zależności od tego, co będzie lepszą wartością zastępczą lub będzie łatwiejsze do obliczenia, i odpowiednio ustaw text-fit na shrink lub grow. Jeśli nie masz powodu, aby używać shrink, preferuj grow + ustawienie font-size na minimum, ponieważ jest to bezpieczniejsze w większości przypadków.
  • Zawsze ograniczaj wzrost lub spadek za pomocą wartości procentowej (np. 300%) jako zabezpieczenia.
  • Kontener musi mieć określony rozmiar inline. text-fit nigdy nie zmienia rozmiaru wewnętrznego, więc nie ma wpływu na szerokości fit-content/max-content ani elementy flex/grid o rozmiarze treści.
  • Przycinanie odstępu nad pierwszym i pod ostatnim wierszem: zobacz Precyzyjne wyrównanie tekstu.
  • Wartość line-height powinna być mała, nie większa niż 1, ponieważ w przeciwnym razie odstępy między wierszami o różnych rozmiarach czcionki będą zbyt duże.
  • WAŻNE: pamiętaj, że obliczona wartość font-size nie ulega zmianie, więc odstępy em nie są skalowane.
  • Aby uniknąć przypadkowego nadmiernego podkreślenia sierot, zastosuj text-wrap: balance lub text-wrap: pretty, jeśli są wolne wiersze.

Odstępy

Jeśli wszystkie linie są wymuszone, zapewnia to większą kontrolę nad odstępami:

  • Zastosuj text-box: trim-both cap alphabetic do każdego bloku wiersza, aby jego pole obejmowało własne glify. Przycinanie odbywa się na podstawie przeskalowanych danych. Więcej informacji znajdziesz w sekcji Precyzyjne wyrównanie tekstu.
  • Do odstępów między wierszami używaj funkcji Flexbox lub Grid + gap w nagłówku, a nie line-height. Odstępy są wtedy jednolite, a nie rosną wraz z rozmiarem czcionki w każdym wierszu.

Jeśli niektóre wiersze są wolne, nie używaj text-box: przycina on tylko pierwszy i ostatni wiersz, więc zewnętrzne wiersze będą przylegać do glifów, a wewnętrzne odstępy zachowają interlinię. Niech line-height zarządza wszystkimi odstępami.

Szata graficzna

  • Kompozycje wyglądają najlepiej, gdy rozmiary czcionek w poszczególnych wierszach znacznie się różnią. Unikaj tworzenia kompozycji z tekstu o jednolitych liniach, ponieważ spowoduje to, że rozmiary czcionek nie będą ani takie same, ani wystarczająco różne, co narusza zasadę projektowania dotyczącą kontrastu. Możesz to zapewnić, wymuszając krótkie wiersze: umieść słowa, które chcesz wyróżnić, w bloku, a resztę pozostaw do zawijania, czyli zastosuj mieszany układ. Jest to szczególnie ważne w przypadku połączenia z text-wrap: balance.
  • W przypadku skryptów zachodnich zalecamy połączenie tej opcji z text-transform: uppercase, ponieważ wydłużenia górne i dolne mogą tworzyć zamknięte przestrzenie lub nakładać się na sąsiednie linie, co wygląda mniej estetycznie.
  • Jeśli wymuszasz krótkie wiersze, wybierz słowa, które po podkreśleniu wzmocnią przekaz.
  • Ograniczenie: powiększony tekst będzie miał też większą równowagę wizualną, a jego pociągnięcia będą postrzegane jako mocniejsze. Obecnie nie ma możliwości zrównoważenia tego, np. przez zmniejszenie font-weight w przypadku większego tekstu, ponieważ nie ma jednostki, której można by użyć w obliczeniach, bo skalowanie nie wpływa na jednostki względne czcionki, takie jak em.

Strategie zastępcze

text-box

text-box nie wymaga osobnej wersji zastępczej: zachowaj mały symbol line-height również w przypadku stałych kompozycji. W przypadku text-box nie ma to żadnego wpływu, a tam, gdzie nie jest obsługiwane, odstępy są niewielkie, ale skalują się z rozmiarem czcionki każdego wiersza.

text-wrap: balance

text-fit

Wymuszone linie mają krótką, wierną kreację zastępczą: zmierz każdą linię w jej podstawowym rozmiarze i przeskaluj ją według współczynnika do kontenera, z tym samym limitem.

@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);
  }
}

Wiersze bez ograniczeń nie mają niezawodnego rozwiązania zastępczego (podziały wierszy są nieznane do momentu utworzenia układu): progresywne ulepszanie do zrównoważonego nagłówka o płynnym rozmiarze podstawowym, np. clamp(2rem, 1rem + 5cqi, 5rem). W mieszanym układzie powyższy skrypt nadal pasuje do wymuszonych wierszy. Blok zawijania jest tak szeroki jak kontener, więc zachowuje skalę 1 i otrzymuje tylko płynny rozmiar podstawowy.

Jeśli dopasowanie tekstu jest kluczowe, rozważ użycie biblioteki JS (np. fitty), która jest ładowana warunkowo tylko wtedy, gdy text-fit nie jest obsługiwany.