Kompletna instrukcja używania @font-face
Designerzy stron internetowych dostali do ręki potężne narzędzie. Mogą teraz niemal dowolnie przebierać w potężnej bazie rozmaitych fontów i używać ich na stronach internetowych. Do tej pory byliśmy ograniczeni do tego, co na swoim komputerze zainstalowane miał użytkownik, więc – w praktyce – do fontów, które dostępne były standardowo z systemem operacyjnym. Trochę ograniczało to pole do popisu, zwłaszcza kiedy chcieliśmy wyróżnić stronę. Było co prawda kilka technik, które pozwalały używać w jakimś stopniu własnych fontów – umieszczanie ich w obrazkach, albo wyświetlanie przy połączeniu JavaScript i Flasha. Tyle, że nie było to wygodne rozwiązanie. Nawet nie tyle dla twórców, co dla użytkowników.
Całe szczęście, ktoś to zauważył i w CSS3 (właściwie wcześniej, jednak przeglądarki nie wspierały ówczesnych rozwiązań) mamy możliwość osadzania na stronach dowolnego fontu.
Znajdź swój krój pisma
Zaczynamy oczywiście od znalezienia kroju pisma, który będziemy wykorzystywać na stronie. Trzeba jednak być bardzo ostrożnym. Wszystko, co zamieszczamy na stronie internetowej może być w łatwy sposób pobrane przez użytkownika, choć lepiej powiedzieć, że jest już pobrane z chwilą wejścia na stronę. O ile twórcy darmowych fontów specjalnie się tym nie przejmują, tak domy, które swoje wyroby sprzedają często za kilka tysięcy złotych, nie chcą, żeby ich materiały były łatwo dostępne dla każdego. Koniecznie więc zwróćmy uwagę na licencję, bo nie wszyscy twórcy fontów godzą się na używanie ich na stronach. Do tego, jeśli już się godzą, najczęściej pozwalają zamieścić na stronie wyłącznie plik dostarczony przez nich samych.
Jako projektanci dostaliśmy w swoje łapki większą moc, a większa moc, to większa odpowiedzialność.
;) Używając własnych fontów musimy pamiętać, że nie zawsze będą one renderowane przez przeglądarkę tak, jakby nam się wydawało. Na stronach bardzo często używa się dość małych rozmiarów tekstu, a ciężko znaleźć dobry font, który będzie wygodny w czytaniu przy dłuższych tekstach. Nie możemy utrudniać czytania!
Umieść go na stronie
@font-face {
font-weight: normal;
font-style: normal;
font-variant: normal;
font-family: 'MojFont';
src: url('mojFont.eot?') format('eot'),
url('mojFont.woff') format('woff'),
url('mojFont.ttf') format('truetype'),
url('mojFont.svg#svgFontName') format('svg');
}
Powyższa metoda została opracowana przez Ethana Dunhama. Zasada działania jest bardzo prosta. W pierwszej linijce deklarujemy użycie własnego pliku z krojem pisma. W drugiej, trzeciej i czwartej określamy styl. Na stronach najczęściej używamy tekstu pogrubionego i pochyłego. Pamiętajmy, że każdy styl umieszczony jest w odrębnym pliku, więc chcąc ich używać, musimy ponownie zadeklarować użycie fontu o tej samej nazwie, ale innym stylu. Jeżeli nie zdefiniujemy fontów dla danego stylu, a zechcemy go potem użyć, niektóre przeglądarki spróbują same przerobić tekst (pochylić bądź pogrubić). Najczęściej wygląda to fatalnie, ale czasami można wykorzystać – szczególnie, kiedy wybrany przez nas font nie posiada np. stylu pochyłego. Poniżej przykład dla pogrubienia.
@font-face {
font-weight: bold;
font-style: normal;
font-variant: normal;
font-family: 'MojFont';
src: url('mojFont.eot?') format('eot'),
url('mojFont.woff') format('woff'),
url('mojFont.ttf') format('truetype'),
url('mojFont.svg#svgFontName') format('svg');
}
W kolejnych liniach informujemy przeglądarkę gdzie znajdują się potrzebne pliki. Niestety grupa opracowująca standard dała ciała i znów każdy silnik renderujący preferuje inny format. Możliwe, że sytuacja wyklaruje się sama i w przeciągu kilku miesięcy będziemy mogli używać jednego.
Ważne jest, żeby w pierwszej kolejności podać ścieżkę dostępu do pliku .eot, czyli formatu wykorzystywanego przez Internet Explorer. W innym przypadku IE pogubi się i nie wyświetli zadeklarowanego fonta. Zauważcie, że na końcu URLa trzeba postawić znak zapytania. To taki mały hack, który powoduje, że IE myśli, że dalsza część deklaracji fonta, to tak zwany query string
, a musi tak myśleć, bo jak tylko zobaczy, że deklarujemy więcej niż jeden format, to głupieje i nie wyświetli nic.
No dobra, ale skąd wziąć te wszystkie formaty? Jeśli zakupiliśmy font z licencją na używanie go na stronie, prawdopodobnie dostaniemy odpowiednie pliki razem z czcionką. Jeśli nie, możemy przekonwertować posiadany .otf lub .ttf sami. Oczywiście można to wszystko robić ręcznie przy użyciu odpowiednich programów, ale myślę, że to strata czasu jeśli posiadamy dostęp do narzędzia, które odwali brudną robotę za nas. Font Squirrel przygotował świetny @font-face generator, który automatycznie wygeneruje wszystkie potrzebne pliki.
A jakich formatów potrzebujemy? W tej chwili kilku. Internet Explorer toleruje tylko swój Embedded OpenType, który Microsoft próbuje przeforsować od dawna, ale który nigdy nie zyskał popularności. Pozostałe przeglądarki chętnie przyjmą .ttf. I w zasadzie tyle by wystarczyło. Jednak jeśli chcemy żeby wybrane czcionki wyświetlały się również na iPhone musimy rozważyć pewną kwestię. Starsza wersja oprogramowania obsługuje tylko fonty w formacie .svg. Generator oczywiście zaproponuje nam i ten format, jednak radziłbym go nie używać. Najnowsza wersja oprogramowania dla iPhone wspiera już standardowe .ttf, a poprzednie rozwiązanie powodowało też kilka błędów (które mogły nawet zawiesić Safari).
Po wrzuceniu plików na serwer wypadałoby jeszcze dodać wpisy mime-type, żeby wiadomo było z jakim typem danych przeglądarka ma do czynienia. W Apache najprościej utworzyć plik .htaccess na przykład w katalogu z fontami.
# dodaj mime-type fontów
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
Zwrócę szczególną uwagę na Firefoxa, który nie wyświetla fontów z plików znajdującym się na innym serwerze niż strona. Można to jednak łatwo obejść dodając w pliku .htaccess, wpis o poniższej treści. W miejsce * można wstawić domenę, wtedy pliki dostępne będą tylko dla niej.
# zezwól na używanie fontów z zewnętrznych domen
<FilesMatch "\.(ttf|otf|eot)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>
Jest jeszcze kwestia WOFF, którego użyłem w kodzie powyżej. Jest to format przygotowany specjalnie dla sieci. Ja sam jestem przeciwnikiem rozwiązań, które mają zastosowanie tylko w jednym medium, jednak wszystko wskazuje na to, że już za kilka miesięcy wszystkie przeglądarki (łącznie z Internet Explorer 9) będą obsługiwać ten właśnie format, tym bardziej, że autorzy fontów patrzą na niego przychylnie. Głównie za sprawą metadanych, które zawarte w pliku informują kto jest autorem kroju, co ma być jakąś formą ochrony przed piractwem. Plusem na pewno jest to, że .woff jest bezstratnie skompresowany, ale w praktyce jest to tylko kontener na dane zawarte w OpenType czy TrueType.
Jako ciekawostkę dodam, że Mozilla planuje umożliwić twórcom stron dostęp do zaawansowanych własności OpenType, czyli pomoże zadbać o poprawną typografię w sieci. Te zaawansowane własności
to na przykład ułamki, alternatywne glyphy, czy poprawnie zapisane zbitki liter (np. fi
w którym często kropka nad i brzydko łączy się z literą f
).
- Ethan Dunham: The New Bulletproof @Font-Face Syntax
- Tim Brown: How to use CSS @font-face
- Metal Toad Media: How to use @font-face to avoid faux-italic and bold browser styles
- Paul Irish: @font-face gotchas
- Mozilla: Web Open Font Format for Firefox 3.6
Zoptymalizuj działanie
Fonty to dodatkowe dane do pobrania. Trzeba więc zrobić wszystko, żeby zajmowały jak najmniej. Przy generowaniu potrzebnych plików na Font Squirrel warto zaznaczyć opcję Expert
i sprawdzić czego można się pozbyć, żeby zmniejszyć wielkość pliku wynikowego. Nie potrzebujemy oznaczeń walut albo symboli matematycznych? Usuwamy je odznaczając w sekcji Subsetting
.
Kolejną metodą na zmniejszenie pliku jest kompresja. Fonty to w większości tekst, więc kompresują się bardzo dobrze. Można uzyskać nawet 46% mniej danych do przesłania. Pomijając oczywiście format WOFF, który jest skompresowany z założenia. Do utworzonego wcześniej pliku .htaccess dodajemy:
# wlacz kompresje
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE font/otf
Kolejnym problemem jest zachowanie przeglądarek do momentu w którym pliki fontów zostaną pobrane. Opera, Firefox i Internet Explorer wyświetlą najpierw tekst zwykłą czcionką, a dopiero gdy zostanie pobrany właściwy plik, zmienią ją na tę zadeklarowaną w @font-face. Przeglądarki oparte na Webkit dla odmiany nie wyświetlą tekstu w ogóle zanim nie pobiorą plików czcionek. I to wszystko na oczach użytkownika. Czas oczekiwania na pojawienie się tekstu we właściwym foncie nazwano FOUT i opracowano kilka metod na jego zminimalizowanie.
Przede wszystkim pamiętajmy, że pliki czcionek należy cache'ować. Niech przeglądarka po pobraniu ich zapisze je sobie w pamięci podręcznej, dzięki czemu użytkownik nie będzie musiał ich pobierać za każdym razem kiedy wejdzie na naszą stronę. Żeby przeglądarka wiedziała jak długo ma trzymać taki plik w pamięci należy przesłać jej odpowiedni nagłówek. Do powyższego pliku .htaccess dopisujemy dwie linijki (w tym przypadku pliki zostaną odświeżone dopiero po dwóch latach):
# wlacz cache
ExpiresActive On
ExpiresDefault "access plus 2 years"
Teoretycznie można również zakodować czcionkę w Base64 i wkleić ją bezpośrednio do arkusza stylów, ale mam mieszane uczucia co do tego rozwiązania, szczególnie w sytuacji, gdy musimy używać wielu formatów. Być może w niedalekiej przyszłości właśnie to okaże się najlepszym rozwiązaniem.
Kolejnym trikiem jest flushowanie treści strony jak najwcześniej. W skrócie – kiedy przeglądarka wysyła żądanie do serwera, ten mieli stronę, a przeglądarka czeka sobie na wynik i dopiero kiedy otrzyma odpowiednio dużo danych zaczyna renderowanie. Oznacza to również, że przeglądarka często nie zdąży pobrać plików z fontami zanim wyświetli jakiś tekst. Z pomocą PHP możemy wymusić wysłanie przez serwer danych jak najszybciej. Wtedy przeglądarka zyska czas na wysłanie kolejnego żądania i pobrania dodatkowych plików. Najlepiej to zrobić jeszcze przed właściwą treścią strony:
</head>
<?php flush(); ?>
<body>
Do tego warto przenieść pliki fontów pod inną domenę niż właściwa strona. Umożliwi to przeglądarce nawiązanie równoległego połączenia, dzięki czemu strona i fonty będą pobierały się w tym samym czasie. Trzeba też pamiętać, żeby nie deklarować nieużywanych fontów, ponieważ IE i tak będzie chciał je pobrać. Inne przeglądarki pobierają tylko fonty, które zostały użyte gdzieś na stronie. Oprócz tego przed odnośnikiem do pliku CSS nie powinien znaleźć się żaden tag <script> – to również zawiesi ładowanie strony pod IE.
- Sitepoint: Web Site Optimization: 13 Simple Steps
- Yahoo Developer Network: Best Practices for Speeding Up Your Web Site
- Kalid Azad: How To Optimize Your Site With GZIP Compression
- Stoyan Stefanov: Gzip your @font-face files
- Stoyan Stefanov: @font-face gzipping – take II
- Aaron Peters: Better @font-face performance: flushing the document early
- Paul Irish: Fighting the @font-face FOUT
- Mark Nottingham: Caching Tutorial
Komentarze
Szkoda że wybraną przez ciebie czcionkę czyta się bardzo źle przez to "ściśnienie" literek.
pecet: Ja eksperymentuje. ;) Gdzieś muszę.
Ciekawy i pomocny materiał. Dzięki.
Ale co daje flush w przypadku nas, Joggerowiczów? :)
Sami tego nie zrobimy, ale administracja mogłaby uwzględnić przy pracach nad Jogger 3.
Świetny tekst!
dzięki, tego mi brakowało, zwłaszcza fragmentu odnośnie zachowania przed pobraniem fonta.
Dlaczego używasz na przemian "font" i "czcionka"? wypadałoby zdecydować się na jedną formę, najlepiej font.
Zapis który proponujesz:
# wlacz cache
ExpiresActive On
ExpiresDefault "access plus 2 years"
Spowoduje, że wszystkie pliki (nie tylko fonty) będą aktualizowane co dwa lata. Należałoby napisać np:
ExpiresByType font/ttf "access plus 2 year"
ExpiresByType font/woff "access plus 2 year"
Co oznacza, że będzie to dotyczyło tylko plików typu ttf i woff.
Czcionek dobrze poszukać na dafont.com, zaś instrukcja dotycząca @font-face od dłuższego casu jest dostępna z poziomu MDN i Mozilla Hacks.
Za to część dotyczącą .htaccess uważam za bardzo pomocą.
Ze swojej strony dodam odnośnik do ciekawego narzędzia, które pozwala przekonwertować osadzonego fonta woff do otf lub ttf -- woff2otf. Przydaje się, gdy chcemy pobrać używalnego fonta ;-)
A także polecę program FontLab Studio, w którym łatwo wygenerujemy polskie ogonki dla czcionek z akcentami, ale bez polskich znaków diakrytycznych.
css3.pl: Dla różnorodności. Wiem, że to nie poprawne, ale szczerze mówiąc tylko jeśli zajrzymy do słownika. To, co uznane i zrozumiane popularnie, jest już poprawne.
Ja proponuję plik .htaccess utworzyć w katalogu z fontami, wtedy tylko fonty będą cache'owane. WOFF nie ma jeszcze ustalonego mime-type.
Zgadza się, niestety i ta strona nie ustrzegła się tego błędu. ;)
Niezły wpis, na pewno się przyda tym bardziej, że sporo osób (klientów, przełożonych) rzuciło się na tę technologię.
Czy rezygnując z src: local('☺') wymuszę stosowanie mojej czcionki, nawet jeśli takowa jest zainstalowana w systemie?
Grzegorz: Jeśli zamiast emotka wpiszesz nazwę fontu, taką jaki ten ma w systemie, to przeglądarka najpierw postara się użyć pliku już zainstalowanego na komputerze. Jeśli użyjesz tam buźki, to przeglądarka oleje wszystko co jest na komputerze i wymusi używanie zadeklarowanego w CSSie pliku.
Jak można wybrnąć z tego problemu dot Firefoxa. plik z czcionką zainstalowany jest na innym serwerze a nie mam dostępu do .htacces ?
Tomek: Nie mam pojęcia szczerze mówiąc. Póki .htaccess to jedyne co udało mi się znaleźć.
Ja dopisałbym jeszcze że przeglądarki interpretują czcionki pierwsze z brzegu. Czyli pierwsza po eot którą zadeklarujemy będzie czytana przez wszystkie inne przeglądarki poza ie. Przeglądarka czytając formaty bierze pierwszy z brzegu który jej odpowiada więc generalnie nie ma sensu stosować woff po otf czy ttf gdyż nie zostanie on przeczytany. Inna kwestia kiedy osadzimy kolejno svg, woff i na końcu ttf lub otf. Wówczas webkity pobiorą svg i wyrenderują znakomitą jakościowo czcionkę, firefox i ie 9 pominie svg i weźmie woff a w razie gdyby te rozwiązania nie zadziałały z pomocą przyjdzie true lub opentype.