HTML & CSS

Типографіка в CSS. Шрифти та текст

Глибоке занурення у CSS-типографіку: font-family, @font-face, Google Fonts, font-size (px/em/rem), line-height, text-align, text-decoration, text-overflow, одиниці виміру та CSS Custom Properties для системи типографіки.

Типографіка в CSS. Шрифти та текст

Чому деякі сайти читаються легко, а інші — як крізь матове скло?

Відкрийте два сайти: один — блог із вдало підібраним шрифтом, комфортними міжрядковими інтервалами та правильною ієрархією заголовків. Інший — із дрібним текстом, тісними рядками та кричущим шрифтом. Контент може бути однаково цікавим, але перший ви дочитаєте, а другий закриєте через 10 секунд.

Типографіка (Typography) — мистецтво оформлення тексту — це 95% веб-дизайну. Більшість інформації в інтернеті — саме текст. І CSS дає повний контроль над тим, як цей текст виглядає: від вибору шрифту до відстані між літерами.

У попередній статті ми розібрали блокову модель — розміри та відступи елементів. Тепер поринемо в те, що всередині цих коробок — у текст та його оформлення.

🔤 Шрифти

Вибір гарнітури (font-family), підключення кастомних шрифтів, Google Fonts, стек шрифтів.

📏 Розміри

px, em, rem, %, vw, vh — коли і яку одиницю використовувати.

📝 Оформлення тексту

Вирівнювання, міжрядковий інтервал, інтервал між літерами, декорації.

🎨 Система типографіки

CSS Custom Properties для побудови узгодженої типографічної системи.

Властивість font-family визначає яким шрифтом відображати текст. Це перше, що впливає на сприйняття сайту.

Як ОС рендерить шрифти

