Pobrany font może pozostać nieużywany, ponieważ CSS wybiera inny krój, tekst wykracza poza zakres obsługiwanych znaków albo minęło już okno wyświetlania. Na Macu zacznij od sprawdzenia fontu, który faktycznie renderuje jedną etykietę, a następnie prześledź wstecz proces wyboru i ładowania.

Ten poradnik jest przeznaczony dla osoby utrzymującej stronę internetową, która widzi udane żądanie fontu, ale nadal widzi tekst zastępczy. Do opisanych kroków kontrolnych użyj Chrome w systemie macOS. Przykładowa etykieta Panel 204 i nazwa rodziny Sample Sans ilustrują diagnozę; nie opisują żadnej konkretnej strony.

Co właściwie potwierdza udane pobranie?

Traktuj diagnozę jako cztery osobne pytania: Czy zasób został pobrany? Czy zarejestrowano użyteczny krój? Czy CSS wybrał ten krój dla tych znaków? Czy moduł renderujący go narysował? Wstępne ładowanie fontu rozpoczyna pobieranie z wyprzedzeniem; jego obecność nie wskazuje, który font dostarcza widoczny tekst. MDN: rel="preload"

Dopasowywanie fontów odbywa się na podstawie tekstu, a nie samych pobranych plików. Przeglądarka uwzględnia żądane rodziny i właściwości fontu, a następnie sprawdza obsługę znaków. Dlatego jedna etykieta może używać kilku fontów, a inna część strony może powodować pobranie fontu, które niewiele mówi o docelowej etykiecie. W3C: CSS Fonts Module Level 4, dopasowywanie fontów

Skorzystaj z tej tabeli decyzyjnej, aby wybrać kolejny punkt kontroli. To pomoc diagnostyczna oparta na udokumentowanych granicach ładowania i dopasowywania, a nie zapis wyników pomiarów przeglądarki.

Obserwacja Kolejny punkt kontroli Co pomaga rozróżnić
Obliczona rodzina różni się od zamierzonej Prześledź zwycięską deklarację CSS Problem kaskady lub wskazania elementu
Obliczona rodzina jest prawidłowa, ale renderowany font jest inny Sprawdź deskryptory kroju i obsługiwane znaki Problem wyboru lub użycia fontu zastępczego
JavaScript zgłasza załadowany krój, ale nie ma go w zestawie fontów dokumentu Sprawdź kod rejestracji Ładowanie bez rejestracji
Font pojawia się po ponownym załadowaniu, ale nie przy pierwszej wizycie Sprawdź font-display i czas ładowania Zachowanie związane z oknem wyświetlania
Zwykły tekst działa, a tekst na canvasie pozostaje bez zmian Sprawdź kolejność rysowania i ustawienia fontu canvasu Osobna operacja rysowania

Który font faktycznie rysuje docelową etykietę?

Na stronie, której dotyczy problem, naciśnij Command + Shift + C i zaznacz tekst. W panelu Elements wybierz najmniejszy element zawierający problematyczną etykietę. Otwórz Computed, a następnie przewiń do Rendered Fonts. Chrome wskazuje ten widok jako miejsce, w którym można sprawdzić fonty dostarczające renderowany tekst. Chrome DevTools: dokumentacja funkcji CSS, Chrome DevTools: stosowanie innych efektów

Zapisz renderowany krój oraz informację, czy pochodzi z lokalnego źródła, czy z zasobu sieciowego. Zapisz też obliczone wartości font-family, font-weight i font-style. Obliczona rodzina to żądany stos, a wynik renderowanych fontów wskazuje, które z nich dostarczyły glify. Samo podobieństwo wyglądu jest słabym dowodem, ponieważ dwa kroje mogą wyglądać podobnie. Chrome DevTools: Jaki to font?

Jeśli zamierzony krój pojawia się w problematycznym tekście, zbadaj konkretną różnicę w wyglądzie, na przykład grubość lub funkcje typograficzne. Jeśli go brakuje, kontynuuj poniżej. Podczas testów nie zmieniaj oryginalnego tekstu ani widocznego obszaru, aby można było porównywać kolejne obserwacje.

Czy efektywny CSS żąda zamierzonego kroju?

W panelu Computed sprawdź efektywne właściwości fontu, a następnie użyj panelu Styles, aby znaleźć ich deklaracje. Chrome rozróżnia te widoki: Styles obejmuje nadpisane deklaracje, a Computed pokazuje faktycznie zastosowane wartości. Jeśli karta zawiera kilka etykiet, sprawdź element zawierający tekst; deklaracja fontu rodzica nie jest wystarczającym dowodem dotyczącym elementu potomnego. Chrome DevTools: dokumentacja funkcji CSS

Sprawdź zwycięcze ustawienie skrótowe font oraz poszczególne właściwości. Na przykład font: 16px sans-serif wybiera ogólną rodzinę i resetuje pominięte składniki skrótu, w tym grubość i styl. Resetuje też właściwości takie jak font-feature-settings i font-variation-settings. Popraw deklarację odpowiedzialną za nieoczekiwaną wartość, a następnie sprawdź wynik ponownie. MDN: font

