Иногда кнопки на сайте содержат очень разный по длине текст. С коротким текстом всё просто: он помещается в одну строку и выглядит аккуратно. Но как только текст становится длиннее, приходится переносить его на две строки. Проблема в том, что при автоматическом переносе строки получаются неравномерными: в первой может влезть почти вся фраза, а одно слова оказаться во второй строке.
Проблему не просто описать словами, потому давайте рассмотрим пример дизайна.

Здесь мы видим группу-кнопок с названиями рубрик сайта. Основная проблема — названия сильно могут отличаться по длине. Они варьируются от короткого «Перекусы» до длиннющего «Физическая нагрузка: советы и рекомендации».
Дизайнер изящно решил эту проблему, сделав перенос на две строки, и так сбалансировал разбивку на строки и ширину контейнера кнопки, что текст на кнопке отлично заполняет контейнер.
CSS, к сожалению, не даёт инструментов верстальщику, чтобы решить эту задачу, задав единообразно стили для всех кнопок. При этом на практике всё может оказать еще сложнее, т.к. названия могут быть еще длиннее и надо как то усекать текст. Такого кейса даже нет в предложенном дизайне, но мы его тоже рассмотрим.
Использование max-width
Если мы зададим максимальную ширину кнопки, то задача будет решена только для случая с короткими названиями, которые умещаются в одну строку. Ширина кнопки будет подстраиваться под длину строки.
1 |
max-width: 250px; |

Двустрочные контейнеры будут заполнены не сбалансировано (типично: полная 1я строка и неполная вторая), максимальная ширина контейнера определит место переноса на следующую строку.
Длинные тексты будут обрезаны всегда в одном месте. А очень длинные займут больше строк, чем нужно.
Ограничение в две строки
Начнем с решения простых проблем, и вернемся потом к более сложным.
В CSS есть способ ограничить вывод нужным количеством строк. В нашем случае их нужно две:
1 2 3 4 5 6 7 8 9 |
.two-lines-container { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; } |
Данный CSS код ограничит текст двумя строками, если текст длиннее — то появится характерное многоточие (ellipsis).

Балансировка сток
Ещё не давно в чистом CSS сделать именно автоматическое равномерное разбиение текста на 2 строки — было не то что не тривиально, а не возможно, потому что движок верстки ломает строки по правилам переноса/пробелов, а не «по середине всей строки текста».
Сейчас у CSS есть экспериментальное свойство text-wrap: balance
, которое является частью CSS Text Level 4. При наличии этого свойства, браузер старается распределить слова равномерно по строкам.
Поддержка пока: Chromium 114+, Safari 16.4+, Firefox в эксперименте.
Т.е мы добавим еще одну строку в стили:
1 |
text-wrap: balance; |
И получим:

У сожалению, свойство оказывает эффект уже после расчета ширины контейнера и потому, хоть длины строк сбалансированы, но мы имеем пустоты в многострочных контейнерах.
Идея: квантование ширины
Чтобы обойти ограничение, можно использовать подход «квантования ширины». Вместо того чтобы подгонять ширину кнопки идеально под каждое значение, мы задаём несколько «ступенек» — фиксированные диапазоны ширины.
1 2 3 4 5 6 7 8 |
.dtl { max-width: 320px; } .dtl12-2 { max-width: 150px; } /* до 24 символов */ .dtl12-3 { max-width: 190px; } /* до 36 символов */ .dtl12-4 { max-width: 230px; } /* до 48 символов */ .dtl12-5 { max-width: 270px; } /* до 60 символов */ |
Я создаю набор классов — размерной сетки. Они подключаются в нужные контейнера на сервере, потому js для маркировки нам не нужен.
Здесь в имени классов я зашифровал «data text length 12» — .dtl12-2
читается как «текстовая длина 12 × 2 = 24 символа». То есть если текст укладывается в 24 символа, то кнопка получает этот класс, а её ширина ограничивается 150 пикселями.
Все шаги в совокупности дают вот такой результат:

Пример HTML кода:
1 2 3 |
<span class="two-lines-container dtl dtl12-5"> Бессонница, плохой сон- фактор неэффективного снижения веса </span> |
На практике требуется 5-7 реперных точек сетки, чтобы покрыть нужный диапазон значений. Получается довольно близко к требованиям макета.