Своя типографика
Шрифты через next/font, шкала текста как токены и составные стили через @utility.
Обновлено
Что значит своя типографика
В дизайне обычно 5–8 фиксированных стилей текста: большой заголовок страницы, заголовки секций, основной текст, мелкий текст, подписи. Каждый стиль = комбинация шрифта + размера + межстрочного интервала + насыщенности + межбуквенного интервала.
Классическая ошибка: комбинацию переписывают вручную везде.
<h1 class="font-display text-[2.75rem] leading-[1.1] font-bold tracking-[-0.02em]">
<!-- ... и те же 5 классов ещё в 30 местах -->Цель: одно имя — text-display, text-h2, text-body, — определённое один раз и используемое везде, как класс. Дизайн меняется в одном месте.
Шаг 1 — шрифты
Загружаете шрифт через next/font (со своего домена, без «прыжка» раскладки) и выставляете его как CSS-переменную:
// app/layout.tsx
import { IBM_Plex_Sans, JetBrains_Mono } from 'next/font/google'
const sans = IBM_Plex_Sans({ variable: '--font-plex-sans', subsets: ['latin', 'cyrillic'], weight: ['400', '500', '600', '700'] })
const mono = JetBrains_Mono({ variable: '--font-jetbrains-mono', subsets: ['latin', 'cyrillic'] })
<html className={`${sans.variable} ${mono.variable}`}>Подмножество cyrillic обязательно для русского текста (а latin-ext — для букв с диакритикой).
Затем сопоставляете их в теме Tailwind:
@theme inline {
--font-sans: var(--font-plex-sans); /* font-sans — по умолчанию на всём сайте */
--font-mono: var(--font-jetbrains-mono); /* font-mono */
--font-display: var(--font-plex-sans); /* font-display — новый класс */
}Шаг 2 — шкала размеров как токены
Каждый --text-* в @theme становится классом text-*. К нему можно привязать межстрочный интервал, межбуквенный интервал и насыщенность — всё применяется одним классом:
@theme {
--text-display: 3rem;
--text-display--line-height: 1.1;
--text-display--letter-spacing: -0.02em;
--text-display--font-weight: 700;
--text-h2: 1.75rem;
--text-h2--line-height: 1.25;
--text-h2--font-weight: 600;
--text-body: 1rem;
--text-body--line-height: 1.65;
--text-caption: 0.8125rem;
--text-caption--line-height: 1.4;
}<h1 class="text-display">Заголовок</h1>
<h2 class="text-h2">Секция</h2>
<p class="text-body text-muted">Абзац</p>
<span class="text-caption">Подпись</span>Работают с любыми вариантами: text-h2 md:text-display.
Если хотите полностью заменить стандартную шкалу (text-sm, text-xl...) своей: --text-*: initial; в начале @theme. Тогда команда сможет использовать только размеры из дизайна.
Шаг 3 — составные стили через @utility
Когда в стиле больше, чем font-size (другой шрифт, text-transform, цвет), создаёте свой утилитарный класс:
@utility text-eyebrow {
font-family: var(--font-mono);
font-size: 0.75rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--color-accent);
}<p class="text-eyebrow md:text-sm">Урок 3</p>@utility лучше обычного CSS-класса: он попадает в слой utilities, работает с вариантами (hover:, md:, dark:) и находится так же, как любой класс Tailwind.
Варианты для типографики — сравнение
| Метод | Когда |
|---|---|
прямые классы Tailwind (text-xl font-semibold) |
один раз, особый случай |
токен --text-* с подсвойствами |
шкала размеров дизайна — по умолчанию |
@utility |
составной стиль со шрифтом / transform / цветом |
компонент <Heading level={2}> |
тег + стиль + логика (например, id для якорей) |
плагин @tailwindcss/typography (prose) |
длинный контент из markdown / CMS — как уроки здесь |
Где их хранить
Всё в одном файле глобальных стилей (app/globals.css или src/app/styles/): цветовые токены, шрифты, шкала текста, свои утилиты. Компоненты их только используют.
Коротко
next/font→ CSS-переменная →@theme inline { --font-* }.--text-имя+--text-имя--line-height / --font-weight / --letter-spacing= полный стиль в одном классе.@utilityдля составных стилей; работает со всеми вариантами.