Następnie porównaj żądaną rodzinę z deskryptorem font-family w odpowiedniej regule @font-face. Ten deskryptor definiuje nazwę rodziny CSS służącą do odwoływania się do kroju; nazwa pliku nie jest nazwą, której należy użyć w stosie fontów elementu. Sprawdź regułę dostarczoną przeglądarce, w tym jej src, grubość, styl i wszelkie zadeklarowane zakresy. MDN: @font-face

Obsługiwany zakres grubości fontu zmiennego można wyrazić za pomocą dwóch wartości, natomiast dla kroju statycznego można zadeklarować jedną grubość. Dopasuj te deskryptory do rzeczywistego zasobu. Niezgodność warto zbadać, ale sama w sobie nie wyjaśnia użycia fontu zastępczego: dopasowywanie fontów uwzględnia alternatywy, gdy dokładny styl jest niedostępny. MDN: @font-face, W3C: dopasowywanie stylów fontów

Czy lokalny font ma pierwszeństwo?

Sprawdź, czy src zawiera alternatywę local(). Na Macu z zainstalowanym tym fontem przeglądarka może użyć lokalnej kopii, podczas gdy osobno wstępnie załadowany font internetowy pozostanie nieużywany. Aby wyizolować tę sytuację w Chrome, otwórz panel Rendering, włącz Disable local fonts i odśwież stronę. Porównaj Rendered Fonts przed i po teście, a następnie przywróć to ustawienie. Test dotyczy źródeł local() w regułach @font-face. Chrome DevTools: stosowanie innych efektów

Czy krój został załadowany i zarejestrowany we właściwym dokumencie?

Krój utworzony za pomocą new FontFace() może zostać załadowany, zanim zostanie dodany do zestawu fontów. Aby można było go użyć do renderowania dokumentu, należy dodać go do document.fonts. Sprawdź w ścieżce ładowania aplikacji, czy wykonywane są obie operacje; samo rozstrzygnięcie obietnicy ładowania kroju nie kończy rejestracji. MDN: CSS Font Loading API

Poniższy kompletny skrypt diagnostyczny wyświetla kroje zarejestrowane w bieżącym dokumencie. Uruchom go w konsoli kontekstu strony, której dotyczy problem. Odczytuje zestaw bez inicjowania ładowania i zmieniania stylów; nie wskazuje renderowanych glifów. Jego zachowanie zależne od przeglądarki nie zostało tu sprawdzone.

(() => {
  const faces = Array.from(document.fonts, face => ({
    family: face.family,
    weight: face.weight,
    style: face.style,
    stretch: face.stretch,
    unicodeRange: face.unicodeRange,
    status: face.status
  }));

  console.table(faces);
  console.log("Registered face count:", faces.length);
})();

Użyj tego zestawienia, aby odróżnić brak rejestracji od zarejestrowanego, lecz nieużywanego kroju. Jeśli wpis ma status error, zbadaj błąd ładowania, zanim zaczniesz zmieniać typografię. Wpis loaded potwierdza stan ładowania, ale wybór kroju nadal zależy od elementu i tekstu. MDN: CSS Font Loading API

Nie traktuj document.fonts.check() jako dowodu renderowania. Może zwrócić true nawet dla nieistniejącej rodziny. Opcjonalny argument tekstowy zawęża dopasowanie według zadeklarowanych zakresów Unicode i nie sprawdza obsługi poszczególnych glifów. Podobnie document.fonts.ready rozstrzyga się po załadowaniu i ułożeniu używanych fontów; nie poświadcza, że renderowano każdy zadeklarowany krój. MDN: FontFaceSet.check(), MDN: Document.fonts

Czy font obsługuje testowane znaki?

Sprawdź zarówno CSS-owy deskryptor unicode-range, jak i rzeczywisty zasób fontu. Deskryptor kontroluje, które znaki mogą używać kroju. Rozszerzenie deskryptora nie utworzy glifów, których brakuje w pliku: mapa znaków fontu nadal bierze udział w dopasowywaniu. MDN: unicode-range, W3C: dopasowywanie stylów fontów

Rozważ przykładową regułę ograniczoną do zakresu U+0030-0039. W napisie Panel 204 mieszczą się w nim tylko 2, 0 i 4. Litery i spacja już nie. Pobranie wywołane przez cyfry nie potwierdza więc, że font potrafi wyświetlić całą etykietę. MDN opisuje, że napotkanie znaku objętego zakresem może spowodować pobranie całego zasobu fontu. MDN: unicode-range

Ten samodzielny przykład JavaScript pokazuje tę różnicę. Działa w konsoli przeglądarki lub Node.js bez dodatkowej konfiguracji. Deterministyczne obliczenie zakresu wykonano dla pokazanego przykładu.

