Uwaga! Trwają prace nad nową wersją serwisu. Mogą występować przejściowe problemy z jego funkcjonowaniem. Przepraszam za niedogodności!
⛔ Potrzebujesz wsparcia? Oceny CV? A może Code Review? ✅ Dołącz do naszej społeczności na Discordzie!
Na początku nauki programowania korzystamy z fontów dostępnych w naszym systemie. Wkrótce jednak nabieramy ochoty na coś bardziej finezyjnego niż zwykły Arial czy Times New Roman. Dzięki temu artykułowi dowiesz się, jak zadbać o to, by fonty w naszym projekcie wyświetlały się na każdym urządzeniu w ten sam sposób.
Nie przedłużając, mamy co najmniej trzy sposoby „dodania” fontów do projektu:
Bez względu na to, skąd pobierasz fonty, zawsze sprawdź licencję, zwłaszcza jeśli tworzysz projekt komercyjny. Być może font trzeba będzie kupić.
Na potrzeby artykułu skorzystajmy z bezpłatnych fontów Google Fonts. Po upewnieniu się, że polskie znaki są obsługiwane, pobrałam kilka krojów fontu Overpass: thin, medium i bold oraz italic dla wszystkich trzech opcji.
Pliki pobierają się w formacie ZIP, dlatego trzeba je rozpakować i zapisać w katalogu naszego projektu, np. w podkatalogu fonts/Overpass. Overpass jest fontem zmiennym (ang. variable font), lecz ponieważ nie wszystkie aplikacje takie fonty wspierają, skorzystamy z opcji statycznej.
Jeżeli pobrany font masz tylko w jednym formacie – font Overpass z Google Fonts ma tylko format .ttf – warto zadbać o parę innych formatów ze względu na wsparcie przeglądarek. Do wygenerowania innych formatów użyjemy narzędzia online transfonter.org (jest też jeszcze np. Font Squirrel). Nowe pliki zapiszemy w tym samym podkatalogu, co resztę. U mnie to fonts/Overpass.
Struktura plików po małych porządkach prezentuje się u mnie w ten sposób:
W pliku CSS za pomocą reguły @font-face wskazujemy font i kroje, z których chcemy korzystać przy stylowaniu.
Uwaga: w tym miejscu osoby początkujące często tworzą nieoptymalne reguły. Sprawdź poniżej – jak sądzisz, co będzie lepsze?
Pisanie pełnej nazwy fontu i kroju (np. Overpass Regular Italic, Overpass Bold) przy każdym stylowanym elemencie:
h1 { font-family: 'Overpass Bold'; } h2 { font-family: 'Overpass Regular Italic'; }
Pisanie tylko nazwy rodziny (Overpass) i regulowanie reszty przez właściwości font-weight i font-style:
h1 { font-family: 'Overpass'; font-weight: bold; } h2 { font-family: 'Overpass'; font-weight: normal; font-style: italic; }
Ponieważ pierwsza opcja jest krótsza, może wydawać się lepsza, lecz widać tutaj co najmniej dwa niebezpieczeństwa:
Wracając do reguły @font-face, dla każdego kroju określamy:
Ustaliliśmy wyżej, że pierwszy zapis (pełna nazwa fontu i kroju) jest nieoptymalny, dlatego nie chcesz takiej reguły:
@font-face { font-family: 'Overpass Thin'; src: url(./fonts/overpass/Overpass-Thin.ttf) format('truetype'), url(./fonts/overpass/Overpass-Thin.eot), url(./fonts/overpass/Overpass-Thin.eot?#iefix) format('embedded-opentype'), url(./fonts/overpass/Overpass-Thin.woff2) format('woff2'), url(./fonts/overpass/Overpass-Thin.woff) format('woff'); }
Za to chcesz taką:
@font-face { font-family: 'Overpass'; src: url(./fonts/overpass/Overpass-Thin.ttf) format('truetype'), url(./fonts/overpass/Overpass-Thin.eot), url(./fonts/overpass/Overpass-Thin.eot?#iefix) format('embedded-opentype'), url(./fonts/overpass/Overpass-Thin.woff2) format('woff2'), url(./fonts/overpass/Overpass-Thin.woff) format('woff'); font-style: normal; font-weight: 100; }
Jak widzisz, grubość i styl fontu deklarujemy w osobnych właściwościach. Dzięki temu przeglądarka odwoła się do odpowiedniego kroju bez potrzeby używania przy stylowaniu pełnej nazwy, np. Overpass Thin.
Reguły @font-face dla pozostałych krojów fontu tworzymy analogicznie:
/* Font style: normal */ @font-face { font-family: 'Overpass'; src: url(./fonts/overpass/Overpass-Thin.ttf) format('truetype'), url(./fonts/overpass/Overpass-Thin.eot), url(./fonts/overpass/Overpass-Thin.eot?#iefix) format('embedded-opentype'), url(./fonts/overpass/Overpass-Thin.woff2) format('woff2'), url(./fonts/overpass/Overpass-Thin.woff) format('woff'); font-style: normal; font-weight: 100; } @font-face { font-family: 'Overpass'; src: url(./fonts/overpass/Overpass-Medium.ttf) format('truetype'), url(./fonts/overpass/Overpass-Medium.eot), url(./fonts/overpass/Overpass-Medium.eot?#iefix) format('embedded-opentype'), url(./fonts/overpass/Overpass-Medium.woff2) format('woff2'), url(./fonts/overpass/Overpass-Medium.woff) format('woff'); font-style: normal; font-weight: 500; } @font-face { font-family: 'Overpass'; src: url(./fonts/overpass/Overpass-Bold.ttf) format('truetype'), url(./fonts/overpass/Overpass-Bold.eot), url(./fonts/overpass/Overpass-Bold.eot?#iefix) format('embedded-opentype'), url(./fonts/overpass/Overpass-Bold.woff2) format('woff2'), url(./fonts/overpass/Overpass-Bold.woff) format('woff'); font-style: normal; font-weight: 700; } /* Font style: italic */ @font-face { font-family: 'Overpass'; src: url(./fonts/overpass/Overpass-ThinItalic.ttf) format('truetype'), url(./fonts/overpass/Overpass-ThinItalic.eot), url(./fonts/overpass/Overpass-ThinItalic.eot?#iefix) format('embedded-opentype'), url(./fonts/overpass/Overpass-ThinItalic.woff2) format('woff2'), url(./fonts/overpass/Overpass-ThinItalic.woff) format('woff'); font-style: italic; font-weight: 100; } @font-face { font-family: 'Overpass'; src: url(./fonts/overpass/Overpass-MediumItalic.ttf) format('truetype'), url(./fonts/overpass/Overpass-MediumItalic.eot), url(./fonts/overpass/Overpass-MediumItalic.eot?#iefix) format('embedded-opentype'), url(./fonts/overpass/Overpass-MediumItalic.woff2) format('woff2'), url(./fonts/overpass/Overpass-MediumItalic.woff) format('woff'); font-style: italic; font-weight: 500; } @font-face { font-family: 'Overpass'; src: url(./fonts/overpass/Overpass-BoldItalic.ttf) format('truetype'), url(./fonts/overpass/Overpass-BoldItalic.eot), url(./fonts/overpass/Overpass-BoldItalic.eot?#iefix) format('embedded-opentype'), url(./fonts/overpass/Overpass-BoldItalic.woff2) format('woff2'), url(./fonts/overpass/Overpass-BoldItalic.woff) format('woff'); font-style: italic; font-weight: 700; }
Teraz nasz font jest gotowy do użycia. Wystarczy ostylować elementy HTML w pliku CSS tak, jak to zwykle robimy. Jeżeli chcesz przetestować stworzone przez nas rozwiązanie, możesz przekopiować poniższy kod HTML:
<h1>Font Overpass</h1> <h2>Normal</h2> <ul class="normal"> <li class="normal--thin">Overpass Thin</li> <li class="normal--regular">Overpass Regular</li> <li class="normal--bold">Overpass Bold</li> </ul> <h2>Italic</h2> <ul class="italic"> <li class="italic--thin">Overpass Thin Italic</li> <li class="italic--regular">Overpass Regular Italic</li> <li class="italic--bold">Overpass Bold Italic</li> </ul>
Poniżej znajdziesz style z pliku CSS:
h1 { font-family: 'Overpass'; font-weight: bold; } h2 { font-family: 'Overpass'; font-weight: normal; } ul { font-size: 18px; } .normal--thin { font-family: 'Overpass'; font-weight: 100; } .normal--regular { font-family: 'Overpass'; font-weight: normal; } .normal--bold { font-family: 'Overpass'; font-weight: bold; } .italic--thin { font-family: 'Overpass'; font-style: italic; font-weight: 100; } .italic--regular { font-family: 'Overpass'; font-style: italic; font-weight: normal; } .italic--bold { font-family: 'Overpass'; font-style: italic; font-weight: bold; }
Reguły CSS można oczywiście skrócić, ponieważ wiele linii się powtarza, lecz obecna forma jest najbardziej czytelna w kontekście zrozumienia zagadnienia @font-face.
Uwaga: jeśli chcesz się upewnić, że fonty ładują się z Twoich plików, możesz sprawdzić ich źródło w DevTools w zakładce Elements -> Computed. Źródło local file oznacza, że pliki ładują się z zasobów systemu (czyli np. Twojego komputera, jeśli na nim pracujesz). My chcemy widzieć wartość network resources.
Być może zastanawiasz się, dlaczego w font-weight w regułach @font-face zastosowaliśmy wartości liczbowe (100, 500, 700), a przy stylowaniu raz piszemy 100, innym razem normal i bold.
Moglibyśmy wszędzie wpisywać wartości liczbowe i byłoby to nawet lepsze rozwiązanie, gdybyśmy mieli więcej krojów różnej grubości lub spodziewali się, że kiedyś je dodamy. W tym przykładzie jednak chciałam zwrócić Twoją uwagę na sposób odczytywania wartości bold i normal przez przeglądarkę.
Wartość normal to to samo co 400, natomiast bold to to samo co 700 (nie ma wartości tekstowej dla fontu „cienkiego”). Jakim sposobem więc nasz font Overpass Medium wyświetla się prawidłowo, skoro w regule @font-face we właściwości font-weight wpisaliśmy wartość 500, a przy stylowaniu piszemy font-weight: normal (równie dobrze moglibyśmy to pominąć, bo normal to wartość domyślna)?
Dzieje się tak za sprawą tzw. fallback weights – gdy pożądana wartość nie zostaje odnaleziona, wykorzystywana jest inna najbliższa zgodnie z opisanymi w dokumentacji zasadami.
Im więcej fontów i krojów, tym więcej reguł w pliku CSS, które niepotrzebnie zajmują tam miejsce. Możemy przenieść je do osobnego pliku np. fonts.css. Pamiętajmy tylko, by podłączyć ten plik w HTML-u.
<!DOCTYPE html> <html lang="pl"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="fonts.css"> <link rel="stylesheet" href="style.css"> <title>Jak dołączyć własne fonty do projektu – @font-face w CSS | DevMentor.pl</title> </head> <body> <!-- ... --> </body> </html>
Teraz już wiesz, jak dołączyć własne fonty do projektu! Nie przejmuj się, jeśli przytłacza Cię np. liczba formatów. Obecnie TTF i WOFF2 w większości przypadków wystarczą. Jeżeli kiedyś będziesz budować rozwiązanie wspierające mało popularne czy stare przeglądarki, Google pomoże Ci znaleźć odpowiednie opcje.
Udostępnij ten artykuł:
Potrzebujesz cotygodniowej dawki motywacji?
Zapisz się i zgarnij za darmo e-book o wartości 39 zł!
PS. Zazwyczaj rozsyłam 1-2 wiadomości na tydzień. Nikomu nie będę udostępniał Twojego adresu email.
Mam coś dla Ciebie!
W każdy piątek rozsyłam motywujący do nauki programowania newsletter!
Dodatkowo od razu otrzymasz ode mnie e-book o wartości 39 zł. To ponad 40 stron konkretów o nauce programowania i pracy w IT.
PS Zazwyczaj wysyłam 1-2 wiadomości na tydzień. Nikomu nie będę udostępniał Twojego adresu e-mail.