Wyślij zapytanie Dołącz do Sii

Nowoczesne technologie rozwijają się na naszych oczach – od pierwszych komputerów z dostępem do Internetu (w Polsce 17 stycznia 1991) po Internet na wyciągnięcie ręki w naszych kieszeniach. Udział urządzeń mobilnych (z wyłączeniem tabletów) w 2024 stanowił 61.21% globalnego ruchu na stronach internetowych.

Według statystyk 73,1% projektantów stron internetowych zgadza się, że nieresponsywny projekt jest główną przyczyną porzucania stron przez odwiedzających.

Udział urządzeń mobilnych w ruchu internetowym
Ryc. 1 Udział urządzeń mobilnych w ruchu internetowym

Z artykułu dowiesz się m.in.: na czym polega podejście tradycyjne do typografii oraz jak zastosować płynną typografię.

Nowe wyzwania

Powszechny dostęp do urządzeń mobilnych spowodował, że pojawiło się nowe wyzwanie – dostosowywanie zawartości strony (tekstów, obrazów, filmów itd.) do rozmiaru ekranu urządzenia, z którego korzysta użytkownik.

Jeśli zagadnienia z zakresu responsywności są Ci obce, polecam zapoznać się z pojęciami:

  • Media query – to kod CSS, który jest ukierunkowany na określone cechy urządzenia, takie jak rozmiar ekranu czy orientacja.
  • Viewport – to widoczny dla użytkownika obszar strony internetowej.
  • CSS units – PX, PT, EM, REM, %, VW, VH, VMIN i VMAX jako jednostki CSS. Można je podzielić na dwie kategorie: bezwzględne i względne.
  • Breakpoints – tzw. punkt przerwania, to określony punkt w projekcie strony internetowej lub aplikacji, w którym układ treści zmienia się, aby lepiej dopasować się do rozmiaru ekranu urządzenia).

Podejście tradycyjne

Typografia jest istotnym elementem strony internetowej. Zastosowanie atrybutów typograficznych, takich jak skala, odstępy i rozmiar, może wpływać pozytywnie lub negatywnie na odbiór, użyteczność czy dostępność strony.

Osiągnięcie zadowalającego efektu wizualnego możliwe jest dzięki dynamicznemu rozwojowi CSS.
CSS umożliwia korzystanie z różnych właściwości np.:

  • media query,
  • układ elastyczny (flex),
  • układ siatki (grid),

aby osiągnąć responsywny design. Media query pozwala programistom określić, jak powinna wyglądać strona internetowa dla różnych rozmiarów ekranu.

Jeśli korzystamy z media query (breakpoints), wartości ulegają zmianie w określonych punktach. Są to zdefiniowane w kodzie wartości szerokości ekranu, dla których projektanci definiują wygląd stron internetowych. Zmiany te następują skokowo. Same breakpoint mogą wykorzystywać różne jednostki.

Poniżej najprostszy przykład z breakpoints w px:

@media screen and (max-width: 765px) {
  div.example {
    font-size: 16px;
  }
}
@media screen and (min-width: 765px) {
  div.example {
    font-size: 36px;
  }
}

Zgodnie z powyższym, div.example będzie miał rozmiar tekstu 36px, jeśli ekran będzie większy lub równy 768px, ale 16px, jeśli będzie miał mniej niż 768px. Nie jest to narzędzie doskonałe. Występuje zasada „albo albo” i nie ma nic płynnego pomiędzy.

Inne przykłady tradycyjnego podejścia, w którym zastosowane są breakpoints z wartościami podanymi w rem:

:root {
  --font-size-basic: 1rem; /* 16px */
}

/* Between 768px and 1023px */
@media screen and (min-width: 48rem) and (max-width: 64rem) {
  :root {
    --font-size-basic: 1.125rem; /* 18px */
  }
}

/* 1024px or bigger */
@media screen and (min-width: 64rem) {
  :root {
    --font-size-basic: 1.5rem; /* 24px */
  }
}

/* Applying the font-size */
body {
  font-size: var(--font-size-basic);
}

Taki kod sprawi, że rozmiar tekstu będzie dostosowywał się do ekranów o różnych szerokościach. Jednak efekt może nie być do końca zadowalający.

Na drodze do płynności

Pierwsza prawdziwa implementacja płynnej typografii w CSS pojawiła się wraz z wprowadzeniem CSS calc i jednostek vw i vh.

