Zachowaj dokładność grup wierszy SplitText, odbudowując je po zmianach układu tekstu. Korzystaj z automatycznego podziału przy obsługiwanych zdarzeniach, dodawaj jawne odbudowy po zmianach typografii i porównuj wynik z niepodzielonym tekstem przeglądarki w podglądzie na Macu.
Ten przewodnik jest przeznaczony dla osób edytujących stronę w przeglądarce z użyciem GSAP SplitText i płynnego nagłówka. Celem jest zachowanie zgodności każdego wygenerowanego kontenera wiersza ze słowami, które aktualnie znajdują się w danym wierszu wizualnym, także wtedy, gdy szerokość nagłówka pozostaje stała, a zmienia się rozmiar czcionki.
Dlaczego płynna typografia może pozostawiać nieaktualne grupy wierszy?
Wygenerowany kontener wiersza obejmuje określoną grupę słów. Po zmianie dostępnego miejsca lub typografii może być konieczne ponowne utworzenie tej grupy. GSAP dokumentuje opcję autoSplit: true dla zakończenia ładowania czcionek i zmian szerokości, gdy podział obejmuje wiersze. Te udokumentowane zdarzenia nie oznaczają, że istnieje ogólny obserwator każdej zmiany typografii. Dokumentacja SplitText
Rozważmy nagłówek z font-size: clamp(2rem, 4vw, 4rem) w kontenerze o maksymalnej szerokości 42rem. MDN definiuje clamp() jako wartość preferowaną, ograniczoną minimum i maksimum. W tym przykładzie preferowany rozmiar czcionki zależy od szerokości widocznego obszaru nawet po osiągnięciu limitu kontenera. Funkcja CSS clamp()
Poniższe obliczenia zakładają przykładowy rozmiar czcionki głównej wynoszący 16 pikseli CSS oraz wystarczającą ilość miejsca, by kontener osiągnął maksymalną szerokość. Są to obliczone wymiary, a nie wyniki pomiarów w przeglądarce ani przewidywane liczby wierszy.
| Szerokość widocznego obszaru | Szerokość kontenera po ograniczeniu | Obliczony rozmiar czcionki |
|---|---|---|
| 900 pikseli CSS | 672 piksele CSS | 36 pikseli CSS |
| 1200 pikseli CSS | 672 piksele CSS | 48 pikseli CSS |
| 1600 pikseli CSS | 672 piksele CSS | 64 piksele CSS |
Kontener zachowuje tę samą szerokość, a litery rosną. W praktyce oznacza to, że samo monitorowanie szerokości nie obejmuje tego przypadku. Potraktuj zmianę obliczonego rozmiaru czcionki jako kolejny powód do odbudowy, a następnie sprawdź rozmieszczenie słów.
Oceń dokładność, porównując z niepodzielonym tekstem renderowanym przez przeglądarkę przy tych samych wymiarach i stylach. Nie wymagaj, by nagłówek zachował pierwotną liczbę wierszy: układ płynny może tworzyć różne wiersze.
Zanim zmienisz animację, przygotuj niepodzielony tekst jako punkt odniesienia
Utwórz w lokalnym podglądzie dwie kopie krótkiego przykładowego nagłówka. Nadaj im tę samą szerokość, czcionkę, rozmiar, grubość, odstępy i reguły zawijania. Pierwszą pozostaw bez zmian, a na drugiej zastosuj SplitText. To tymczasowe porównanie uwidoczni nieaktualny podział bez zakładania, w którym miejscu powinno zawijać się konkretne słowo.
Zacznij od zwykłych odstępów i zawijania. Specyfikacja W3C CSS Text określa, jak white-space steruje zwijaniem białych znaków i miękkim zawijaniem wierszy; opisuje też osobne reguły dzielenia wierszy i odstępów. Odbudowa powinna zachować zamierzone reguły, zamiast zastępować je ręcznie wstawionymi podziałami. CSS Text Module Level 3
Jeśli strona korzysta z czcionek internetowych, przed pierwszym podziałem poczekaj na document.fonts.ready. MDN dokumentuje, że ta obietnica zostaje spełniona po zakończeniu odpowiedniego ładowania czcionek i operacji układu. Zapewnia to początkowy punkt pomiaru, ale nie blokuje późniejszych zmian układu. FontFaceSet: właściwość ready
Sprawdź też, której czcionki faktycznie używa przeglądarka. MDN odróżnia używane czcionki od wszystkich zadeklarowanych: na przykład opcjonalna czcionka może nie zostać użyta, jeśli nie zdąży się załadować w wyznaczonym czasie. Gotowość nie jest dowodem, że każda zadeklarowana czcionka stała się renderowaną czcionką. Document: właściwość fonts
Połącz automatyczny podział z jawną kontrolą płynnego rozmiaru
Poniższy kompletny moduł przeglądarkowy tworzy niepodzielony tekst do porównania, animowaną kopię i przycisk Toggle spacing. Użyj tymczasowej strony podglądu w istniejącym projekcie JavaScript, którego bundler obsługuje importy npm, najwyższopoziomowe await i uruchamia przeglądarkowy plik wejściowy po utworzeniu treści dokumentu. Zainstaluj Node.js i npm na Macu.
Zainstaluj GSAP w katalogu projektu następującym poleceniem. Do obsługi tego przepływu pracy z callbackami użyj GSAP w wersji 3.13 lub nowszej. Dokumentacja instalacji GSAP opisuje instalację przez npm i jawne rejestrowanie wtyczek. Instalacja
npm install gsap
Zastąp moduł wejściowy przeglądarki na tymczasowej stronie podglądu poniższym kodem. Inicjalizacja jest zgodna z udokumentowanym wzorcem SplitText.create(). Efekt zanikania używa gsap.from(), aby animować zmianę od zerowej przezroczystości do istniejącego wyglądu. SplitText.create(), gsap.from()
import { gsap } from 'gsap';
import { SplitText } from 'gsap/SplitText';
gsap.registerPlugin(SplitText);
const style = document.createElement('style');
style.textContent = `
.flow-demo {
width: min(100%, 42rem);
font-family: system-ui, sans-serif;
}
.flow-demo h2 {
font-size: clamp(2rem, 4vw, 4rem);
line-height: 1.15;
font-weight: 600;
margin: 1rem 0;
white-space: normal;
text-wrap: wrap;
}
.flow-line { outline: 1px solid #aaa; }
`;
document.head.append(style);
const host = document.createElement('section');
host.className = 'flow-demo';
const reference = document.createElement('h2');
reference.textContent =
'Panel Alpha holds a series of soft shapes beside Panel Beta.';
const target = reference.cloneNode(true);
const button = document.createElement('button');
button.type = 'button';
button.textContent = 'Toggle spacing';
host.append(reference, target, button);
document.body.append(host);
await document.fonts.ready;
const split = SplitText.create(target, {
type: 'lines',
linesClass: 'flow-line',
autoSplit: true,
onSplit(self) {
return gsap.from(self.lines, {
opacity: 0,
duration: 0.3,
stagger: 0.04
});
}
});
let timer;
let fontSize = getComputedStyle(target).fontSize;
function checkFluidSize() {
clearTimeout(timer);
timer = setTimeout(() => {
const next = getComputedStyle(target).fontSize;
if (next !== fontSize) {
fontSize = next;
split.split();
}
}, 150);
}
window.addEventListener('resize', checkFluidSize);
let spaced = false;
button.addEventListener('click', () => {
spaced = !spaced;
reference.style.letterSpacing = target.style.letterSpacing =
spaced ? '0.06em' : 'normal';
split.split();
});
Animacja jest tworzona wewnątrz onSplit() i zwracana, aby SplitText mógł ją posprzątać i zsynchronizować przy kolejnych odbudowach. GSAP dokumentuje ten przepływ pracy z callbackami w wersji 3.13 i nowszych. Dokumentacja SplitText
Dodany procedur obsługi zmiany rozmiaru sprawdza tylko obliczony rozmiar czcionki i żąda odbudowy po ustaniu zmian rozmiaru. Opóźnienie 150 milisekund to przykładowy wybór implementacyjny. Ten przykład zapewnia dokładne grupy po zakończeniu zmiany rozmiaru; nie gwarantuje poprawnego grupowania podczas każdej pośredniej klatki zmiany rozmiaru.
Przycisk odstępów pokazuje drugi jawny wyzwalacz. Zmienia obie kopie, a następnie wywołuje split.split(). GSAP dokumentuje, że w razie potrzeby ta metoda najpierw przywraca istniejący podział. W tym niewielkim przykładzie zmiana szerokości i rozmiaru czcionki może też spowodować nakładające się żądania odbudowy; jeśli profilowanie wykaże zbędną pracę na większej stronie, połącz je. split()
Moduł przeszedł kontrolę składni JavaScript, a przykładowe obliczenia wymiarów zostały wykonane. Układ i animacja w przeglądarce nie były tutaj uruchamiane; przeprowadź poniższe kontrole wizualne w lokalnym podglądzie.
Dobieraj wyzwalacze odbudowy do zmian w układzie
Przykład obserwuje jedno wyrażenie płynnego rozmiaru czcionki. Dostosowując go, ustal, który kod lub zdarzenie układu zmienia tekst, i uruchamiaj odbudowę w tym miejscu. Nie zakładaj, że przykład wykrywa niezwiązane zmiany klas, typografię zależną od kontenera ani ciągłą animację właściwości czcionki.
| Zmiana na stronie | Sugerowana obsługa |
|---|---|
| Szerokość elementu tekstowego | Włącz udokumentowane automatyczne dzielenie i sprawdź wynik. |
| Rozmiar czcionki zależny od szerokości widocznego obszaru przy stałej szerokości tekstu | Porównuj obliczony rozmiar po zmianie rozmiaru i odbudowuj podział, gdy się zmieni. |
| Element sterujący zmienia tracking, grubość lub ustawienia czcionki | Zażądaj odbudowy po zastosowaniu nowych stylów przez element sterujący. |
| Typografia zależy od otaczającego kontenera | Obserwuj kontener sterujący rozmiarem i sprawdzaj odpowiednie obliczone właściwości typografii. |
| Komponent staje się widoczny po ukryciu | Zainicjalizuj go lub odbuduj, gdy osiągnie docelowe wymiary renderowania. |
W układach zależnych od kontenera ResizeObserver zgłasza zmiany rozmiaru elementów niezależnie od zmiany rozmiaru okna. Obserwuj kontener, który dostarcza dane wejściowe dotyczące rozmiaru. Nie można zakładać, że obserwator pola tekstowego powiadomi o każdej zmianie obliczonego stylu. ResizeObserver
Nie odbudowuj podziału bezwarunkowo przy każdej zaobserwowanej zmianie wysokości. Sama odbudowa może wpłynąć na układ. MDN dokumentuje cykle ResizeObserver i wyjaśnia, że aby uniknąć pętli sprzężenia zwrotnego, trzeba kontrolować zależność; odroczenie pracy do kolejnej klatki nie usuwa źródła nieskończonego cyklu. Porównuj istotne dane wejściowe przed zażądaniem kolejnej odbudowy. Błędy obserwacji ResizeObserver
Jeśli tekst nagłówka się zmieni, przywróć poprzedni podział przed zastąpieniem treści, a następnie zainicjalizuj nową instancję na podstawie nowego tekstu źródłowego. GSAP dokumentuje, że revert() przywraca oryginalną treść sprzed podziału. Edytowanie wygenerowanych kontenerów, a następnie przywracanie tekstu grozi utratą tych zmian. revert()
Sprawdzaj zawijanie bez zmiany kształtowania tekstu w przeglądarce
Otwórz lokalny podgląd w przeglądarce na Macu i powoli zmieniaj rozmiar okna, a następnie zwolnij uchwyt. Po zakończeniu odbudowy i zanikania porównaj ostatnie słowo w każdym wierszu obu kopii. Powtórz to, gdy kontener jest ograniczony maksymalną szerokością oraz gdy jest na tyle wąski, że musi się zmniejszyć. Kliknij Toggle spacing przy każdym rozmiarze.
Jeśli kopie się różnią, wykonaj kolejno następujące czynności diagnostyczne:
- Sprawdź, czy obie kopie mają tę samą dostępną szerokość i obliczoną typografię.
- Odbuduj podział przy aktualnym rozmiarze. Jeśli rozwiąże to problem, sprawdź, którego wyzwalacza brakowało.
- Jeśli różnica pozostanie, usuń style z wygenerowanych kontenerów wierszy i sprawdź ponownie.
- Przywróć niepodzielony tekst i sprawdź, czy podstawowe reguły CSS dają zamierzone zawijanie.
- Zmieniaj po jednym parametrze układu naraz, aż różnicę da się powtórzyć.
Pozostaw kształtowanie znaków silnikowi tekstowemu przeglądarki. W3C określa sytuacje, w których kształtowanie powinno być kontynuowane przez granice elementów śródliniowych, oraz te, w których powinno zostać przerwane, w tym przypadki rozdzielenia przez dopełnienie, obramowanie lub margines elementu śródliniowego. Oznacza to, że style kontenerów mogą wpływać na to, co jest mierzone. Nie dodawaj odstępów między osobnymi polami znaków tylko po to, by odtworzyć wcześniejszy zrzut ekranu. Kształtowanie na granicach elementów
Nie licz wierszy wizualnych, dzieląc innerText przy znakach nowej linii. WHATWG definiuje innerText jako renderowany tekst z regułami zbierania tekstu, jawnych podziałów i granic strukturalnych; nie zwraca tablicy wierszy zawiniętych automatycznie. Jako punktu odniesienia używaj niepodzielonego tekstu renderowanego przez przeglądarkę. Właściwości innerText i outerText
Przestrzegaj udokumentowanych ograniczeń biblioteki: GSAP odradza używanie text-wrap: balance z podziałem i informuje, że SplitText nie jest przeznaczony dla węzłów tekstowych SVG. W przypadku wyśrodkowanych optycznie nagłówków pozostaw tekst niepodzielony i animuj cały element; do tworzenia kontenerów wierszy używaj zwykłego zawijania w elemencie tekstowym HTML. Wskazówki i ograniczenia SplitText
Zakończ, gdy podzielona kopia będzie zgodna z niepodzieloną przy faktycznych zmianach szerokości i typografii. Umieszczaj jawne odbudowy blisko zmian, które ich wymagają, zachowaj tekst porównawczy podczas diagnozowania, a przed dodaniem nagłówka do gotowej strony usuń tymczasową kopię i obramowania wierszy.
Źródła
- SplitText — GSAP
- SplitText.create() — GSAP
- split() — GSAP
- revert() — GSAP
- Instalacja — GSAP
- gsap.from() — GSAP
- Funkcja CSS clamp() — MDN Web Docs
- FontFaceSet: właściwość ready — MDN Web Docs
- Document: właściwość fonts — MDN Web Docs
- ResizeObserver — MDN Web Docs
- CSS Text Module Level 3 — W3C
- Standard HTML: właściwości innerText i outerText — WHATWG