Типографіка та система кольорів у Tailwind v4
Типографіка та система кольорів у Tailwind v4
Чому типографіка та кольори — це архітектурне рішення
Коли розробники починають роботу з UI, типографіку і кольори часто розглядають як декоративні деталі, що можна «налаштувати пізніше». Це фундаментальна помилка. Кольорова система і типографічна ієрархія — це архітектура комунікації: вони визначають, що користувач побачить першим, що прочитає другим, і як зрозуміє ієрархію інформації на сторінці.
У контексті Tailwind ці системи мають ще один вимір: вони є дизайн-токенами, що пов'язують CSS-утиліти з семантичними значеннями. Правильно побудована кольорова система дозволяє перемикати теми єдиною змінною; грамотна типографічна шкала — описати будь-яку ієрархію контенту за допомогою кількох передбачуваних класів.
Tailwind v4 суттєво еволюціонував обидві системи: перехід на OKLCH-кольори вирішив давні проблеми перцептивної рівномірності, а нові утиліти text-balance та text-pretty вперше дозволили контролювати переноси рядків без JavaScript.
@theme (стаття 05) та системою варіантів (стаття 06). Рекомендуємо прочитати їх перед тим, як продовжувати.Кольорова система Tailwind v4: від палітри до токенів
Стандартна палітра: 22 шкали, 11 відтінків
Tailwind поставляється з повною кольоровою палітрою, що охоплює 22 колірних сімейства. Кожна шкала містить 11 ступенів — від 50 (майже білий) до 950 (майже чорний). Це дає 242 готових кольорових значення без будь-якої конфігурації:
| Група | Кольори |
|---|---|
| Нейтральні | slate, gray, zinc, neutral, stone |
| Теплі | red, orange, amber, yellow |
| Природні | lime, green, emerald, teal |
| Холодні | cyan, sky, blue, indigo |
| Фіолетові/Рожеві | violet, purple, fuchsia, pink, rose |
Числова шкала відтінків побудована за принципом семантичного призначення: 50–200 — фони і підкладки, 300–400 — рамки і розділювачі, 500–600 — основний акцентний колір, 700–900 — темні текстові варіанти, 950 — майже чорний для темних тем.
<!-- Семантичне використання шкали slate -->
<div class="bg-slate-50"> <!-- Фон сторінки або секції -->
<div class="bg-white border border-slate-200 rounded-xl p-6">
<span class="text-xs font-bold uppercase tracking-widest text-slate-400">
Мітка категорії — slate-400
</span>
<h2 class="text-xl font-bold text-slate-900 mt-1">
Заголовок картки — slate-900
</h2>
<p class="text-sm text-slate-600 mt-2 leading-relaxed">
Основний текст — slate-600, добре читається на білому.
</p>
<div class="border-t border-slate-100 mt-4 pt-3">
<span class="text-xs text-slate-400">slate-100 як лінія розділення</span>
</div>
</div>
</div>
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-6 bg-slate-100 font-sans flex justify-center">
<div class="w-full max-w-sm bg-slate-50 p-6 rounded-2xl border border-slate-200 shadow-sm">
<!-- Внутрішня картка -->
<div class="bg-white border border-slate-200 rounded-xl p-6 shadow-sm">
<span class="text-[10px] font-bold uppercase tracking-widest text-slate-400 block mb-1">
Мітка категорії — slate-400
</span>
<h2 class="text-xl font-bold text-slate-900 leading-tight">
Заголовок картки — slate-900
</h2>
<p class="text-sm text-slate-600 mt-2 leading-relaxed">
Основний текст — slate-600, добре читається на білому. Ця ієрархія кольорів допомагає користувачеві легко сприймати контент.
</p>
<div class="border-t border-slate-100 mt-4 pt-3">
<span class="text-xs text-slate-400">slate-100 як лінія розділення</span>
</div>
</div>
</div>
</body>
</html>
OKLCH: революція у кольоровому просторі
У Tailwind v4 вся стандартна палітра переведена на колірний простір OKLCH. Щоб зрозуміти практичне значення цього, розглянемо фундаментальну відмінність між sRGB і OKLCH.
У традиційному sRGB кольорах (#4f46e5, rgb(79, 70, 229)) числа описують фізичну інтенсивність R, G, B каналів. Ці числа не корелюють із тим, як людський мозок сприймає яскравість. Наслідком є те, що кольори з однаковим числовим значенням яскравості (blue-500 і yellow-500) виглядають принципово різними за перцептивним контрастом.
OKLCH (Oklab Lightness, Chroma, Hue) будує кольоровий простір навколо людського сприйняття:
oklch(L C H / α)
│ │ │ └── Прозорість (0–1)
│ │ └────── Відтінок (0–360°, кут на колірному колі)
│ └──────── Насиченість (0–0.37+, 0 = сірий)
└────────── Яскравість (0–1, де 0 = чорний, 1 = білий)
Ключова властивість OKLCH: значення L (Lightness) є перцептивно рівномірним. Тобто indigo-500 і emerald-500 мають однакове значення L і справді виглядають однаково яскраво — текст на них матиме однаковий рівень читабельності. Це усуває клас проблем, де дизайнер підбирав кольори на oko, бо цифрова система їм не допомагала.
::field{name="Перцептивна рівномірність" type="Lightness}
blue-500 та indigo-500 мають однаковий L — однаковий зоровий контраст із білим текстом. У sRGB вони відрізнялись і доводилось підбирати вручну.
::
oklch(from var(--color-brand) calc(l * 0.85) c h) — точно затемнений варіант бренд-кольору без зсуву відтінку. У sRGB це потребувало ручного підбору або JS.Opacity modifier /: прозорість у назві класу
До Tailwind v3 для напівпрозорого фону потрібно було або окремий клас bg-opacity-50, або CSS-змінна. Tailwind ввів елегантніше рішення — opacity modifier у форматі {utility}/{opacity}:
<!-- Фон із різною прозорістю -->
<div class="bg-indigo-500/100">Непрозорий</div>
<div class="bg-indigo-500/75">75% непрозорий</div>
<div class="bg-indigo-500/50">50% — напівпрозорий</div>
<div class="bg-indigo-500/25">25%</div>
<div class="bg-indigo-500/10">10% — ледве помітний тінт</div>
<div class="bg-indigo-500/0">Повністю прозорий</div>
<!-- Текст -->
<p class="text-slate-900/80">Трохи приглушений текст</p>
<p class="text-slate-900/50">Напівпрозорий текст (уникайте для основного!)</p>
<!-- Рамка -->
<div class="border border-white/20">Напівпрозора рамка на темному фоні</div>
<!-- Focus ring -->
<input class="focus:ring-2 focus:ring-indigo-500/30 focus:outline-none" />
<!-- Довільне значення -->
<div class="bg-indigo-500/[0.35]">35%</div>
Opacity modifier підтримується для bg-, text-, border-, ring-, shadow-, outline-, divide-, placeholder-, caret- та accent-. Технічно він реалізований через CSS color-mix() або змінну --tw-bg-opacity, що дозволяє плавно змінювати прозорість без зміни базового кольору.
Glassmorphism — один із найефективніших застосувань opacity modifier:
<!-- Скляна картка поверх градієнтного фону -->
<div class="relative bg-gradient-to-br from-indigo-500 to-purple-600 p-8 rounded-2xl">
<div class="bg-white/10 backdrop-blur-sm border border-white/20
rounded-xl p-6 text-white">
<!-- bg-white/10 = білий із 10% прозорістю -->
<!-- border-white/20 = рамка з 20% прозорістю -->
<!-- backdrop-blur-sm = розмиття фону за карткою -->
<h3 class="font-bold text-lg">Glassmorphism картка</h3>
<p class="text-white/70 mt-2 text-sm">Текст із 70% прозорістю</p>
</div>
</div>
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-8 bg-slate-50 font-sans space-y-6">
<!-- Палітра відтінків -->
<div>
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Шкала indigo: від 50 до 950</p>
<div class="flex rounded-xl overflow-hidden h-12 shadow-sm">
<div class="flex-1 bg-indigo-50 flex items-end justify-center pb-1"><span class="text-[9px] text-indigo-300">50</span></div>
<div class="flex-1 bg-indigo-100 flex items-end justify-center pb-1"><span class="text-[9px] text-indigo-300">100</span></div>
<div class="flex-1 bg-indigo-200 flex items-end justify-center pb-1"><span class="text-[9px] text-indigo-400">200</span></div>
<div class="flex-1 bg-indigo-300 flex items-end justify-center pb-1"><span class="text-[9px] text-indigo-500">300</span></div>
<div class="flex-1 bg-indigo-400 flex items-end justify-center pb-1"><span class="text-[9px] text-white">400</span></div>
<div class="flex-1 bg-indigo-500 flex items-end justify-center pb-1"><span class="text-[9px] text-white">500</span></div>
<div class="flex-1 bg-indigo-600 flex items-end justify-center pb-1"><span class="text-[9px] text-white">600</span></div>
<div class="flex-1 bg-indigo-700 flex items-end justify-center pb-1"><span class="text-[9px] text-white">700</span></div>
<div class="flex-1 bg-indigo-800 flex items-end justify-center pb-1"><span class="text-[9px] text-white">800</span></div>
<div class="flex-1 bg-indigo-900 flex items-end justify-center pb-1"><span class="text-[9px] text-white">900</span></div>
<div class="flex-1 bg-indigo-950 flex items-end justify-center pb-1"><span class="text-[9px] text-indigo-700">950</span></div>
</div>
</div>
<!-- Opacity modifier -->
<div>
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Opacity modifier /N</p>
<div class="grid grid-cols-6 gap-2">
<div class="h-14 bg-violet-500/100 rounded-xl flex items-center justify-center text-white text-xs font-bold shadow-sm">/100</div>
<div class="h-14 bg-violet-500/80 rounded-xl flex items-center justify-center text-slate-800 text-xs font-bold">/80</div>
<div class="h-14 bg-violet-500/60 rounded-xl flex items-center justify-center text-slate-800 text-xs font-bold">/60</div>
<div class="h-14 bg-violet-500/40 rounded-xl flex items-center justify-center text-slate-800 text-xs font-bold">/40</div>
<div class="h-14 bg-violet-500/20 rounded-xl flex items-center justify-center text-violet-700 text-xs font-bold">/20</div>
<div class="h-14 bg-violet-500/10 rounded-xl flex items-center justify-center text-violet-700 text-xs font-bold border border-dashed border-violet-200">/10</div>
</div>
</div>
<!-- Glassmorphism -->
<div>
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Glassmorphism</p>
<div class="relative h-32 bg-gradient-to-br from-indigo-500 via-purple-500 to-pink-500 rounded-2xl flex items-center justify-center gap-4 p-4">
<div class="bg-white/10 backdrop-blur-sm border border-white/20 rounded-xl px-5 py-3 text-center">
<p class="text-white font-semibold text-sm">bg-white/10</p>
<p class="text-white/60 text-xs">border-white/20</p>
</div>
<div class="bg-white/25 backdrop-blur-md border border-white/40 rounded-xl px-5 py-3 text-center">
<p class="text-white font-semibold text-sm">bg-white/25</p>
<p class="text-white/70 text-xs">backdrop-blur-md</p>
</div>
<div class="bg-black/20 backdrop-blur-sm border border-white/10 rounded-xl px-5 py-3 text-center">
<p class="text-white font-semibold text-sm">bg-black/20</p>
<p class="text-white/60 text-xs">темний варіант</p>
</div>
</div>
</div>
</body>
</html>
🧪 Практика: кольорова система
Визначте у @theme повну кольорову систему для SaaS-продукту: (1) основний бренд-колір через --color-brand-{50..900} в OKLCH, (2) семантичні токени --color-bg, --color-surface, --color-text, --color-muted, --color-border, --color-accent, (3) реалізуйте 3 компоненти (кнопка, картка, badge), що використовують семантичні токени — не конкретні кольори.
Типографічна система: від font-size до text-wrap
Шкала font-size та вбудований line-height
Найважливіша деталь, яку розробники часто не помічають: кожен text-{size} клас у Tailwind задає два значення одночасно — font-size та line-height. Це не випадково: команда Tailwind розрахувала оптимальний міжрядковий інтервал для кожного розміру тексту, щоб розробникам не потрібно було думати про це окремо.
| Клас | font-size | line-height | Призначення |
|---|---|---|---|
text-xs | 12px (0.75rem) | 16px | Caption, labels, badges, metadata |
text-sm | 14px (0.875rem) | 20px | Secondary text, descriptions, UI |
text-base | 16px (1rem) | 24px | Body text (стандарт) |
text-lg | 18px (1.125rem) | 28px | Lead paragraph, intro |
text-xl | 20px (1.25rem) | 28px | Sub-heading, card title |
text-2xl | 24px (1.5rem) | 32px | Section heading |
text-3xl | 30px (1.875rem) | 36px | Page section title |
text-4xl | 36px (2.25rem) | 40px | Hero subtitle |
text-5xl | 48px (3rem) | 1 (= font-size) | Hero title |
text-6xl | 60px (3.75rem) | 1 | Display |
text-7xl | 72px (4.5rem) | 1 | Large display |
text-8xl | 96px (6rem) | 1 | XL display |
text-9xl | 128px (8rem) | 1 | XXL display |
Зверніть увагу на перехід при text-5xl: від line-height: 28px до line-height: 1. Для великих декоративних заголовків рівний числовий line-height небажаний — він додає зайвий простір між рядками. Значення 1 означає «line-height дорівнює font-size», що є стандартом для дисплейної типографіки.
<!-- Коректна типографічна ієрархія сторінки -->
<header>
<!-- Eyebrow: UPPERCASE + widest tracking — маленький але помітний -->
<p class="text-xs font-bold uppercase tracking-widest text-indigo-500">
Продукт · Версія 4.0
</p>
<!-- H1: великий, щільний, читабельний -->
<h1 class="text-4xl md:text-5xl font-black tracking-tight text-slate-900 mt-2">
Головний заголовок сторінки
</h1>
<!-- Lead: більший body text для вступного абзацу -->
<p class="text-lg md:text-xl text-slate-600 leading-relaxed mt-4 max-w-2xl">
Вступний абзац. Трохи більший за основний текст,
із relaxed line-height для кращої читабельності.
</p>
</header>
<main>
<!-- H2: секція -->
<h2 class="text-2xl font-bold text-slate-900 mt-12 mb-4">
Підзаголовок секції
</h2>
<!-- Body text -->
<p class="text-base text-slate-700 leading-relaxed">
Основний текст сторінки. text-base + leading-relaxed —
золотий стандарт читабельності для довгого контенту.
</p>
<!-- Caption / metadata -->
<p class="text-xs text-slate-400 font-medium mt-6">
Оновлено: 3 червня 2025 · 5 хв читання
</p>
</main>
Перевизначення line-height: точне налаштування
Незважаючи на вбудований line-height, його часто потрібно явно перевизначити. Tailwind надає іменовані та числові варіанти:
<!-- Іменовані значення -->
<p class="text-base leading-none"> line-height: 1 — для заголовків, кнопок</p>
<p class="text-base leading-tight"> line-height: 1.25 — компактний текст</p>
<p class="text-base leading-snug"> line-height: 1.375</p>
<p class="text-base leading-normal"> line-height: 1.5 — базовий стандарт</p>
<p class="text-base leading-relaxed"> line-height: 1.625 — довгий читабельний текст</p>
<p class="text-base leading-loose"> line-height: 2 — дуже розріджений</p>
<!-- Числові (в rem, на основі spacing-шкали) -->
<p class="leading-4"> /* 1rem = 16px */</p>
<p class="leading-5"> /* 1.25rem = 20px */</p>
<p class="leading-6"> /* 1.5rem = 24px */</p>
<p class="leading-7"> /* 1.75rem = 28px */</p>
<p class="leading-8"> /* 2rem = 32px */</p>
<p class="leading-9"> /* 2.25rem = 36px */</p>
<p class="leading-10"> /* 2.5rem = 40px */</p>
text-base leading-relaxed або text-lg leading-relaxed. Це золотий стандарт читабельності. leading-relaxed (1.625) дає оптимальний повітряний простір між рядками при читанні довгих блоків тексту.Font Weight: від thin до black
Жирність шрифту є одним із головних інструментів типографічної ієрархії. Tailwind надає дев'ять ступенів жирності, що відповідають стандартній CSS-шкалі ваг:
<p class="font-thin"> 100 — Ultra Thin: декоративні великі заголовки</p>
<p class="font-extralight"> 200 — Extra Light: елегантна легкість</p>
<p class="font-light"> 300 — Light: довгі тексти з великим шрифтом</p>
<p class="font-normal"> 400 — Normal (Regular): стандартний body text</p>
<p class="font-medium"> 500 — Medium: secondary UI, підписи до label</p>
<p class="font-semibold"> 600 — Semi Bold: label, badge, caption заголовок</p>
<p class="font-bold"> 700 — Bold: стандартний заголовок</p>
<p class="font-extrabold"> 800 — Extra Bold: акцентні заголовки</p>
<p class="font-black"> 900 — Black: hero title, display typography</p>
system-ui, Georgia) зазвичай підтримують 400 та 700. При підключенні Google Fonts явно вказуйте потрібні ваги у параметрах запиту, щоб не завантажувати весь шрифтовий файл: family=Inter:wght@400;500;600;700;800;900.Letter Spacing та Text Transform
Letter spacing та трансформація тексту — два інструменти, що разом утворюють характерний дизайнерський патерн. tracking-widest uppercase із малим розміром і font-semibold — це класичний label-стиль, що зустрічається у більшості premium продуктів:
<!-- Tracking (letter-spacing) -->
<h1 class="tracking-tighter"> -0.05em — дуже компактний, для великих display</h1>
<h1 class="tracking-tight"> -0.025em — щільний заголовок (часто для text-4xl+)</h1>
<p class="tracking-normal"> 0 — стандарт (default)</p>
<p class="tracking-wide"> 0.025em — легко розширений</p>
<span class="tracking-wider"> 0.05em</span>
<span class="text-xs uppercase tracking-widest font-semibold text-slate-400">
0.1em — LABEL СТИЛЬ (категорія, метадані, eyebrow text)
</span>
<!-- Text Transform -->
<p class="uppercase"> ВЕЛИКІ ЛІТЕРИ — для labels та акцентів</p>
<p class="lowercase"> малі літери — для спеціальних ефектів</p>
<p class="capitalize"> Перша Велика В Кожному Слові</p>
<p class="normal-case"> Скидання трансформації</p>
Text Decoration: підкреслення та strike-through
<!-- Базові варіанти підкреслення -->
<a class="underline">Стандартне підкреслення</a>
<a class="underline underline-offset-2">Зміщення 2px від базової лінії</a>
<a class="underline underline-offset-4">Зміщення 4px — популярний сучасний стиль</a>
<!-- Колір та товщина -->
<a class="underline decoration-indigo-500 underline-offset-4">Кольорове підкреслення</a>
<a class="underline decoration-2 underline-offset-4">Товщина 2px</a>
<!-- Стиль лінії -->
<a class="underline decoration-dotted underline-offset-4">Крапкове</a>
<a class="underline decoration-dashed underline-offset-4">Пунктирне</a>
<a class="underline decoration-wavy underline-offset-4 decoration-red-500">Хвилясте (помилка)</a>
<!-- Інші декорації -->
<p class="line-through text-slate-400">Викреслений текст (ціна зі знижкою)</p>
<p class="no-underline">Скасувати підкреслення</p>
<!-- Font Style -->
<p class="italic">Курсив — для цитат, визначень, іноземних слів</p>
<p class="not-italic">Скасувати курсив</p>
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-6 bg-slate-50 font-sans space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-2xl mx-auto">
<!-- Weights & Tracking -->
<div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm space-y-4">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest">Font Weight & Tracking</p>
<div class="space-y-2">
<p class="font-thin text-2xl tracking-tight text-slate-800">Thin (100) tracking-tight</p>
<p class="font-normal text-base text-slate-700">Normal (400) regular body text</p>
<p class="font-semibold text-sm tracking-wide text-slate-800">Semibold (600) tracking-wide</p>
<p class="font-black text-xl tracking-tighter uppercase text-slate-900">Black (900) tracking-tighter</p>
<span class="text-[10px] font-bold uppercase tracking-widest text-indigo-500 block">widest uppercase label</span>
</div>
</div>
<!-- Line Heights -->
<div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm space-y-4">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest">Line Heights (leading)</p>
<div class="space-y-3">
<div>
<span class="text-[9px] font-mono text-slate-400">leading-none (1.0)</span>
<p class="text-xs leading-none text-slate-700 max-w-xs mt-1">Цей абзац має мінімальну висоту рядка, слова майже торкаються одне одного.</p>
</div>
<div>
<span class="text-[9px] font-mono text-slate-400">leading-normal (1.5)</span>
<p class="text-xs leading-normal text-slate-700 max-w-xs mt-1">Це стандартний інтервал для більшості UI елементів та невеликих текстів.</p>
</div>
<div>
<span class="text-[9px] font-mono text-slate-400">leading-loose (2.0)</span>
<p class="text-xs leading-loose text-slate-700 max-w-xs mt-1">Дуже великий інтервал, використовується для особливих дизайн-рішень.</p>
</div>
</div>
</div>
<!-- Decorations -->
<div class="bg-white p-5 rounded-2xl border border-slate-200 shadow-sm space-y-4 md:col-span-2">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest">Text Decoration & Styles</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm text-slate-700">
<div class="space-y-3">
<div>
<a href="#" onclick="event.preventDefault()" class="underline text-indigo-600">Стандартне підкреслення</a>
</div>
<div>
<a href="#" onclick="event.preventDefault()" class="underline underline-offset-4 text-indigo-600">Зміщення underline-offset-4</a>
</div>
<div>
<a href="#" onclick="event.preventDefault()" class="underline decoration-indigo-500 decoration-2 underline-offset-4">Товщина decoration-2</a>
</div>
</div>
<div class="space-y-3">
<div>
<a href="#" onclick="event.preventDefault()" class="underline decoration-dotted underline-offset-4">Крапкове (decoration-dotted)</a>
</div>
<div>
<a href="#" onclick="event.preventDefault()" class="underline decoration-dashed underline-offset-4">Пунктирне (decoration-dashed)</a>
</div>
<div>
<a href="#" onclick="event.preventDefault()" class="underline decoration-wavy decoration-red-500 underline-offset-4 font-semibold">Хвилясте decoration-wavy</a>
</div>
<div class="pt-1 flex gap-4 text-xs">
<span class="line-through text-slate-400">Стара ціна: 499₴</span>
<span class="italic text-slate-500">Курсивний підпис</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
🧪 Практика: типографічна шкала
Реалізуйте сторінку з повною демонстрацією типографічної ієрархії: від text-9xl до text-xs. Для кожного рівня покажіть: розмір класу, реальне значення у пікселях, рекомендоване призначення. Додайте кожному відповідний font-weight і tracking. Мета — мати живу «шпаргалку» за типографікою.
text-balance та text-pretty: контроль переносів рядків
Проблема «сирітського рядка» та нерівних переносів
Одна з найпоширеніших типографічних проблем у вебі — нерівний розподіл слів між рядками заголовку або «orphan» (одиноке слово на останньому рядку параграфу). До недавнього часу вирішення цих проблем вимагало або JavaScript (бібліотека Balancer.js), або ручного підбору max-width. Tailwind v4 вирішує це нативно через два CSS-значення text-wrap.
text-balance застосовує алгоритм рівномірного розподілу слів між рядками. Браузер намагається зробити всі рядки однакової ширини. Це критично важливо для заголовків: коли одна велика назва розбивається на рядки, природніше, якщо вони мають приблизно однакову довжину, а не перший — довгий, другий — із одним словом.
text-pretty спрямований на запобігання «orphan»: одинокого слова на останньому рядку параграфу. Браузер перебирає варіанти переносу, щоб уникнути такої ситуації.
<!-- Без text-balance: нерівні рядки заголовку -->
<h2 class="text-2xl font-bold max-w-xs text-slate-900">
Довгий заголовок, що нерівномірно розбивається
між рядками і виглядає погано
</h2>
<!-- Результат: перший рядок повний, другий — 2 слова -->
<!-- З text-balance: рівномірні рядки -->
<h2 class="text-balance text-2xl font-bold max-w-xs text-slate-900">
Довгий заголовок, що нерівномірно розбивається
між рядками і виглядає погано
</h2>
<!-- Результат: обидва рядки приблизно однакові -->
<!-- text-pretty: без orphan у параграфах -->
<p class="text-pretty text-slate-600 leading-relaxed max-w-md">
Це довгий параграф, який без text-pretty міг би закінчуватися
одним-єдиним словом на останньому рядку, що виглядає некрасиво
і порушує читабельність тексту.
</p>
text-balance має невеликий вплив на продуктивність при великій кількості елементів, бо алгоритм є обчислювально дорогим. Рекомендується застосовувати лише до заголовків (h1, h2, h3), а не до довгого body text. Для параграфів — text-pretty.Truncate та Line Clamp: обрізання тексту
Обрізання тексту — неодмінна вимога при роботі з динамічним контентом. Довжина назви продукту, опису або заголовку новини непередбачувана. Tailwind надає два механізми:
<!-- Truncate: один рядок із "..." -->
<h3 class="truncate text-slate-900 font-semibold">
Дуже довга назва товару, яка не має влазити в картку
</h3>
<!-- Вимагає: parent з фіксованою або обмеженою шириною -->
<!-- Line Clamp: обрізання після N рядків -->
<p class="line-clamp-1 text-slate-600">Один рядок максимум</p>
<p class="line-clamp-2 text-slate-600">
Два рядки максимум. Весь контент після другого рядка обрізається
і замінюється трьома крапками незалежно від кількості слів.
</p>
<p class="line-clamp-3 text-slate-600">
Три рядки максимум. Особливо корисно для карток із описом товару
або анотацією статті, де дизайн передбачає фіксовану висоту картки.
</p>
<p class="line-clamp-none">Скасувати line-clamp (напр. при розгортанні)</p>
line-clamp-{n} реалізований через комбінацію -webkit-line-clamp, display: -webkit-box та overflow: hidden. Незважаючи на webkit-префікс, він підтримується всіма сучасними браузерами.
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-8 bg-slate-50 font-sans space-y-8">
<!-- text-balance порівняння -->
<div>
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-4">text-balance vs без</p>
<div class="grid grid-cols-2 gap-4">
<div class="bg-white rounded-xl p-5 border border-red-100">
<p class="text-xs font-semibold text-red-400 uppercase tracking-widest mb-3">Без text-balance ✗</p>
<h2 class="text-xl font-bold text-slate-900 max-w-[180px]">Заголовок що розбивається нерівномірно</h2>
</div>
<div class="bg-white rounded-xl p-5 border border-green-100">
<p class="text-xs font-semibold text-green-500 uppercase tracking-widest mb-3">З text-balance ✓</p>
<h2 class="text-balance text-xl font-bold text-slate-900 max-w-[180px]">Заголовок що розбивається нерівномірно</h2>
</div>
</div>
</div>
<!-- Типографічна ієрархія -->
<div class="bg-white rounded-2xl border border-slate-200 p-6">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-5">Типографічна ієрархія</p>
<article class="space-y-3 max-w-sm">
<span class="text-xs font-bold uppercase tracking-widest text-indigo-500">Технології · 5 хв</span>
<h1 class="text-3xl font-black tracking-tight text-slate-900 leading-tight text-balance">
Tailwind CSS v4: що нового
</h1>
<p class="text-lg text-indigo-600 font-medium leading-snug">
Lead paragraph — більший, акцентний вступ до статті.
</p>
<p class="text-base text-slate-700 leading-relaxed text-pretty">
Основний текст. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ось як виглядає звичайний абзац із relaxed line-height і text-pretty.
</p>
<p class="text-sm text-slate-400 leading-relaxed">
Додаткова інформація меншим шрифтом і приглушеним кольором.
</p>
</article>
</div>
<!-- Line Clamp -->
<div class="bg-white rounded-2xl border border-slate-200 p-6">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-4">line-clamp у картках</p>
<div class="grid grid-cols-2 gap-4">
<div class="border border-slate-200 rounded-xl p-4">
<div class="w-full h-28 bg-gradient-to-br from-indigo-100 to-purple-100 rounded-lg mb-3"></div>
<span class="text-xs font-bold uppercase tracking-widest text-indigo-500">Дизайн</span>
<h3 class="font-bold text-slate-900 text-sm mt-1 line-clamp-2">
Дуже довга назва картки, яка має обрізатися після двох рядків і показувати три крапки
</h3>
<p class="text-xs text-slate-500 mt-2 line-clamp-3 leading-relaxed">
Опис картки, що обрізається після третього рядка. Lorem ipsum dolor sit amet consectetur adipiscing elit. Продовження тексту, що не буде показане.
</p>
</div>
<div class="border border-slate-200 rounded-xl p-4">
<div class="w-full h-28 bg-gradient-to-br from-emerald-100 to-teal-100 rounded-lg mb-3"></div>
<span class="text-xs font-bold uppercase tracking-widest text-emerald-600">Код</span>
<h3 class="font-bold text-slate-900 text-sm mt-1 line-clamp-2">
Коротка назва
</h3>
<p class="text-xs text-slate-500 mt-2 line-clamp-3 leading-relaxed">
Короткий опис. Обрізання не відбувається, якщо тексту менше N рядків.
</p>
</div>
</div>
</div>
</body>
</html>
🧪 Практика: картки з динамічним текстом
Реалізуйте 4 картки статей у сітці 2×2. Заголовок кожної — line-clamp-2, опис — line-clamp-3. Навмисно задайте різну довжину тексту (від 5 слів до 50 слів). Переконайтеся, що всі картки мають однакову висоту через h-full і flexbox. Заголовок картки — text-balance. Категорія — text-xs uppercase tracking-widest font-bold.
Font Family: підключення кастомних шрифтів
Системні шрифти: font-sans, font-serif, font-mono
Tailwind надає три базові сімейства шрифтів, що використовують системні стеки:
<!-- system-ui, -apple-system, BlinkMacSystemFont, Segoe UI... -->
<body class="font-sans">Основний шрифт додатку (sans-serif)</body>
<!-- Georgia, Cambria, Times New Roman... -->
<blockquote class="font-serif">Цитата у серифному шрифті</blockquote>
<!-- ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas... -->
<code class="font-mono bg-slate-100 px-1 rounded">const x = 1</code>
Підключення Google Fonts
У Tailwind v4 кастомні шрифти підключаються через @theme:
Метод 1: <link> у HTML + @theme у CSS (рекомендований)
<!-- index.html: preconnect для швидшого завантаження -->
<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;800;900&display=swap"
rel="stylesheet"
>
/* main.css */
@import 'tailwindcss';
@theme {
--font-sans: 'Inter', system-ui, sans-serif;
}
Метод 2: @import у CSS
/* УВАГА: @import url() має бути ПЕРШИМ у файлі — до @import 'tailwindcss' */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&family=Playfair+Display:ital,wght@0,700;1,700&display=swap');
@import 'tailwindcss';
@theme {
--font-sans: 'Inter', system-ui, sans-serif;
--font-display: 'Playfair Display', Georgia, serif;
}
Метод 3: Локальні шрифти через @font-face
@import 'tailwindcss';
/* Оголошення локального шрифту (variable font) */
@font-face {
font-family: 'BrandFont';
src: url('/fonts/brand-variable.woff2') format('woff2-variations');
font-weight: 100 900; /* Весь діапазон ваг для variable font */
font-style: normal;
font-display: swap; /* Показати системний шрифт під час завантаження */
}
@font-face {
font-family: 'BrandFont';
src: url('/fonts/brand-variable-italic.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: italic;
font-display: swap;
}
@theme {
--font-sans: 'BrandFont', system-ui, sans-serif;
--font-brand: 'BrandFont', sans-serif;
}
| Метод | Коли використовувати | Переваги | Недоліки |
|---|---|---|---|
<link> у HTML | Next.js, Nuxt, статичні сайти | Найшвидше завантаження (preconnect, preload) | Потрібна зміна HTML-шаблону |
@import у CSS | Прості проекти, швидкий старт | Все в CSS | Може блокувати рендер якщо першим |
@font-face | Корпоративні та брендові шрифти | Повний контроль, офлайн-підтримка | Потрібно хостити файли |
Після реєстрації у @theme шрифт використовується через стандартні класи font-{name}:
<h1 class="font-display font-black tracking-tight">
Заголовок на display-шрифті (Playfair Display)
</h1>
<p class="font-sans">
Основний текст на Inter
</p>
<code class="font-mono text-sm">
Код на mono шрифті
</code>
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<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;700&family=Playfair+Display:ital,wght@0,700;1,700&family=JetBrains+Mono&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
display: ['Playfair Display', 'Georgia', 'serif'],
mono: ['JetBrains Mono', 'monospace']
}
}
}
}
</script>
</head>
<body class="p-6 bg-slate-50 font-sans flex flex-col items-center">
<div class="w-full max-w-md bg-white p-6 rounded-2xl shadow-md border border-slate-100 space-y-6">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest">Демонстрація шрифтових сімейств</p>
<!-- font-display -->
<div class="border-b border-slate-100 pb-4">
<span class="text-[9px] font-mono text-slate-400 block mb-1">font-display (Playfair Display)</span>
<h3 class="font-display font-bold text-2xl text-slate-900 leading-tight">
Playfair Display — елегантна <span class="italic text-indigo-600">антиква</span> для заголовків.
</h3>
</div>
<!-- font-sans -->
<div class="border-b border-slate-100 pb-4">
<span class="text-[9px] font-mono text-slate-400 block mb-1">font-sans (Inter)</span>
<p class="font-sans text-sm text-slate-600 leading-relaxed">
Inter — сучасний високочитабельний гротеск для основного тексту, інтерфейсів, кнопок та підписів.
</p>
</div>
<!-- font-mono -->
<div>
<span class="text-[9px] font-mono text-slate-400 block mb-1">font-mono (JetBrains Mono)</span>
<code class="font-mono text-xs text-violet-600 bg-violet-50 px-2 py-1 rounded block w-fit border border-violet-100">
const framework = "Tailwind CSS v4";
</code>
</div>
</div>
</body>
</html>
🧪 Практика: підключення Google Fonts
Підключіть два шрифти: Inter (sans, ваги 400;600;700;900) та Playfair Display (serif, ваги 700 normal і 700 italic). Визначте --font-sans: Inter і --font-display: Playfair Display у @theme. Реалізуйте hero-секцію: заголовок на font-display font-bold italic, підзаголовок та тіло — на font-sans. Перевірте у DevTools вкладку Network, що шрифти справді завантажились.
@tailwindcss/typography: плагін prose
Проблема стилізації довільного HTML-контенту
Tailwind за замовчуванням скидає всі браузерні стилі через Preflight (@layer base). Це зручно при створенні власного UI, але стає проблемою, коли потрібно відобразити довільний HTML-контент — наприклад, результат рендерингу Markdown або відповідь з CMS. Елементи <h1>, <p>, <ul>, <blockquote> виглядатимуть однаково без стилів.
Рішення — плагін @tailwindcss/typography з класом prose, що надає повний набір типографічних стилів для семантичного HTML-контенту.
Встановлення
npm install @tailwindcss/typography
/* main.css */
@import 'tailwindcss';
@import '@tailwindcss/typography';
Базове використання
<!-- Один клас prose — весь контент всередині стилізується автоматично -->
<article class="prose">
<h1>Заголовок статті</h1>
<p>Перший параграф із <strong>жирним</strong> текстом і <a href="#">посиланням</a>.</p>
<h2>Підзаголовок секції</h2>
<ul>
<li>Пункт зі стилізованим маркером</li>
<li>Другий пункт</li>
</ul>
<ol>
<li>Нумерований список</li>
<li>Автоматична нумерація</li>
</ol>
<pre><code>const x = 1; // Стилізований code-block</code></pre>
<blockquote>
Цитата з автоматичним лівим бордером і курсивом.
</blockquote>
<hr />
<table>
<thead><tr><th>Колонка 1</th><th>Колонка 2</th></tr></thead>
<tbody><tr><td>Дані 1</td><td>Дані 2</td></tr></tbody>
</table>
</article>
prose стилізує автоматично: h1–h6, p, a, ul/ol/li, blockquote, code, pre, hr, table, img, figure, figcaption, strong, em.
Розміри prose
<article class="prose prose-sm"> <!-- Компактний: text-sm як основа --></article>
<article class="prose"> <!-- Стандартний: text-base --></article>
<article class="prose prose-lg"> <!-- Великий: text-lg --></article>
<article class="prose prose-xl"> <!-- Дуже великий: text-xl --></article>
<article class="prose prose-2xl"> <!-- Максимальний: text-2xl --></article>
Dark Mode та кастомізація кольору посилань
<!-- prose-invert: автоматична адаптація до темної теми -->
<article class="prose dark:prose-invert">
<!-- Колір тексту, посилань, заголовків адаптується автоматично -->
</article>
<!-- prose-{color}: колір акцентних елементів (посилання, маркери) -->
<article class="prose prose-indigo"> <!-- Індиго посилання --></article>
<article class="prose prose-violet"> <!-- Фіолетові посилання --></article>
<article class="prose prose-slate"> <!-- Нейтральні --></article>
<!-- Повна комбінація для реального проєкту -->
<article class="prose prose-lg prose-indigo dark:prose-invert max-w-2xl mx-auto">
<!-- Великий, індиго акценти, темний режим, обмежена ширина -->
</article>
Кастомізація prose через CSS
Для глибшої кастомізації prose-стилів — CSS-змінні або @layer:
@layer base {
.prose {
/* Перевизначення кольору заголовків */
--tw-prose-headings: oklch(0.2 0.05 264);
/* Перевизначення кольору посилань */
--tw-prose-links: oklch(0.58 0.22 277);
/* Перевизначення кольору code */
--tw-prose-code: oklch(0.55 0.2 330);
}
}
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com"></script>
<script>tailwind.config = { plugins: [] }</script>
<style>
/* Мімікрія prose без плагіну для демо */
.prose-demo h1 { font-size: 2rem; font-weight: 800; color: #0f172a; margin-bottom: 0.5rem; line-height: 1.2; }
.prose-demo h2 { font-size: 1.4rem; font-weight: 700; color: #0f172a; margin: 1.5rem 0 0.5rem; border-bottom: 1px solid #e2e8f0; padding-bottom: 0.5rem; }
.prose-demo p { color: #334155; line-height: 1.75; margin-bottom: 1rem; }
.prose-demo a { color: #6366f1; text-decoration: underline; text-decoration-color: #a5b4fc; text-underline-offset: 3px; }
.prose-demo ul { list-style: disc; padding-left: 1.5rem; color: #475569; line-height: 2; }
.prose-demo blockquote { border-left: 4px solid #6366f1; padding-left: 1rem; color: #64748b; font-style: italic; margin: 1.5rem 0; }
.prose-demo code { background: #f1f5f9; color: #7c3aed; padding: 0.1em 0.4em; border-radius: 0.25rem; font-family: monospace; font-size: 0.875em; }
.prose-demo pre { background: #1e293b; color: #e2e8f0; padding: 1rem; border-radius: 0.75rem; overflow-x: auto; font-family: monospace; font-size: 0.875rem; margin: 1rem 0; }
.prose-demo strong { color: #1e293b; font-weight: 700; }
</style>
</head>
<body class="p-8 bg-slate-50 font-sans">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-5">prose плагін — стилізація довільного HTML</p>
<div class="bg-white rounded-2xl border border-slate-200 p-8 max-w-2xl mx-auto shadow-sm">
<article class="prose-demo">
<h1>Tailwind CSS v4: повний огляд</h1>
<p>Tailwind CSS v4 представляє <strong>революційний підхід</strong> до конфігурації: замість JavaScript-файлу — CSS-директива <code>@theme</code>.</p>
<blockquote>«CSS-first конфігурація змінює спосіб мислення про дизайн-систему» — Adam Wathan</blockquote>
<h2>Ключові зміни</h2>
<ul>
<li>OKLCH кольорова система</li>
<li>Lightning CSS замість PostCSS</li>
<li>Нові варіанти: <code>has-*</code>, <code>not-*</code>, <code>starting:</code></li>
</ul>
<h2>Приклад коду</h2>
<pre>@theme {
--color-brand: oklch(0.58 0.22 277);
--font-sans: 'Inter', system-ui;
}</pre>
<p>Посилання в prose: <a href="#">офіційна документація Tailwind</a> та <a href="#">репозиторій на GitHub</a>.</p>
</article>
</div>
</body>
</html>
🧪 Практика: повна сторінка статті
Реалізуйте сторінку блог-статті зі структурою: (1) навбар із назвою сайту, (2) hero-секція: eyebrow, h1 із text-balance, lead-paragraph, метадані (автор, дата, час читання), (3) <article class="prose prose-lg prose-indigo dark:prose-invert"> із повним markdown-контентом (h2, h3, p, ul, ol, blockquote, code, pre), (4) footer з навігацією «попередня/наступна стаття». Додайте dark:prose-invert і кнопку перемикання теми.
Практичні патерни: типографіка в реальному UI
Label-стиль: UPPERCASE + tracking-widest
Найпоширеніший типографічний патерн у premium-дизайні — мітки категорій, розділів, підписів. Формула: text-xs font-bold uppercase tracking-widest + колір:
<!-- Мітка категорії над заголовком (eyebrow text) -->
<p class="text-xs font-bold uppercase tracking-widest text-indigo-500">
Технології
</p>
<!-- Підпис до секції -->
<span class="text-xs font-semibold uppercase tracking-widest text-slate-400">
Останні новини
</span>
<!-- Badge із фоном -->
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full
text-xs font-bold uppercase tracking-wider
bg-green-100 text-green-800">
Активний
</span>
<!-- Metadata рядок -->
<div class="flex items-center gap-2 text-xs text-slate-400 font-medium">
<span>3 червня 2025</span>
<span>·</span>
<span>5 хв читання</span>
<span>·</span>
<time>Оновлено сьогодні</time>
</div>
Hero типографіка: масштаб та баланс
<section class="text-center px-4 py-24">
<!-- Eyebrow: маленький, але помітний -->
<p class="text-sm font-bold uppercase tracking-widest text-indigo-500 mb-4">
Нові можливості v4.0
</p>
<!-- H1: великий, щільний, збалансований -->
<h1 class="text-5xl md:text-6xl lg:text-7xl font-black tracking-tight
text-slate-900 text-balance mx-auto max-w-4xl leading-[0.95]">
Tailwind CSS v4 —<br class="hidden md:block" />
<span class="text-transparent bg-clip-text bg-gradient-to-r from-indigo-500 to-violet-500">
майбутнє вже тут
</span>
</h1>
<!-- Lead paragraph: більший, читабельний, обмежена ширина -->
<p class="text-lg md:text-xl text-slate-600 leading-relaxed text-pretty
max-w-2xl mx-auto mt-6">
CSS-first конфігурація, OKLCH кольори та Lightning CSS engine.
Менше конфігурації, більше можливостей — для команд будь-якого розміру.
</p>
<!-- CTA кнопки -->
<div class="flex flex-col sm:flex-row gap-4 justify-center mt-10">
<a href="#" class="px-8 py-4 bg-indigo-600 hover:bg-indigo-700
text-white font-semibold rounded-xl text-base
transition-colors shadow-lg shadow-indigo-500/25">
Почати безкоштовно
</a>
<a href="#" class="px-8 py-4 border-2 border-slate-200 hover:border-slate-300
text-slate-700 font-semibold rounded-xl text-base
transition-colors">
Документація →
</a>
</div>
</section>
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">
</head>
<body class="bg-white font-sans" style="font-family: 'Inter', system-ui, sans-serif;">
<!-- Hero Section -->
<section class="text-center px-6 py-20 bg-gradient-to-b from-slate-50 to-white">
<p class="text-xs font-bold uppercase tracking-widest text-indigo-500 mb-5">
Нові можливості · Tailwind v4.0
</p>
<h1 class="text-4xl md:text-6xl font-black tracking-tight text-slate-900 text-balance max-w-2xl mx-auto leading-tight mb-6">
Типографіка та кольори<br>
<span class="bg-clip-text text-transparent bg-gradient-to-r from-indigo-500 via-violet-500 to-purple-600">
нового покоління
</span>
</h1>
<p class="text-lg text-slate-600 leading-relaxed text-pretty max-w-xl mx-auto mb-10">
OKLCH-кольори, text-balance, prose плагін та повна типографічна система для сучасного UI.
</p>
<div class="flex gap-3 justify-center flex-wrap">
<button class="px-6 py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-xl text-sm transition-all shadow-lg shadow-indigo-500/20 active:scale-95">
Почати вивчення
</button>
<button class="px-6 py-3 border-2 border-slate-200 hover:border-indigo-300 text-slate-700 font-semibold rounded-xl text-sm transition-all">
Документація →
</button>
</div>
</section>
<!-- Кольорова палітра -->
<section class="px-6 py-12 bg-slate-50">
<p class="text-xs font-bold uppercase tracking-widest text-slate-400 text-center mb-6">Opacity modifiers + glassmorphism</p>
<div class="max-w-lg mx-auto">
<div class="relative h-28 bg-gradient-to-r from-violet-500 to-indigo-500 rounded-2xl flex items-center justify-center gap-3 p-4">
<div class="bg-white/10 backdrop-blur-sm border border-white/20 rounded-xl px-4 py-2 text-white text-sm font-semibold">/10</div>
<div class="bg-white/20 backdrop-blur-md border border-white/30 rounded-xl px-4 py-2 text-white text-sm font-semibold">/20</div>
<div class="bg-white/30 backdrop-blur-md border border-white/40 rounded-xl px-4 py-2 text-white text-sm font-semibold">/30</div>
<div class="bg-black/20 backdrop-blur-sm border border-white/10 rounded-xl px-4 py-2 text-white text-sm font-semibold">black/20</div>
</div>
</div>
</section>
<!-- Картки із line-clamp -->
<section class="px-6 py-12 bg-white">
<p class="text-xs font-bold uppercase tracking-widest text-slate-400 text-center mb-6">line-clamp у картках</p>
<div class="grid grid-cols-3 gap-4 max-w-2xl mx-auto">
<div class="border border-slate-200 rounded-xl p-4 flex flex-col">
<span class="text-xs font-bold uppercase tracking-widest text-indigo-500">Дизайн</span>
<h3 class="font-bold text-slate-900 text-sm mt-2 line-clamp-2 flex-shrink-0">Дуже довга назва, що обрізається після двох рядків обов'язково</h3>
<p class="text-xs text-slate-500 mt-2 line-clamp-3 leading-relaxed">Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt.</p>
<p class="text-xs text-slate-400 mt-auto pt-3">3 хв читання</p>
</div>
<div class="border border-slate-200 rounded-xl p-4 flex flex-col">
<span class="text-xs font-bold uppercase tracking-widest text-emerald-600">Код</span>
<h3 class="font-bold text-slate-900 text-sm mt-2 line-clamp-2">Коротка назва</h3>
<p class="text-xs text-slate-500 mt-2 line-clamp-3 leading-relaxed">Короткий опис без обрізання.</p>
<p class="text-xs text-slate-400 mt-auto pt-3">1 хв читання</p>
</div>
<div class="border border-slate-200 rounded-xl p-4 flex flex-col">
<span class="text-xs font-bold uppercase tracking-widest text-violet-600">Архітектура</span>
<h3 class="font-bold text-slate-900 text-sm mt-2 line-clamp-2 text-balance">Назва з text-balance для рівномірних рядків</h3>
<p class="text-xs text-slate-500 mt-2 line-clamp-3 leading-relaxed text-pretty">Опис із text-pretty для уникнення одиноких слів на останньому рядку параграфу.</p>
<p class="text-xs text-slate-400 mt-auto pt-3">7 хв читання</p>
</div>
</div>
</section>
</body>
</html>
Завдання для самоперевірки
Завдання 1.1. Типографічна шкала.
Реалізуйте живу шпаргалку: відобразіть всі ступені text-xs → text-9xl на одній сторінці. Кожен елемент має підпис: назва класу, розмір у пікселях, рекомендоване призначення. Для text-5xl і вище — font-black tracking-tight, для тексту — font-normal leading-relaxed.
Завдання 1.2. Декодування класів.
Поясніть словами, що робить кожен клас:
<article class="max-w-prose mx-auto">
<p class="text-xs font-bold uppercase tracking-widest text-indigo-500 mb-2">
Категорія
</p>
<h1 class="text-4xl font-black tracking-tight text-balance text-slate-900">
Заголовок статті
</h1>
<p class="text-lg text-slate-600 leading-relaxed text-pretty mt-4 line-clamp-3">
Lead paragraph із обрізанням після трьох рядків...
</p>
<div class="border border-indigo-500/30 bg-indigo-500/5 rounded-xl p-4 mt-6">
Блок із opacity modifier
</div>
</article>
Завдання 1.3. Картки з динамічним текстом.
Реалізуйте 4 картки у сітці 2×2. Кожна картка: категорія (label-стиль), заголовок (line-clamp-2 text-balance), опис (line-clamp-3 text-pretty), дата + час читання. Навмисно задайте різну довжину тексту — картки повинні мати однакову висоту через flex flex-col + mt-auto для footer картки.
Завдання 2.1. Hero-секція лендінгу.
Реалізуйте повну hero-секцію:
- Eyebrow:
text-xs font-bold uppercase tracking-widest text-indigo-500 - H1:
text-5xl md:text-7xl font-black tracking-tight text-balance+ gradient text черезbg-clip-text text-transparent bg-gradient-to-r - Lead paragraph:
text-xl text-slate-600 leading-relaxed text-pretty max-w-2xl - Дві CTA кнопки: primary (bg-indigo-600 + shadow) та secondary (border-2)
- Адаптивно:
flex-col sm:flex-rowдля кнопок
Завдання 2.2. Glassmorphism картка.
На градієнтному фоні реалізуйте glassmorphism картку:
bg-white/10 backdrop-blur-md border border-white/20для картки- Вкладена іконка з
bg-white/20таbackdrop-blur-sm - Текст:
text-whiteдля заголовку,text-white/70для тіла - Лінія-розділювач:
border-white/20 - Внизу: stats-рядок із
text-white/60
Завдання 2.3. Кольорова система у @theme.
Визначте повну кольорову систему для SaaS-дашборду:
@theme {
/* Бренд: 9 відтінків через OKLCH */
--color-brand-50: oklch(0.97 0.01 277);
/* ... */
--color-brand-900: oklch(0.25 0.08 277);
/* Семантичні токени */
--color-bg: /* light фон */;
--color-surface: /* картки */;
--color-text: /* основний текст */;
--color-muted: /* приглушений */;
--color-accent: /* CTA елементи */;
}
Реалізуйте кнопку, badge та картку використовуючи лише семантичні токени.
Завдання 3.1. Повна сторінка документації.
┌─────────────────────────────────────────────────────┐
│ Navbar: sticky, logo + nav links │
├─────────┬───────────────────────────┬───────────────┤
│ Sidebar │ <article> │ TOC │
│ (nav) │ prose prose-lg │ (sticky) │
│ sticky │ prose-indigo │ │
│ │ dark:prose-invert │ │
│ │ max-w-prose │ │
└─────────┴───────────────────────────┴───────────────┘
Вимоги:
- Sidebar: sticky
top-16, список посилань ізdata-[state=active]:для активного пункту - Контент:
prose prose-lg prose-indigo dark:prose-invertіз повним HTML (h1-h3, p, ul, ol, code, pre, blockquote, table) - TOC:
sticky top-20, посилання на якоря dark:prose-invert+ кнопка перемикання теми- Адаптивно: sidebar прихований на мобільному, TOC — на
xl:і вище
Завдання 3.2. Повна система бренд-кольорів.
Реалізуйте design system page — сторінку, що документує кольорову систему проєкту:
- Відобразити всі 9 відтінків бренд-кольору з їх OKLCH-значеннями
- Показати semantic tokens: назва токену, CSS-змінна, hex-значення, приклад застосування
- Перевірка контрасту: поряд із кожним текстовим кольором показати оцінку WCAG AA/AAA
- Переключення light/dark теми — tokeni змінюються, демо оновлюються автоматично
Попередня стаття: Варіанти: hover, focus та нові v4Наступна стаття: Компоненти: @apply, @utility та патерни
Варіанти: hover, focus, responsive, dark mode та нові v4
Повний академічний розбір системи варіантів Tailwind CSS v4: стани взаємодії, structural pseudo-classes, group та peer, нові варіанти has-*, not-*, nth-*, starting:, адаптивні breakpoints та dark mode. З живими прикладами та практичними завданнями.
Компоненти та повторюваність: @apply, @utility та патерни
Академічний розбір вирішення проблеми повторюваності у Tailwind CSS v4: компонентний підхід, @apply для виняткових випадків, @utility для кастомних утиліт, @layer base/components, @custom-variant та @plugin. Повний набір реальних компонентів із живими прикладами.