Как настроить высоту строки в CSS

Высота строки CSS задается свойством line-height. Для обычного текста берите число без единиц, для заголовка задавайте собственный коэффициент. Так размер строки сохраняет пропорции, а вложенные элементы наследуют предсказуемое значение. Переносимые подписи в кнопках выравнивайте через flex или grid.

Что такое line-height и из чего складывается высота строки

Браузер раскладывает текст по линейным блокам. Линейный блок содержит строку, строчные элементы, изображения и свободное место вокруг текста.

font-size задает размер шрифта, но не границы видимых букв.

На положение текста влияют метрики гарнитуры: ascent над базовой линией, descent под ней, x-высота строчных букв и cap height прописных.

  • Базовая линия – условная линия, на которой стоят символы.
  • Ascent – часть метрик над базовой линией.
  • Descent – часть метрик под базовой линией.
  • X-высота – высота строчной буквы x.
  • Cap height – высота прописных букв.
Метрики шрифта с базовой линией, x-высотой и высотой прописных букв
Расстояние между базовыми линиями соседних строк
Половинный интерлиньяж над строкой и под строкой

Если line-height больше font-size, разница образует интерлиньяж. Браузер распределяет его вокруг текста, поэтому высота линейного блока может быть больше видимой высоты букв.

.sample {
  font-size: 20px;
  line-height: 32px;
  background: #eef4ff;
}

В примере разница равна 32px - 20px = 12px. В упрощенной модели по 6px приходится на каждую сторону, но реальный видимый зазор зависит от метрик шрифта.

Подробное описание свойства смотрите в документации MDN по line-height.

Значения line-height: normal, число, px/rem, em и проценты

Единица измерения влияет на вычисление и наследование. Особенно заметна разница, когда вложенный элемент меняет размер шрифта.

ЗначениеКак вычисляетсяЧто наследуют потомкиКогда использовать
normalБраузер выбирает интервал по метрикам текущего шрифтаКлючевое слово; потомок рассчитывает свой интервалКогда точный ритм текста не нужен
Число, например 1.5Коэффициент умножается на собственный font-sizeСам коэффициентОсновной текст и вложенные элементы
pxФиксированная длина в CSS-пикселяхВычисленная длинаОднострочное выравнивание
remДлина считается от размера шрифта корневого элементаВычисленная длинаФиксированный ритм страницы
emДлина считается от размера шрифта самого элементаВычисленная длинаЛокальная фиксированная длина
Проценты, например 150%Процент считается от размера шрифта элементаВычисленная длинаКогда потомок должен получить готовую длину
.automatic { line-height: normal; }
.ratio     { line-height: 1.5; }
.pixels    { line-height: 24px; }
.root-size { line-height: 1.5rem; }
.relative  { line-height: 1.5em; }
.percent   { line-height: 150%; }

При font-size: 16px число 1.5 дает строку 24px. Значения 1.5em и 150% тоже дают 24px на родителе, но потомок получает уже вычисленную длину.

normal зависит от шрифта и не равно фиксированному 1.2.

Почему высоту строки задают без единиц

Безразмерное число наследуется как коэффициент. Каждый потомок умножает его на собственный размер шрифта.

.demo {
  font-size: 16px;
  line-height: 1.5em;
}

.demo h2 {
  font-size: 40px;
  line-height: inherit;
}

Родитель вычисляет 1.5em как 16px * 1.5 = 24px. Заголовок наследует 24px при размере 40px, поэтому его строки могут наезжать друг на друга. Процент 150% на родителе дает такой же результат.

.demo {
  font-size: 16px;
  line-height: 1.5;
}

.demo h2 {
  font-size: 40px;
  line-height: inherit;
}

Теперь заголовок наследует коэффициент 1.5 и получает 40px * 1.5 = 60px. Обычный текст получает 16px * 1.5 = 24px.

Для заголовка можно задать отдельное число, например 1.15. При размере 40px оно дает 40px * 1.15 = 46px.

.demo h2 {
  line-height: 1.15;
}

Какую высоту строки выбрать для текста и заголовков

Начните с коэффициента и оцените длину строки, гарнитуру и переносы. Одинаковое значение выглядит по-разному в абзаце и крупном заголовке.

СодержимоеНачальный ориентирЧто оценить
Основной текст1.5–1.7Легко ли перейти к следующей строке
Крупный заголовок1.1–1.25Не соприкасаются ли буквы после переноса
Интерфейсная подпись1.3–1.5Помещается ли длинная подпись
body {
  font-size: 1rem;
  line-height: 1.6;
}

.article h2 {
  font-size: 2rem;
  line-height: 1.2;
}

.caption {
  font-size: 0.875rem;
  line-height: 1.4;
}

Длинная строка часто требует большего интервала: взгляду проще найти начало следующей строки.