Funkcja calc() w CSS umożliwia wykonywanie obliczeń matematycznych.

Jednostki vw oraz vh są jednostkami względnymi w żaden sposób nie są powiązane z podstawowym rozmiarem fontu. Zamiast tego są one względne w stosunku do wielkości ekranu (okna roboczego), który kontroluje użytkownik.

Jedna jednostka viewport* to 1% wielkości ekranu:

  • vw – 1% szerokości viewport (czyli 100px dla ekranu 1920px to 5,208vw),
  • vh – 1% wysokość viewport,

* Viewport = to widoczny dla użytkownika obszar strony internetowej.

Poniżej kod zapisany z wykorzystaniem funkcji calc() oraz breakpointów jako prekursor płynnej typografii:

.fluid {
  font-size: 14px;
}
@media screen and (min-width: 768px) {
  .fluid {
    font-size: calc(16px + 16 * ((100vw - 768px) / (1024 - 768)));
  }
}
@media screen and (min-width: 1024px) {
  .fluid {
    font-size: 32px;
  }
}

Powyższy przykład wygląda na skomplikowany, dlatego podzielmy go na segmenty.

Minimalny rozmiar fontu to 16px.

Jeśli ekran ma minimum 768px szerokości, wówczas font jest obliczany i będzie reagował na szerokość ekranu (ze względu na użycie jednostki względnej vw).

Dla ekranu o minimalnej szerokości 1024px jego rozmiar jest ustalony i wynosi 32px, niezależnie od tego, jak duży ekran będzie.

EkranFont [px]
120032
102432
98029.25
86021.75
76816 *
32016