const text = "Panel 204";
const rows = Array.from(text, character => {
  const value = character.codePointAt(0);
  return {
    character,
    codePoint: "U+" + value.toString(16).toUpperCase().padStart(4, "0"),
    inDeclaredRange: value >= 0x30 && value <= 0x39
  };
});

console.table(rows);

Jeśli zakres nie obejmuje potrzebnych znaków, popraw nieprawidłowy deskryptor lub dostarcz podzbiór, który je zawiera. Podczas sprawdzania wyniku zachowaj oryginalny tekst powodujący problem. Nie zakładaj, że iterowanie po ciągu znaków pozwala przetestować składanie glifów: sekwencje znaków łączonych wymagają obsługi klastrów, a standard uwzględnia informacje o składaniu, gdy jest to potrzebne. Podczas porównywania renderowanego wyniku zachowaj całe sekwencje. W3C: dopasowywanie fontów i klastrów znaków

Czy font nie zdążył w oknie wyświetlania?

Sprawdź font-display, jeśli rodzina i zakres obsługi znaków wyglądają poprawnie. optional ma niezwykle krótki okres blokowania i nie ma okresu zamiany. fallback ma krótki okres zamiany. Zasób, który dotrze po upływie odpowiedniego okna, może więc pozostawić widoczny tekst zastępczy podczas tego wczytania strony. swap pozwala na nieograniczony okres zamiany po początkowym okresie blokowania. MDN: font-display

Aby przeprowadzić kontrolowaną diagnozę, tymczasowo zmień problematyczną regułę na font-display: swap w arkuszu stylów dostarczanym przez serwer i powtórz wczytanie w warunkach początkowych. Jeśli po załadowaniu pojawi się krój, czas wczytywania jest prawdopodobnym wyjaśnieniem. Zanim zachowasz to ustawienie, zdecyduj, czy późniejsza zmiana wyglądu strony jest odpowiednia. Powtórz zarówno wstępne wczytanie, jak i odświeżenie z pamięci podręcznej; wynik z pamięci podręcznej sam w sobie nie odtwarza pierwotnego czasu dotarcia fontu.

Co się zmienia, gdy tekst rysuje biblioteka lub canvas?

Jeśli strona używa już Font Face Observer, sprawdź obserwowaną rodzinę oraz jej opcje weight, style i stretch. Dokumentacja opisuje tę bibliotekę jako mechanizm ładujący i monitorujący, wymaga standardowych reguł @font-face oraz niestandardowego ciągu testowego, gdy font nie zawiera domyślnych znaków testowych. Domyślny limit czasu wynosi trzy sekundy. Przekroczenie limitu czasu obserwatora i okno font-display przeglądarki to odrębne warunki. Dokumentacja Font Face Observer

Wniosek diagnostyczny: po komunikacie obserwatora o powodzeniu należy sprawdzić docelowy element. Monitorowanie dostępności jednego kroju nie potwierdza, że zwycięski CSS elementu żąda właśnie tego kroju. Instalowanie kolejnego mechanizmu ładującego niewiele pomoże, gdy nadal nie wiadomo, który krój został wyrenderowany.

Canvas stanowi osobną granicę rysowania. Kontekst rysowania ma własne ustawienie font, początkowo 10px sans-serif; nieprawidłowe przypisanie jest ignorowane. Ustawienie rodziny CSS na elemencie canvas nie wystarcza więc, by potwierdzić font kontekstu. Sprawdź wartość przypisaną kontekstowi rysowania oraz kolejność operacji ładowania i rysowania. WHATWG: style tekstu na canvasie

W przypadku tekstu na canvasie poczekaj, aż zamierzony, zarejestrowany krój zostanie załadowany, ustaw font kontekstu, a następnie narysuj ponownie problematyczną scenę, używając zwykłej procedury rysowania aplikacji. Piksele narysowane wcześniej nie zmienią kroju po załadowaniu fontu. Przygotowanie tekstu na canvasie używa również hipotetycznego, nieskończenie szerokiego pola wiersza, dlatego udany test na canvasie nie potwierdza, że etykieta o ograniczonej szerokości na stronie będzie łamać wiersze w ten sam sposób. WHATWG: przygotowanie tekstu i jego rysowanie

Jak potwierdzić naprawę?

Wróć do pierwotnej etykiety i powtórz obserwację, która ujawniła problem. Sprawdź żądane właściwości, renderowany krój i odpowiednie znaki w pierwotnych warunkach ładowania. W przypadku canvasu przed porównaniem ponownie narysuj scenę. Prowadź zwięzły zapis elementu, żądanych właściwości, faktycznego renderowanego kroju, zasobu i zmiany, która przyniosła efekt; dzięki temu diagnozę można odtworzyć.

Zakończ, gdy potrafisz wyjaśnić, dlaczego font nie był używany, i pokazać zamierzony wynik dla problematycznego tekstu. Poprawiona deklaracja rodziny, prawidłowy podzbiór, zarejestrowany krój, odpowiednia polityka wyświetlania lub ponowne rysowanie we właściwym momencie dotyczą różnych etapów. Wybierz naprawę potwierdzoną obserwacjami.

Źródła