Короткий заголовок часто выглядит лучше при плотном наборе. После смены шрифта проверьте диакритические знаки, прописные буквы и нижние выносные элементы. Метрики гарнитур меняют видимый зазор даже при одинаковом коэффициенте.

Критерий 1.4.8 WCAG 2.2 уровня AAA предусматривает механизм настройки оформления текстовых блоков. Среди условий – межстрочный интервал не меньше 1,5 размера шрифта. Межабзацный интервал должен составлять не меньше 1,5 межстрочного интервала.

Критерий 1.4.12 уровня AA требует сохранять содержимое и функциональность при пользовательском изменении интервалов:

  • Высота строки – 1,5 размера шрифта.
  • Интервал после абзаца – 2 размера шрифта.
  • Межбуквенное расстояние – 0,12 размера шрифта.
  • Межсловное расстояние – 0,16 размера шрифта.

Этот критерий не обязывает назначать перечисленные значения по умолчанию.

Пользователь должен иметь возможность применить их без потери текста или функций. Поэтому избегайте фиксированной высоты контейнера для многострочного текста.

Высота строки в адаптивной верстке

Свяжите размер шрифта с rem, а высоту строки задайте числом. Коэффициент сохранит пропорцию на разных экранах.

.article {
  font-size: 1rem;
  line-height: 1.5;
}

.article h2 {
  font-size: clamp(1.75rem, 1.25rem + 2vw, 3rem);
  line-height: 1.15;
}

@media (min-width: 48rem) {
  .article {
    font-size: 1.125rem;
    line-height: 1.6;
  }
}

clamp() ограничивает размер заголовка снизу и сверху. Между границами размер меняется вместе с шириной окна, а коэффициент сохраняет пропорцию строки.

Меняйте коэффициент на брейкпоинте, когда ширина колонки заметно меняется.

Проверьте самый длинный заголовок на узком экране. Увеличьте размер текста в браузере: заголовок должен переноситься без наложения строк.

Вертикальное выравнивание одной строки через line-height

Для короткой надписи, которая точно не переносится, задайте одинаковые height и line-height. Линейная область займет высоту контейнера.

.single-line {
  display: block;
  box-sizing: border-box;
  height: 48px;
  padding: 0 16px;
  font-size: 16px;
  line-height: 48px;
  text-align: center;
  white-space: nowrap;
}

Метрики шрифта могут смещать видимые буквы относительно оптического центра.

При переносе прием ломается: каждая строка получает высоту 48px, и подпись выходит за границы элемента. Для текста в две строки используйте flex или grid.

.button {
  display: grid;
  place-items: center;
  min-height: 48px;
  padding: 12px 16px;
  font: inherit;
  line-height: 1.3;
  text-align: center;
}

min-height позволяет кнопке вырасти вместе с текстом. Однострочная запись для flex выглядит так: display: flex; align-items: center; justify-content: center;.

Как убрать лишний отступ над и под текстом

Сначала уберите margin и padding. Если зазор останется, его создает линейный блок, интерлиньяж и метрики шрифта.

.title {
  margin: 0;
  padding: 0;
  font-size: 2rem;
  line-height: 1.2;
}

Значение line-height: 1 уменьшает интерлиньяж, но не совмещает границы элемента с видимыми буквами.

Обрезка через text-box-trim и text-box-edge

Свойство text-box-trim обрезает пространство у начала и конца текстового блока. Свойство text-box-edge выбирает границы шрифта, например cap и alphabetic.

.title {
  margin: 0;
  font-size: 2rem;
  line-height: 1.2;
}

@supports (text-box-trim: trim-both) and (text-box-edge: cap alphabetic) {
  .title {
    text-box-trim: trim-both;
    text-box-edge: cap alphabetic;
  }
}

trim-both обрезает обе стороны. Значения trim-start, trim-end и none выбирают сторону или отключают обрезку. Сокращение text-box объединяет режим обрезки и выбор границ.

@supports (text-box: trim-both cap alphabetic) {
  .title {
    text-box: trim-both cap alphabetic;
  }
}

Пара cap alphabetic задает верхнюю границу по высоте прописных, нижнюю – по базовой линии.

Обрезка меняет геометрию блока, но не удаляет выступающие части букв. Если родитель скрывает переполнение, проверьте диакритику и нижние выносные элементы.

Как определить совместимость в браузере

Для Chrome, Edge, Safari и Firefox используйте проверку конкретной декларации. Она позволяет выбрать рабочий вариант непосредственно в браузере пользователя, без привязки к номеру версии. Таблицы совместимости доступны в документации MDN и в Can I use.

Чтобы увидеть результат в своем браузере, откройте консоль DevTools и выполните:

