second gate studio blog

Autorem tego bloga jest zx. Na stronie zajmuję się szeroko pojętym user-experience i takoż pojętym designem. Piszę o technologii, pokazuję rzeczy zaprojektowane z wyczuciem, dbałością o szczegóły i szukam inspiracji w każdej możliwej dziedzinie. Kontakt.

Wpis dodany roku w kategoriach HTML, CSS, JS, Techblog, Typografia i otagowany słowami: css, czcionka, Trackback.

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).

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.

Komentarze

pecet 15:19:00 | 23 stycznia 2011

Szkoda że wybraną przez ciebie czcionkę czyta się bardzo źle przez to "ściśnienie" literek.

zx 15:19:42 | 23 stycznia 2011

pecet: Ja eksperymentuje. ;) Gdzieś muszę.

WRB 15:57:42 | 23 stycznia 2011

Ciekawy i pomocny materiał. Dzięki.

bobiko 18:34:12 | 23 stycznia 2011

Ale co daje flush w przypadku nas, Joggerowiczów? :)

zx 19:06:12 | 23 stycznia 2011

Sami tego nie zrobimy, ale administracja mogłaby uwzględnić przy pracach nad Jogger 3.

Bastet-milo 21:53:27 | 23 stycznia 2011

Świetny tekst!

jaro 09:56:20 | 24 stycznia 2011

dzięki, tego mi brakowało, zwłaszcza fragmentu odnośnie zachowania przed pobraniem fonta.

css3.pl 09:56:39 | 24 stycznia 2011

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.

Grzegorz 18:20:55 | 24 stycznia 2011

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.

zx 09:33:38 | 25 stycznia 2011

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.

SebaS86 13:51:12 | 29 stycznia 2011

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!

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ę.

Grzegorz 09:45:26 | 31 stycznia 2011

Czy rezygnując z src: local('☺') wymuszę stosowanie mojej czcionki, nawet jeśli takowa jest zainstalowana w systemie?

zx 19:30:10 | 31 stycznia 2011

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.

Tomek 21:52:52 | 30 września 2011

Jak można wybrnąć z tego problemu dot Firefoxa. plik z czcionką zainstalowany jest na innym serwerze a nie mam dostępu do .htacces ?

zx 00:06:41 | 01 października 2011

Tomek: Nie mam pojęcia szczerze mówiąc. Póki .htaccess to jedyne co udało mi się znaleźć.

Kamil 09:14:37 | 19 lutego 2012

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.