* 100vw = 768px
(16 + 16 * ((768 – 768) / (1024 – 768)) = 16

Powyższy kod rozłożony w formie wzoru wygląda następująco:

.fluid {
 font-size: [value-min];
}

@media (min-width: [breakpoint-min]) {
  .fluid {
    font-size: calc([value-min] + ([value-max] - [value-min]) * ((100vw - [breakpoint-min]) / ([breakpoint-max] - [breakpoint-min])));
  }
}

@media (min-width: [breakpoint-max]) {
  .fluid {
    font-size: [value-max]
  }
}

Choć funkcja calc() znacznie ułatwiła tworzenie responsywnych projektów CSS, to programiści chcieli czegoś więcej.

Tworzenie płynnego fontu w powyższy sposób jest możliwe, ale to dość skomplikowany proces i wymaga napisania dużej ilości kodu, a dobry programista to… 😉 Właśnie dlatego powstała metoda clamp().

Fluid Typography

Jedną z wielu korzyści stosowania funkcji clamp() jest brak konieczności dodawania dodatkowych breakpointów dla zabezpieczenia strony przed skrajnymi przypadkami, a także brak konieczności stosowania wymyślnych obliczeń. Dzięki zastosowaniu clamp() wielkość tekstu skaluje się płynnie i wygląda poprawnie niezależnie od wielkości ekranu.

CSS clamp() oferuje to, co najlepsze z metod min() oraz max(). Przyjmuje trzy parametry:

  • wartość minimalną,
  • wartość preferowaną,
  • wartość maksymalną.

Można używać dowolnych jednostek miary/unitów (vw, vh, px, % itd.).

clamp(min, preferowana, maksymalna)

clamp(20px, 50%, 5rem)

  • minimum – równy minimalnemu rozmiarowi czcionki,
  • preferowana – określa sposób skalowania płynnej typografii,
  • maksimum – równy maksymalnemu rozmiarowi czcionki.

Funkcja clamp(MIN, PREFERED, MAX) jest rozwiązywane jako max(MIN, min(VAL, MAX)).

Popracujmy na przykładzie

Rozważmy następujący przykład:

body {
  font-size: clamp(1rem, 4vw, 3rem);
}

Rozmiar fontu będzie wahał się między 16px a 48px, a domyślny rozmiar będzie wynosił 4vw (czyli 4% szerokości ekranu, np.: dla szerokości 1024px font ma rozmiar 40.96px).

Zastosowanie clamp() może pomóc nam stworzyć płynne rozmiary tekstu, które dostosują się do ekranu o dowolnym rozmiarze. Powyższy kod ma jednak pewne wady.

Płynna typografia (wykorzystująca tylko jednostki vw/vh jako preferowane) nie jest doskonała. Powyższy przykład reprezentuje problem z dostępnością i jeśli będziemy opierali się jedynie na jednostkach viewport, nasz kod nie będzie spełniał kryteriów WCAG dotyczących rozmiaru tekstu (rozmiar tekstu może zostać powiększony do 200% bez użycia technologii wspomagających, nie wymagając od użytkownika chcącego odczytać cały wiersz, przesuwania tekstu w poziomie przy zmaksymalizowanym oknie ekranu) .

Bezpieczniejszym podejściem będzie jednoczesne zastosowanie rem. Jednostka rem skaluje się wraz z powiększaniem. Uwzględnienie w preferowanej wartość kombinacji vw oraz rem pozwoli na zachowanie zarówno wartości szerokości ekranu jak i preferencji skalowania użytkownika.

Określanie wartości preferowanej w clamp() w jednostkach rem

Jak wobec tego określić wartość preferowaną w clamp() w jednostkach rem?

Dla przykładu stwórzmy tekst o rozmiarze 16px na ekranach 320px i 19px na ekranach 1280px. Oto jak ta czcionka zwiększyłaby się wraz z rozmiarem ekranu:

Wykres clamp
Ryc. 2 Wykres clamp

Aby maksymalnie wykorzystać możliwości clamp oraz jednostek rem i vw możemy sami obliczyć wszystkie niezbędne wartości.

Poniższy wzór obrazuje kroki, które musielibyśmy wykonać, aby skorzystać z jednostek vw oraz rem, aby odwzorować powyższe wymagania.

Dla przykładu załóżmy, że minimalna szerokość ekranu to 320px i font 16px, maksymalna to 1200px i font 24px.


const parameters = {
  minWidth: 320,
  maxWidth: 1200,
  minFontSize: 16,
  maxFontSize: 24,
  pxPerRem: 16,
};

const minWidth = parameters.minWidth / parameters.pxPerRem;     
const maxWidth = parameters.maxWidth / parameters.pxPerRem;      
const fontRemMin = parameters.minFontSize / parameters.pxPerRem;       
const fontRemMax = parameters.maxFontSize / parameters.pxPerRem;       

const slope = (fontRemMax - fontRemMin) / (maxWidth - minWidth);     
const yAxisIntersection = -minWidth * slope + fontRemMin;            
const clampFunc = `clamp(${fontRemMin}rem, ${yAxisIntersection.toFixed(4)}rem + ${(slope * 100).toFixed(4)}vw, ${fontRemMax}rem)`;

Teraz przeanalizujmy to wszystko krok po kroku.
Na samym początku wszystkie wartości wyrażone w px należy przeliczyć na wartości w rem.
W kolejnym kroku obliczamy nachylenie (slope) zgodnie z zasadami matematyki.

Slope diagram
Ryc. 3 Slope diagram

Obliczamy dla wartości preferowanej punkt przecięcia wykresu na osi y i składamy wszystko w całość.

Po podstawieniu liczb otrzymamy następujące równania:

const parameters = {
  minWidth: 320,
  maxWidth: 1200,
  minFontSize: 16,
  maxFontSize: 24,
  pxPerRem: 16,
};

const minWidth = 320 / 16 = 20;     
const maxWidth = 1200 / 16 = 75;      
const fontRemMin = 16 / 16 = 1;       
const fontRemMax = 24 / 16 = 1.5;       

const slope = (1.5 - 1) / (75 - 20) = 0.5 / 55 = 0.00909;     
const yAxisIntersection = -20 * 0.00909 + 1 = -0.18181818181818182 + 1 = 0.8181818181818181;            
const clampFunc = clamp(1rem, -0.8182rem + 0,909vw, 1.5rem); 

Wynik:

font-size: clamp(1rem, 0.8182rem + 0.9091vw, 1.5rem);

Trochę trudne, prawda? A miało być lepiej, niż z wykorzystaniem calc()!
Dobra wiadomość jest taka, że w Internecie można znaleźć gotowe generatory tego rozwiązania:

Dodatkowo, warto sprawdzić działanie generatora tworzącego wizualizację działania clamp(). Poniżej przykład działania clamp():

Wsparcie

Funkcja clamp() jest nadal uznawana za ‘working draft’, ale mimo to ma szerokie wsparcie przeglądarek i można z niej korzystać.

Can I use
Ryc. 4 Can I use

Zakończenie

Funkcja clamp() w CSS jest użyteczną i elastyczną metodą nie tylko dla rozmiaru fontu, ale także dla innych mierzalnych elementów takich jak kolor, obramowanie, margines, wypełnienie itd. Dzięki temu można niewielkim nakładem pracy uzyskać dynamiczne efekty wizualne, reagujące na zmianę rozmiaru okna przeglądarki.

Jednak nie zawsze płynna typografia wykorzystująca szerokość ekranu głównego jest rozwiązaniem problemów skalowania. Może wystąpić sytuacja, w której lepszym rozwiązaniem byłoby wykorzystanie szerokości kontenera. Za te możliwości odpowiada container queries. To jest jednak temat na osobny artykuł.

Najlepsze praktyki dotyczące responsywnej/płynnej typografii:

  • Uwzględnienie czytelności i dostępności w rozmiarze czcionki – właściwy rozmiar czcionki zapewnia, że treść jest łatwa do odczytania i zrozumienia dla wszystkich użytkowników.
  • Responsywna typografia pomaga zachować równowagę między różnymi elementami projektu na różnych urządzeniach, dlatego ważne jest, aby rozmiary czcionek były odpowiednio skalowane na różnych urządzeniach.

Literatura

  1. Początek internetu w Polsce ­– Alek Tarkowski
  2. Website Design Stats And Trends For Small Businesses – GoodFirms Research
  3. Responsive Web Design – Introduction
  4. Responsive Web Design – Media Queries
  5. CSS Units
  6. How TO – Typical Device Breakpoints
  7. 10 Best Practices for Frontend Web Development: A Guide for Beginners
  8. PX to VW & PX to VH converter
  9. Fluid Typography
  10. Zmiana rozmiaru tekstu
  11. CSS values and units
  12. Slope formula
  13. Simplifying Responsive Font Sizing with a Clamp Calculator
  14. Can I use clamp?
  15. clamp()
  16. A guide to the min(), max(), and clamp() CSS functions
  17. Responsive design
  18. Fluid vs. responsive typography with CSS clamp
  19. CSS Clamp(): The Responsive Combination We’ve All Been Waiting For
  20. Font-size Clamp Generator
  21. Metoda CSS Clamp().
  22. Modern Fluid Typography Using CSS Clamp
  23. Nowoczesny CSS – min(), max() i clamp()
  24. Funkcja clamp w CSS
  25. Linearly Scale font-size with CSS clamp() Based on the Viewport
  26. Responsywność – czym jest? Definicja, projektowanie, zalety stron RWD
  27. 75+ Mobile Surfing Stats on Internet Traffic From Mobile Devices (Updated)
  28. Percentage of mobile device website traffic worldwide from 1st quarter 2015 to 4th quarter 2023
  29. Website Design Stats And Trends For Small Businesses – GoodFirms Research
  30. Fluid typography examples
  31. Creating a Fluid Type Scale with CSS Clamp
  32. A guide to CSS container queries
  33. Responsive Type and Zoom
  34. Internet Traffic from Mobile Devices (May 2024)
5/5 ( głosy: 5)
Ocena:
5/5 ( głosy: 5)
Autor
Avatar
Weronika Urbańczyk

Front-end developerka pasjonująca się piękniejszą stroną programowania. W Sii pracuje od 2021 roku. Na co dzień pisze w React oraz TypeScript. Lubi podejmować wyzwania z kodowania oraz dla rozrywki rozwiązywać zadania z cssbattle oraz codewars. Prywatnie miłośniczka zimnej północy

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Może Cię również zainteresować

Pokaż więcej artykułów

Bądź na bieżąco

Zasubskrybuj naszego bloga i otrzymuj informacje o najnowszych wpisach.

Otrzymaj ofertę

Jeśli chcesz dowiedzieć się więcej na temat oferty Sii, skontaktuj się z nami.

Wyślij zapytanie Wyślij zapytanie

Natalia Competency Center Director

Get an offer

Dołącz do Sii

Znajdź idealną pracę – zapoznaj się z naszą ofertą rekrutacyjną i aplikuj.

Aplikuj Aplikuj

Paweł Process Owner

Join Sii

ZATWIERDŹ

This content is available only in one language version.
You will be redirected to home page.

Are you sure you want to leave this page?