console.table({
  trim: CSS.supports('text-box-trim', 'trim-both'),
  edge: CSS.supports('text-box-edge', 'cap alphabetic'),
  shorthand: CSS.supports('text-box', 'trim-both cap alphabetic')
});

Значение true означает, что браузер принимает эту декларацию.

Для примера с раздельными свойствами нужны true у trim и edge. Для сокращения нужен true у shorthand. Проверка синтаксиса не заменяет оценку результата на выбранном шрифте.

Добавьте обводку к заголовку и включите обрезку в CSS-правилах DevTools:

.title {
  outline: 1px solid #c00;
}

При работающей обрезке границы блока приблизятся к выбранным границам шрифта. Отключите декларацию обрезки: дополнительное пространство появится снова. Удаление временной обводки вернет исходное оформление.

Запасной вариант и расчет по метрикам

Оставьте обычные отступы и заданный line-height вне условия. Браузер без поддержки сохранит этот вариант.

.title-group {
  display: grid;
  gap: 1rem;
}

.title-group .title {
  margin: 0;
  line-height: 1.2;
}

@supports (text-box: trim-both cap alphabetic) {
  .title-group .title {
    text-box: trim-both cap alphabetic;
  }
}

Такой запасной вариант сохраняет читаемость и расстояние между элементами, но не повторяет точную обрезку.

Для старых браузеров расчет по метрикам автоматизирует Capsize. Инструмент рассчитывает поправки по метрикам шрифта.

В упрощенной модели при высоте строки L, ascent A, descent D и cap height C дополнительный интерлиньяж равен L - (A + D). Верхняя поправка равна (L - A - D) / 2 + A - C, нижняя – (L - A - D) / 2 + D.

Все величины в этих формулах должны использовать одинаковые единицы.

Не переносите числовые поправки между гарнитурами. Метрики Lato, Arial и других шрифтов различаются. Оценивайте результат после загрузки выбранного шрифта.

Как проверить высоту строки в DevTools

Откройте инструменты разработчика у элемента с проблемным текстом. Проверяйте сам абзац или заголовок: значение родителя может отличаться от результата у вложенного элемента.

  1. Щелкните правой кнопкой мыши по тексту и выберите исследование элемента.
  2. Откройте панель вычисленных стилей Computed и найдите font-size и line-height.
  3. В панели CSS-правил временно добавьте к элементу font-size: 20px;.
  4. Добавьте line-height: 1.5;. При размере 20px высота строки станет 30px.
  5. Снова откройте Computed. Для этого элемента появятся 20px и 30px.
  6. Замените 1.5 на 2. Строки раздвинутся, а вычисленная высота станет 40px.

Обводка показывает границы элемента, но не рисует каждый линейный блок.

Для визуальной проверки временно добавьте фон с шагом высоты строки. Полосы помогут оценить интервал у обычного многострочного текста.

.debug-text {
  font-size: 20px;
  line-height: 1.5;
  outline: 1px solid #c00;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 29px,
    #aac4ee 29px,
    #aac4ee 30px
  );
}

Полосы служат ориентиром, а не точной подсветкой линейных блоков. Крупные строчные элементы или изображения могут увеличить высоту отдельных строк.

При normal вычисленные стили могут показывать ключевое слово. Для сравнения временно задайте число.

Чтобы вернуть прежний вид, удалите временные декларации из element.style. Перезагрузка страницы тоже отменит изменения.

Ошибки при настройке высоты строки

Проверьте единицы, наследование и содержимое строки, если текст выглядит неожиданно.

  • Фиксированный px. Значение 24px не меняется вместе с размером шрифта и может стать тесным для крупного текста.
  • em или проценты на родителе. Потомок получает готовую длину. Для общей типографики задайте число.
  • line-height у строчного элемента. Свойство влияет на вклад span в линейный блок, но маленькое значение не обязано уменьшить всю строку родителя.
  • Крупный строчный элемент. Большой font-size или line-height у span способен увеличить общую высоту строки.
  • normal без учета шрифта. После смены гарнитуры меняются метрики и видимый интервал.
.paragraph {
  font-size: 16px;
  line-height: 1.5;
}

.paragraph .small {
  line-height: 1;
}

.paragraph .large {
  font-size: 32px;
  line-height: 2;
}

У родителя высота строки равна 24px. Маленький span не отменяет этот вклад, а крупный элемент с высотой строки 32px * 2 = 64px может увеличить линейный блок целиком.

Задайте базовый коэффициент на body, заголовки настройте отдельно, а переносимый текст в кнопках выравнивайте через flex или grid.

Перед окончательным выбором коэффициента увеличьте размер текста и проверьте переносы. Этот тест поможет заметить наложение строк и обрезанные подписи.

Комментарии

Оставьте свой комментарий
Пока никто не оставил комментариев