Текст, который выглядит дорого
Буквица, обтекание фигур, честные переносы и вариативные шрифты. Десяток мелочей, каждая почти незаметна, а вместе они отличают вёрстку от текста в блокноте.
Что ты научишься делать
- Уберёшь висячие строки и одинокие слова в заголовках
- Сделаешь буквицу и обтекание фигуры без единой картинки
- Подключишь вариативный шрифт одним файлом вместо шести
#Разница, которую видно, но не объяснить
Два одинаковых текста, одинаковый шрифт и размер. Один выглядит как страница книги, другой — как вставка из мессенджера. Отличий обычно с десяток, и ни одно по отдельности не бросается в глаза.
Одинокое слово на второй строке заголовка. Последняя строка абзаца из трёх букв. Подчёркивание, перечёркивающее хвост буквы «р». Строка в сто двадцать символов, на которой глаз теряет начало следующей.
#Переносы строк: balance и pretty
Раньше висячее слово в заголовке убирали вручную — ставили неразрывный пробел перед последним словом. Это работает ровно до смены ширины экрана.
text-wrap: balance просит браузер выровнять длину строк в блоке. Для заголовков и коротких подписей это лучшее, что можно сделать одной строкой.
text-wrap: pretty решает другую задачу — не даёт последней строке абзаца остаться из одного короткого слова. Он рассчитан на длинный текст.
Так не надо
<h2>Как выбрать зерно и не переплатить за
упаковку</h2>Неразрывный пробел прибит к конкретному месту. На другой ширине он окажется в середине строки и создаст дыру.
Так надо
h1, h2, h3,
.lead {
text-wrap: balance;
}Браузер сам подбирает разбивку под текущую ширину. Работает на любом экране и не требует правки текста.
#Длина строки
Самый заметный параметр читаемости — не размер шрифта, а длина строки. Комфортный диапазон — 45–75 символов; за сотню глаз начинает промахиваться мимо начала следующей строки.
Единица ch измеряется в ширинах нуля текущего шрифта, поэтому max-inline-size: 65ch — самый честный способ задать меру.
.prose { /* Мера набора: примерно 65 символов в строке */ max-inline-size: 65ch;}/* Иллюстрации и код могут быть шире текста */.prose > figure,.prose > .code { max-inline-size: none;}#Буквица
Первая буква на три строки — приём из книжной вёрстки. Делается псевдоэлементом ::first-letter и обтеканием.
Тонкость в том, что line-height у буквицы нужно занижать: при обычном значении буква окажется слишком высокой и не сядет по строкам.
.article > p:first-of-type::first-letter { float: inline-start; font-size: 3.2em; /* Подбирается на глаз: около 0.8 сажает букву ровно на три строки */ line-height: .82; padding-inline-end: .08em; padding-block-start: .05em; font-weight: 700;}#Обтекание фигуры
Обычный float заставляет текст обтекать прямоугольник. shape-outside задаёт настоящую форму обтекания — круг, многоугольник или контур по прозрачности картинки.
#Переносы и выключка
Выключка по формату (text-align: justify) без переносов даёт дыры между словами — особенно в русском, где слова длинные.
hyphens: auto включает словарь переносов, но работает только если у страницы правильно указан lang. Без него браузер не знает, какой словарь брать, и молча ничего не делает.
#Подчёркивание, которое не мешает
Стандартное подчёркивание ссылки проходит ровно по хвостам букв «у», «р», «д». Три свойства делают его аккуратным.
a { /* Отодвигаем линию от базовой линии текста */ text-underline-offset: .18em; /* Тонкая линия вместо толстой по умолчанию */ text-decoration-thickness: 1px; /* Линия прерывается на хвостах букв */ text-decoration-skip-ink: auto;}#Вариативные шрифты
Обычный шрифт — это отдельный файл на каждое начертание: обычный, полужирный, жирный, курсив. Шесть начертаний — шесть файлов и шесть загрузок.
Вариативный шрифт хранит все промежуточные состояния в одном файле. Вес задаётся любым числом, а не ступенями: доступны и 350, и 620.
@font-face { font-family: "Onest"; src: url("onest-var.woff2") format("woff2-variations"); /* Диапазон, а не одно значение */ font-weight: 100 900; font-display: swap;}h1 { font-weight: 780; }.lead { font-weight: 420; }/* Оси, кроме веса, задаются так */.condensed { font-variation-settings: "wdth" 88;}#Как это выглядит в реальном проекте
@layer base { :where(h1, h2, h3, .lead) { text-wrap: balance; letter-spacing: -0.02em; } :where(p, li) { text-wrap: pretty; line-height: 1.7; } .prose { max-inline-size: 68ch; hyphens: auto; } /* Кавычки-ёлочки и тире не набирают руками: их подставляет редактор, а CSS только не мешает */ :where(blockquote) { quotes: "«" "»" "„" "“"; } blockquote p::before { content: open-quote; } blockquote p::after { content: close-quote; } /* Цифры в таблице должны быть моноширинными, иначе колонка «пляшет» */ .table td { font-variant-numeric: tabular-nums; }}#Когда НЕ надо
- Выключка по формату в узкой колонке. На ширине телефона
justifyбез переносов превращает текст в решето из дыр. Либо включайhyphens, либо оставляй выравнивание по началу строки. - Буквица в интерфейсе. Это приём для длинного чтения. В карточке товара или в модальном окне он смотрится случайно.
- Разрядка основного текста.
letter-spacingпомогает крупным заголовкам и капслоку, но ухудшает читаемость обычного текста: слова перестают восприниматься целиком. - Все оси вариативного шрифта сразу. Каждая ось — это вес файла. Подключай только те, которые реально используешь.
#Поддержка браузерами
| Возможность | Состояние |
|---|---|
text-wrap: balance | Во всех современных браузерах, Safari подтянулся позже |
text-wrap: pretty | Появился позже balance; где не поддержан — просто игнорируется |
::first-letter | Везде и давно |
shape-outside | Во всех современных браузерах |
hyphens: auto | Работает везде при заданном lang |
text-decoration-skip-ink | Во всех современных браузерах |
| Вариативные шрифты | Везде |
Где спотыкаются почти все
Переносы не включаются
Почему У страницы не задан lang, и браузеру нечем определить словарь переносов.
Как надо Проверь <html lang="ru">. Без него hyphens: auto молча не работает.
Буквица «висит» над строками
Почему У ::first-letter остался обычный line-height, и буква занимает больше места, чем нужно.
Как надо Занижай межстрочный интервал до 0.8–0.85 и подгоняй отступами.
Текст обтекает квадрат вместо круга
Почему border-radius меняет только внешний вид, а обтекание считается по прямоугольнику.
Как надо Форму обтекания задаёт shape-outside — его нужно указать отдельно.
Мера набора задана в пикселях
Почему При смене размера шрифта число символов в строке меняется, и мера уезжает.
Как надо Задавай ширину в ch — она привязана к шрифту.
- Мера набора measure
- Длина строки в символах. Комфортно — 45–75.
- Буквица drop cap
- Увеличенная первая буква абзаца, занимающая несколько строк.
- Висячая строка orphan, widow
- Одинокое слово или строка, оторванная от абзаца.
- Обтекание формой shape-outside
- Форма, по которой текст огибает плавающий элемент.
- Вариативный шрифт variable font
- Один файл, содержащий все промежуточные начертания.
- Табличные цифры tabular-nums
- Начертание, где все цифры одной ширины.
Проверь себя
Первое — для заголовков и подписей, второе — для длинного текста. Задачи разные.
Без языка браузер не знает, какой словарь переносов применять, и не делает ничего.
<code>border-radius</code> меняет только вид. Форму обтекания задаёт отдельное свойство.
<code>ch</code> привязана к ширине символа текущего шрифта, поэтому мера сохраняется при смене размера.
Меняется только начертание цифр — сам шрифт остаётся прежним. Для таблиц с ценами это заметно сразу.
Задание
Журнальная статья
Оформи статью по-книжному:
- заголовку — балансировку строк;
- тексту — меру не больше 65ch, межстрочный интервал от 1.6 и переносы;
- первому абзацу — буквицу через
::first-letter; - картинке — круглое обтекание через
shape-outside; - ссылке — аккуратное подчёркивание с отступом.
Разметку не трогай.
Подсказка 1
Балансировка: .article__title { text-wrap: balance; }
Подсказка 2
Мера и переносы: .article__text { max-inline-size: 62ch; line-height: 1.7; hyphens: auto; }
Подсказка 3
Буквица: .article__text::first-letter { float: inline-start; font-size: 3.2em; line-height: .82; padding-inline-end: .08em; }
Подсказка 4
Обтекание: shape-outside: circle(50%); плюс shape-margin: 10px для воздуха.
Показать решение
<article class="article" lang="ru"> <h1 class="article__title">Как выбрать зерно и не переплатить за красивую упаковку</h1> <div class="article__figure"></div> <p class="article__text">Обжарка меняет вкус сильнее, чем сорт. Одно и то же зерно из Эфиопии в светлой обжарке будет кислотным и ягодным, а в тёмной — горьким и плотным. Дата обжарки важнее любых медалей на этикетке: кофе раскрывается через неделю и держится месяца полтора. Подробнее — в <a href="#">нашем разборе</a>.</p></article>.article { font-family: Georgia, serif;}.article__title { font-size: 26px; text-wrap: balance;}.article__figure { float: left; width: 110px; height: 110px; margin-right: 14px; border-radius: 50%; background: linear-gradient(135deg, #7c5cff, #b06cff); shape-outside: circle(50%); shape-margin: 10px;}.article__text { max-inline-size: 62ch; line-height: 1.7; hyphens: auto; text-align: justify;}.article__text::first-letter { float: inline-start; font-size: 3.2em; line-height: .82; padding-inline-end: .08em; padding-block-start: .05em; font-weight: 700;}.article__text a { text-underline-offset: .18em; text-decoration-thickness: 1px; text-decoration-skip-ink: auto;}