Перш ніж розглядати підключення шрифтів, важливо розуміти: один і той самий шрифт може і буде виглядати по-різному на Windows та macOS. Це пов'язано з тим, як різні операційні системи виконують згладжування шрифтів (anti-aliasing):

  • macOS (Apple) історично віддавала перевагу збереженню оригінального дизайну шрифту. Тому на маках літери можуть здаватися трохи більш жирними або "пухнастими", зберігаючи свої точні пропорції.
  • Windows (Microsoft) через технологію ClearType історично віддавала перевагу чіткості читання на екранах (прив'язка до піксельної сітки). Тому на Windows той самий шрифт може виглядати різкішим, тоншим і більш геометричним.

Веб-платформа майже не дає контролю над цим процесом (хоча існують нестандартні властивості типу -webkit-font-smoothing: antialiased, що роблять текст тоншим на macOS, але їх використання часто критикують за шкоду доступності). Тому ваша задача — не зробити шрифт ідентичним на кожному пристрої, а вибрати такий font-family, який буде виглядати однаково добре при різних алгоритмах рендерингу.

Стек шрифтів (Font Stack)

font-family приймає список шрифтів, розділених комами. Браузер використовує перший доступний:

🔒localhost:3000
body {
    font-family: 'Inter', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}

Браузер обробляє цей список зліва направо:

  1. Inter — встановлений? Так → використовує. Ні → переходить далі.
  2. Segoe UI — системний шрифт Windows.
  3. Roboto — системний шрифт Android.
  4. Helvetica Neue — системний шрифт macOS.
  5. Arial — є на більшості систем.
  6. sans-serif — «родове ім'я» — браузер обере будь-який доступний шрифт без засічок.
Шрифти з пробілами у назві обов'язково беруться у лапки: 'Segoe UI', 'Times New Roman'. Одне слово — можна без лапок: Arial, Georgia.

Родові сімейства (Generic Families)

Останнім у стеку завжди має стояти родове сімейство — це «план Б» на випадок, якщо жоден конкретний шрифт недоступний:

🔒localhost:3000
Родове сімействоХарактеристикаВикористання
serifЗ засічкамиДрукований стиль, довгі тексти (книги, статті)
sans-serifБез засічокВеб-інтерфейси, заголовки, сучасний дизайн
monospaceОднакова ширина літерКод, термінал, табличні дані
cursiveРукописнийДекоративні акценти (обережно!)
fantasyДекоративнийДуже рідко — результат непередбачуваний
system-uiСистемний UI-шрифтІнтерфейси, що відповідають стилю ОС
system-ui — сучасна альтернатива довгим стекам. Він автоматично обирає шрифт, який операційна система використовує для свого інтерфейсу (San Francisco на macOS, Segoe UI на Windows, Roboto на Android):
body {
    font-family: system-ui, sans-serif;
}

Підключення зовнішніх шрифтів

Системних шрифтів часто недостатньо для унікального дизайну. CSS дозволяє завантажити будь-який шрифт.

Google Fonts — найпростіший спосіб

Google Fonts — безкоштовна бібліотека з 1500+ шрифтів. Підключення — одним рядком у <head>:

Крок 1: Оберіть шрифт на Google Fonts

Перейдіть на fonts.google.com та оберіть шрифт. Наприклад, Inter — один із найпопулярніших для веб-інтерфейсів.

Google Fonts надасть HTML-код для підключення:

<head>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
</head>

Крок 3: Використайте у CSS

body {
    font-family: 'Inter', sans-serif;
}
Рядки preconnect — це оптимізація швидкості: браузер заздалегідь встановлює з'єднання з сервером Google, щоб шрифт завантажився швидше. Параметр display=swap забезпечує показ тексту системним шрифтом, поки завантажується зовнішній (це керує завантажувальною стратегією і вирішує проблему FOIT — детальніше читайте нижче в розділі про @font-face).

@font-face — повний контроль

Якщо шрифт не на Google Fonts, або ви хочете самостійно хостити файли (для швидкості та приватності), використовуйте @font-face:

@font-face {
    font-family: 'CustomFont';
    src:
        url('/fonts/CustomFont-Regular.woff2') format('woff2'),
        url('/fonts/CustomFont-Regular.woff') format('woff');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'CustomFont';
    src:
        url('/fonts/CustomFont-Bold.woff2') format('woff2'),
        url('/fonts/CustomFont-Bold.woff') format('woff');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

body {
    font-family: 'CustomFont', sans-serif;
}
font-family
string required
Ім'я, під яким шрифт буде доступний у CSS. Може бути будь-яким — ви його вигадуєте самі.
src
url + format
Шлях до файлу шрифту та його формат. woff2 — сучасний стислий формат, woff — фолбек для старих браузерів.
font-weight
number
Вага, для якої цей файл призначений (400 = normal, 700 = bold). Дозволяє браузеру обрати правильний файл.
font-display
string
Стратегія завантаження. Коли браузер зустрічає кастомний шрифт, йому потрібен час на файл woff2. Що показувати користувачу цей час? Існує дві проблеми недозавантажених шрифтів:
  • FOIT (Flash of Invisible Text): Текст стає невидимим на кілька секунд, поки шрифт качається. Це дуже погано для UX.
  • FOUT (Flash of Unstyled Text): Спочатку відображається системний шрифт, а коли кастомний завантажується — текст різко (і неприємно) «змінює свій вигляд» (блимає).
Значення swap (рекомендовано більшістю) каже браузеру: "одразу покажи FOUT, ніколи не роби текст невидимим (уникай FOIT)". Значення optional (ідеально для швидкості): "Дай шрифту 100мс; якщо він не завантажився - використовуй системний шрифт, і не міняй його, коли файл врешті докачається (уникай FOUT). Шрифт буде застосований лише з наступного завантаження сторінки з кешу".
Формат woff2 — обов'язковий мінімум для сучасного вебу (стиснення ~30% краще за woff). Формати ttf, otf, svg — застарілі для веб-використання. Конвертувати шрифти можна на google-webfonts-helper.

Порівняння підходів

Google Fonts

  • ✅ Найпростіше підключення
  • ✅ CDN з кешуванням
  • ✅ 1500+ безкоштовних шрифтів
  • ❌ Залежність від Google CDN
  • ❌ Запит до зовнішнього сервера (GDPR у ЄС)

Самостійний хостинг (@font-face)

  • ✅ Повний контроль
  • ✅ Немає зовнішніх залежностей
  • ✅ Відповідність GDPR
  • ❌ Потрібно самостійно оптимізувати файли
  • ❌ Немає автоматичного кешування CDN

Системні шрифти (system-ui)

  • ✅ Нуль часу завантаження
  • ✅ Рідний вигляд для ОС
  • ✅ Мінімальний розмір CSS
  • ❌ Різний вигляд на різних ОС
  • ❌ Обмежений вибір

Розмір шрифту — font-size

Розмір тексту — одна з найважливіших властивостей. Але CSS пропонує десяток одиниць виміру. Як обрати правильну?

Проблема Pixel Perfect та доступності (Accessibility)

Раніше веб-дизайнери створювали "pixel perfect" сайти, де кожен елемент відповідав макету до пікселя. Такий підхід жахливий для доступності. Згідно з дослідженнями, значний відсоток користувачів (особливо з вадами зору або старшого віку) змінюють базовий розмір шрифту браузера у налаштуваннях (за замовчуванням це 16px, але люди часто ставлять 20px або більше).

Якщо ви задали вашому тексту жорсткий розмір font-size: 16px;, браузер проігнорує налаштування користувача. Текст залишиться дрібним, а сайт стане незручним для читання.

Тому сучасний підхід до веб-типографіки вимагає використання відносних одиниць (rem, em), які здатні масштабуватися разом із налаштуваннями ОС та браузера.

Пікселі (px) — абсолютна одиниця

h1 {
    font-size: 32px;
}
p {
    font-size: 16px;
}
🔒localhost:3000

Переваги: простота, передбачуваність — 16px завжди 16px (що добре для мікро-елементів інтерфейсу, наприклад декоративних бейджів або дрібних іконок, які не повинні масштабуватися і ламати сітку).

Недолік: жорстко закріплений дизайн, який ігнорує потреби людей з вадами зору, про що ми говорили вище. Ніколи не використовуйте px для читабельного тексту абзаців або заголовків!

em — відносно батька

1em дорівнює font-size батьківського елемента:

🔒localhost:3000
emкаскадується — і це головна пастка. Якщо вкладений елемент має font-size: 1.5em, а його дитина теж 1.5em, то результат — 1.5 × 1.5 = 2.25em від початкового розміру. З кожним рівнем вкладеності ефект множиться:
Loading diagram...
graph TD
    A["html\nfont-size: 16px"] --> B["body\n1.25em = 20px"]
    B --> C["article\n1.5em = 30px"]
    C --> D["p\n1.5em = 45px 😱"]
    style A fill:#3b82f6,color:#fff
    style B fill:#3b82f6,color:#fff
    style C fill:#f59e0b,color:#fff
    style D fill:#ef4444,color:#fff

rem — відносно кореня (рекомендовано)

1rem завжди дорівнює font-size кореневого елемента <html> (за замовчуванням — 16px):

🔒localhost:3000
Правило сучасного CSS: використовуйте rem для font-size — він не каскадується і поважає налаштування користувача. Використовуйте em для padding та marginвсередині компонента — вони масштабуватимуться разом із розміром тексту.

Порівняння одиниць

ОдиницяВідносно чогоКаскадуєтьсяКоли використовувати
pxАбсолютнаborder, box-shadow, outline — де потрібна точність
emfont-size батькаpadding, margin всередині компонента
remfont-size <html>font-size, глобальні інтервали
%Батьківський елементwidth, max-width
vw1% ширини viewportFluid typography, повноекранні секції
vh1% висоти viewportПовноекранні секції (height: 100vh)
chШирина символу «0»Обмеження ширини тексту (max-width: 65ch)
ch — елегантна одиниця для типографіки. Рядок у 50–75 символів вважається оптимальним для читання. max-width: 65ch — це стандарт для текстових блоків.

Стилізація шрифту

font-weight — жирність

🔒localhost:3000
Не всі шрифти мають всі 9 рівнів жирності. Якщо запитана вага відсутня, браузер обере найближчу доступну. Наприклад, стандартний Arial має лише 400 та 700. При підключенні Google Fonts обирайте потрібні ваги явно: ?family=Inter:wght@400;600;700.

font-style — курсив

🔒localhost:3000
.normal {
    font-style: normal;
} /* Звичайний */
.italic {
    font-style: italic;
} /* Курсив */
.oblique {
    font-style: oblique;
} /* Нахилений (імітація курсиву) */
italic і oblique виглядають схоже, але italic — це окреслений курсивний варіант шрифту (спеціально розроблений дизайнером для кращої читабельності та гармонії літер). oblique — просто програмно нахилена браузером версія звичайного прямого шрифту. Якщо ви використовуєте italic, але завантажений шрифт не має italic-файлу (наприклад, ви підключили лише wght@400), браузер автоматично застосує oblique як фолбек, щоб якось виділити текст.

font-variant — капітель

🔒localhost:3000
.small-caps {
    font-variant: small-caps; /* ВЕЛИКІ літери, але розміру малих */
}

Скорочення font

Всі властивості шрифту можна задати одним рядком:

/* font: style weight size/line-height family; */
body {
    font:
        normal 400 1rem/1.6 'Inter',
        sans-serif;
}

h1 {
    font:
        italic 700 2.5rem/1.2 Georgia,
        serif;
}
Порядок у скороченні fontфіксований. font-size та font-familyобов'язкові. Якщо пропустити будь-яку з них, все правило буде проігноровано. Через цю крихкість багато розробників обирають писати кожну властивість окремо.

Оформлення тексту

line-height — міжрядковий інтервал

Це одна з найважливіших властивостей для читабельності, основа так званого вертикального ритму (Vertical Rhythm).

Коли ми читаємо абзац тексту, наше око має легко перескакувати з кінця одного рядка на початок наступного. Якщо інтервал занадто тісний — рядки зливаються у суцільну пляму, і ми губимося. Якщо занадто широкий — око втрачає зв'язок між рядками, сприймаючи їх як окремі речення, що вповільнює читання.

Ідеальний line-height залежить від ширини текстового блоку (чим довший рядок, тим більшим має бути інтервал, щоб оку було легше знайти початок наступного рядка) та розміру шрифту.

🔒localhost:3000
Правило для line-height: використовуйте безрозмірне число (без одиниць): line-height: 1.6. Це значення множиться на поточний font-size, що коректно працює з наслідуванням. line-height: 24px або line-height: 1.6em — прив'язані до конкретного значення і можуть зламатись у вкладених елементах із різним font-size.

letter-spacing та word-spacing (Трекінг та Мікротипографіка)

У професійній типографіці існують два різних поняття для відстані між літерами:

  1. Кернінг (Kerning) — це відстань між конкретними парами літер, щоб вони виглядали гармонійно (наприклад, літери A та V краще виглядають, коли трохи "наповзають" одна на одну). Сучасні шрифти вже містять вбудовані таблиці кернінгу, і браузер застосовує їх автоматично (через властивість font-kerning: auto).
  2. Трекінг (Tracking) — це рівномірне розсування або стискання відстані між усіма літерами у слові чи реченні. Саме цим керує CSS-властивість letter-spacing.
🔒localhost:3000
Золоте правило мікротипографіки:
  • Великі літери (uppercase) створені так, що їх вертикальні лінії візуально зливаються, якщо стоять надто близько. Тому тексту ВЕЛИКИМИ ЛІТЕРАМИ (наприклад, у заголовках або кнопках) завжди потрібен додатковий розрізнений letter-spacing (tracking) для кращої читабельності.
  • Малі літери (lowercase) вже мають необхідний природний "повітряний" простір завдяки своїм виносним елементам (як у g, p, b, d). Додавання їм letter-spacing найчастіше псує читабельність. Для звичайного тексту залишайте normal або ледь зменшуйте (-0.01em / -0.02em) для дуже великих заголовків (оскільки при великих font-size оптичний простір між літерами здається занадто великим).

text-align — вирівнювання

🔒localhost:3000

text-decoration — підкреслення та декорації

🔒localhost:3000
Сучасний CSS дозволяє тонко налаштувати підкреслення за допомогою окремих властивостей. Це дає змогу створювати красиві ефекти при наведенні або акценти в тексті.
🔒localhost:3000

text-transform — трансформація регістру

🔒localhost:3000
.uppercase {
    text-transform: uppercase;
} /* ВЕЛИКІ ЛІТЕРИ */
.lowercase {
    text-transform: lowercase;
} /* малі літери */
.capitalize {
    text-transform: capitalize;
} /* Перша Літера Кожного Слова */
.none {
    text-transform: none;
} /* Як у HTML */
text-transform змінює лише візуальне відображення, а не реальний текст в HTML. Якщо користувач скопіює текст .uppercase, він вставиться в оригінальному регістрі. Також для SEO (пошукових систем) та Screen Readers (читалок для сліпих) текст залишається оригінальним. Тому завжди краще використовувати text-transform, ніж жорстко писати КАПСОМ у самому HTML.

Обрізання тексту — text-overflow

Часто текст не вміщується в обмежений простір — наприклад, заголовок картки. CSS дозволяє це елегантно обробити:

Однорядкове обрізання (ellipsis)

🔒localhost:3000

Три властивості працюють разом — прибрати будь-яку — і трикрапка зникне:

white-space: nowrap
string required
Забороняє перенос тексту на новий рядок — весь текст в одному рядку.
overflow: hidden
string required
Приховує вміст, що виходить за межі елемента.
text-overflow: ellipsis
string required
Замінює обрізаний текст на символ «…» (трикрапка).

Багаторядкове обрізання (-webkit-line-clamp)

🔒localhost:3000
-webkit-line-clamp використовує застарілий -webkit- синтаксис, але підтримується усіма сучасними браузерами, включно з Firefox та Safari. Стандартизована властивість line-clamp (без префікса) поки what на стадії розробки.

CSS Custom Properties для типографіки

CSS-змінні (Custom Properties) дозволяють створити узгоджену систему типографіки для всього проєкту:

:root {
    /* Шкала розмірів */
    --font-size-xs: 0.75rem; /* 12px */
    --font-size-sm: 0.875rem; /* 14px */
    --font-size-base: 1rem; /* 16px */
    --font-size-lg: 1.125rem; /* 18px */
    --font-size-xl: 1.25rem; /* 20px */
    --font-size-2xl: 1.5rem; /* 24px */
    --font-size-3xl: 2rem; /* 32px */
    --font-size-4xl: 2.5rem; /* 40px */

    /* Шрифтові сімейства */
    --font-sans: 'Inter', system-ui, sans-serif;
    --font-serif: Georgia, 'Times New Roman', serif;
    --font-mono: 'Fira Code', Consolas, monospace;

    /* Ваги */
    --font-normal: 400;
    --font-medium: 500;
    --font-semibold: 600;
    --font-bold: 700;

    /* Міжрядкові інтервали */
    --leading-tight: 1.25;
    --leading-normal: 1.6;
    --leading-relaxed: 1.75;
}

Використання:

🔒localhost:3000
body {
    font-family: var(--font-sans);
    font-size: var(--font-size-base);
    line-height: var(--leading-normal);
    color: #1e293b;
}

h1 {
    font-size: var(--font-size-4xl);
    font-weight: var(--font-bold);
    line-height: var(--leading-tight);
}

h2 {
    font-size: var(--font-size-3xl);
    font-weight: var(--font-semibold);
    line-height: var(--leading-tight);
}

code {
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
}
Навіщо змінні? Якщо потрібно збільшити базовий розмір тексту на всьому сайті — змінюєте одне значення в :root, і вся типографіка масштабується автоматично. Без змінних — довелось би шукати та змінювати десятки значень у різних файлах.

Fluid Typography — адаптивний розмір тексту

Замість медіа-запитів для зміни розміру тексту на різних екранах, CSS пропонує плавне масштабування через функцію clamp():

h1 {
    /* clamp(мінімум, ідеальне значення, максимум) */
    font-size: clamp(1.5rem, 4vw, 3rem);
}
🔒localhost:3000
Мінімум
length required
Мінімальний розмір шрифту — ніколи не стане меншим. Зазвичай у rem.
Ідеальне значення
length required
Бажаний розмір, що масштабується з viewport. Зазвичай у vw або комбінація rem + vw.
Максимум
length required
Максимальний розмір — ніколи не стане більшим. Зазвичай у rem.
clamp() повністю замінює медіа-запити для типографіки. Замість трьох окремих @media для телефона, планшета та десктопа — один рядок CSS. Детальніше про адаптивний дизайн — у статті про Media Queries.

Практичні завдання

Рівень 1 — Базовий

Рівень 2 — Логіка та комбінування

Рівень 3 — Створення з нуля


Підсумок

🔤 font-family

Завжди вказуйте стек шрифтів із родовим сімейством у кінці. system-ui — найшвидший варіант. Google Fonts та @font-face — для кастомних шрифтів.

📏 rem > em > px

rem — для font-size (не каскадується). em — для padding/margin компонента. px — для border, shadow. clamp() — для fluid typography.

📖 Читабельність

line-height: 1.5–1.7, max-width: 60–75ch, достатній font-size (≥ 16px). Ці три параметри — 90% комфортного читання.

🎨 Система

CSS Custom Properties у :root — фундамент типографічної системи. Один раз налаштували — використовуєте скрізь через var().

Корисні посилання