Типографика
Типографика Framework построена на ролях текста: в разметке выбирают назначение текста, а кегль, высота строки и начертание берутся из роли. Это позволяет менять шрифт и размеры во всём интерфейсе одной переменной.
Роль, а не кегль
Типографика отделяет назначение текста от его размера. В разметке выбирают роль: заголовок, основной текст, подпись. Роль сама знает свой кегль, высоту строки, семейство и начертание и сама меняет их между режимами. Если проект меняет шрифт или кегль, он меняет роль, и это действует везде.
Ролей четыре семейства:
| Роль | Что это | Ступени | Класс | Ступени шкалы |
|---|---|---|---|---|
| Label (подпись) | Подписи контролов, пометки, служебный текст | small, medium, large | .sf-label-small … .sf-label-large |
1/4, 1/3, 1/2 (зафиксированы, Подпись отличается от текста поведением) |
| Body (основной текст) | Абзацы | small, medium, large | .sf-body-small … .sf-body-large |
1/2, 1, 2 |
| Heading (заголовок) | Заголовки текста | 1–6 | .sf-h-1 … .sf-h-6 и h1–h6 |
6, 5, 4, 3, 2, 1 |
| Display (акцент) | Короткий крупный текст и цифры | 1–6 | .sf-display-1 … .sf-display-6 |
12, 11, 10, 9, 8, 7 |
У подписи и основного текста ступени названы словами, а не числами, чтобы их
не путали с номерами заголовков. Заголовки нумеруются в обратную сторону: h1
самый крупный и стоит на ступени 6.
Пример показывает три роли в разметке:
<h2 class="sf-h-2">Заголовок раздела</h2>
<p class="sf-body-medium">Основной текст интерфейса.</p>
<span class="sf-label-small">Служебная подпись</span>
Для точной настройки есть числовые классы .sf-text-1/4 … .sf-text-12, а в
утилитах — text-N (см. Шкала интерфейса: 0, 1/4, 1/3, 1/2, 1…8). Каждый задаёт кегль и высоту строки одной
ступени.
Шкала кегля
Шкала кегля — адаптивная, ступени текста от 1/4 до 12. По величине
шага на настольном экране она делится на три участка:
| Участок | Ступени | Шаг | Пример (наст.) |
|---|---|---|---|
| Малый | 1/4–1/2 |
2 px | 10, 12, 14 |
| Обычный | 1–6 |
4 px | 16, 20 … 36 |
| Крупный | 7–12 |
8 px | 40, 48 … 80 |
На мобильном шаги обычного и крупного участков вдвое мельче, а крупные
ступени заметно меньше (ступень 12: 48 px против 80 px). Малый участок на
мобильном — 10, 12, 12 px.
Пары кегля и высоты строки для каждой ступени в обоих режимах — в справочнике «Значения вертикальных размеров».
Ниже 1/4 в шкале есть служебные ступени --sf-text--size-1/5, 1/6, 1/7
(8, 6, 4 px). Это толщины полос, а не текст: у них нет высоты строки, классов и
утилит.
Литерал 13 px Framework не использует. Ступень b3 в шкале примитивов есть,
но роли текста на ней не стоят.
Высота строки
У текста две семьи высоты строки:
- для основного текста
--sf-text--height-*— примерно 1,5 кегля; - для заголовков
--sf-title--height-*— примерно 1,2 кегля.
В обоих случаях результат округлён вниз до кратного 4 px, а от 80 px —
до кратного 8 px. Например, для
ступени 6 на настольном экране (кегль 36 px): основной текст 36 × 1,5 = 54 →
52 px, заголовок 36 × 1,2 = 43,2 → 40 px. Длинному абзацу нужен воздух между
строками, а заголовок в две строки с таким же воздухом распадается на две
отдельные строки.
Заголовки и акцентный текст берут высоту строки из семьи title, подпись и
основной текст — из семьи text. Числовой класс text-N по умолчанию даёт
высоту основного текста. Модификатор .heading переключает его на высоту
заголовка, не меняя кегль:
<div class="text-6 heading">Крупная надпись в две строки</div>
Кроме ступеней, утилиты высоты строки дают относительные значения:
line-none (1), line-tight (1.25), line-snug (1.375), line-normal (1.5),
line-relaxed (1.625) и line-loose (2) (Высота строки).
Подпись отличается от текста поведением
По кеглю подпись и основной текст местами совпадают, поэтому выбирать между ними по размеру бесполезно. Разница в поведении:
body |
label |
|
|---|---|---|
| Растёт на широком экране | да | нет |
| Несёт нижний отступ абзаца | да | нет |
Абзац растёт вместе с полосой набора и отбивается от соседнего абзаца.
Подпись привязана к контролу, а контрол своего размера от ширины экрана не
меняет. Поэтому все три подписи одинаковы в обоих режимах: small — 10/12,
medium — 12/16, large — 14/20. А .sf-body-small на узком экране даёт 12/16,
на широком — 14/20.
- Если нужен текст, который растёт вместе с экраном, берите
body, а неlabel.
Семейства и начертания
У трёх семейств ролей свои переменные: --sf-text--family,
--sf-heading--family, --sf-display--family. По умолчанию во всех трёх
Inter Variable с одной и той же цепочкой замен:
--sf-text--family: "Inter Variable", "Inter Fallback", system-ui, -apple-system,
Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, "Segoe UI", sans-serif;
Шрифт поставляется вместе с Framework и не загружается с внешних сервисов.
Файлы разбиты по письменностям (unicode-range), поэтому браузер скачивает
только те, что нужны тексту страницы: русской странице хватает латиницы и
кириллицы.
До загрузки Inter работает местная замена Inter Fallback — Arial с
подогнанными метриками. У замены два начертания: обычное (Arial, веса 100–549)
и полужирное (Arial Bold, веса 550–1000), поэтому полужирный текст остаётся
полужирным и на замене. Inter подключается с font-display: optional: при
холодном заходе страница остаётся на замене и не «прыгает» при поздней подмене
шрифта, а при повторных заходах сразу берёт Inter из кеша. Резервировать высоту
или заранее загружать шрифт проекту не нужно.
Начертания задаются токенами веса:
| Токен | Вес | Токен | Вес |
|---|---|---|---|
--sf-weight--thin |
100 | --sf-weight--semi-bold |
600 |
--sf-weight--extra-light |
200 | --sf-weight--bold |
700 |
--sf-weight--light |
300 | --sf-weight--extra-bold |
800 |
--sf-weight--regular |
400 | --sf-weight--black |
900 |
--sf-weight--medium |
500 |
Для утилит и базовых элементов есть и краткие имена:
--sf-font-weight-light (300), --sf-font-weight-regular (400),
--sf-font-weight-medium (500) и --sf-font-weight-bold (700). По умолчанию
основной текст — 400, заголовки — 700, акцентный текст — 300.
Компоненты рисуют подписи, кнопки и поля начертаниями 400 и 500, отдельные
места — 600 и 700, крупные заголовки sf-display-* — 300. Шрифту проекта
нужны начертания 300, 400, 500, 600 и 700 или переменная ось веса;
недостающее начертание браузер синтезирует из ближайшего, и текст выглядит
иначе, чем задумано. Для моноширинного, рубленого шрифта и антиквы есть системные наборы
--sf-mono, --sf-sans, --sf-serif. Код использует --sf-mono.
Поставляемый Inter покрывает латиницу с расширениями, кириллицу, греческий алфавит и вьетнамский. Арабского письма, иврита и письменностей Азии в нём нет: такой текст браузер рисует системным шрифтом из цепочки семейства. Странице на этих языках проект подключает свой шрифт (пример ниже).
Отдельного семейства для контролов нет: поля, кнопки, списки и остальные
компоненты, в том числе Smart, читают --sf-text--family. Смена этой
переменной меняет и их.
Проект, который меняет шрифт, переопределяет переменные семейства и начертания. Роли, адаптивность и ритм при этом сохраняются. Пример подключает шрифт проекта и делает его основным для всех трёх семейств:
@font-face {
font-family: "Project Sans";
src: url("/assets/fonts/project-sans.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
}
@layer project {
:root {
--sf-text--family: "Project Sans", system-ui, sans-serif;
--sf-heading--family: "Project Sans", system-ui, sans-serif;
--sf-display--family: "Project Sans", system-ui, sans-serif;
}
}
Что важно заметить: правила @font-face для Inter остаются в core.css, но
браузер скачивает файл шрифта, только когда текст страницы его использует.
Если ни одно семейство больше не называет Inter, его файлы не загружаются.
Если Inter нужно оставить, а добавить письменность, которой в нём нет, шрифт этой письменности ставят в цепочку сразу после Inter. Браузер берёт из каждого шрифта только знаки, которые в нём есть, поэтому латиница и кириллица остаются в Inter, а арабский текст рисуется вторым шрифтом:
@font-face {
font-family: "Project Arabic";
src: url("/assets/fonts/project-arabic.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
}
@layer project {
:root {
--sf-text--family: "Inter Variable", "Project Arabic", "Inter Fallback", system-ui, sans-serif;
}
}
Какие переменные читает текст без классов и как ядро оформляет абзацы, списки и заголовки без классов, сказано в «Тексте по умолчанию».
Длина строки
Удобная длина строки абзаца — 45–80 знаков. Для неё есть переменные меры
--sf-text--measure (65ch), --sf-text--measure-narrow (45ch) и
--sf-text--measure-wide (80ch) и утилиты measure-narrow, measure,
measure-wide (Длина строки).
Ссылки
Текстовая ссылка без класса окрашена ролью --sf-link, а при наведении,
нажатии и после посещения — ролями --sf-link-hover, --sf-link-active,
--sf-link-visited (цвета — Служебные роли). Подчёркивание отнесено от текста на
--sf-a3. Framework не убирает у ссылки контур фокуса: по ней можно пройти
клавиатурой (Фокус).
Имена переменных
Имена базовых шкал текста пишутся через двойной дефис:
--sf-text--size-*, --sf-text--height-*, --sf-title--height-*. Используйте
эти имена в коде.
Смотрите также
- Служебные роли — цвета ссылок и фокуса.
- Поток текста — поток текста.
- Шкала интерфейса:
0,1/4,1/3,1/2,1…8— утилитыtext-N. - Текст по умолчанию — что ядро ставит тексту без классов.
- Значения вертикальных размеров — кегль и высота строки каждой ступени.