Квантование ширины: способ балансировать текст в кнопках на CSS

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

Проблему не просто описать словами, потому давайте рассмотрим пример дизайна.

Пример макета (то что требуется дизайном)
Пример макета (то что требуется дизайном)

Здесь мы видим группу-кнопок с названиями рубрик сайта. Основная проблема — названия сильно могут отличаться по длине. Они варьируются от короткого «Перекусы» до длиннющего «Физическая нагрузка: советы и рекомендации».

Дизайнер изящно решил эту проблему, сделав перенос на две строки, и так сбалансировал разбивку на строки и ширину контейнера кнопки, что текст на кнопке отлично заполняет контейнер.

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

Использование max-width

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

Результат верстки с использованием max-width

Двустрочные контейнеры будут заполнены не сбалансировано (типично: полная 1я строка и неполная вторая), максимальная ширина контейнера определит место переноса на следующую строку.

Длинные тексты будут обрезаны всегда в одном месте. А очень длинные займут больше строк, чем нужно.

Ограничение в две строки

Начнем с решения простых проблем, и вернемся потом к более сложным.

В CSS есть способ ограничить вывод нужным количеством строк. В нашем случае их нужно две:

Данный CSS код ограничит текст двумя строками, если текст длиннее — то появится характерное многоточие (ellipsis).

Добавляем line-clamp хак

Балансировка сток

Ещё не давно в чистом CSS сделать именно автоматическое равномерное разбиение текста на 2 строки — было не то что не тривиально, а не возможно, потому что движок верстки ломает строки по правилам переноса/пробелов, а не «по середине всей строки текста».

Сейчас у CSS есть экспериментальное свойство text-wrap: balance, которое является частью CSS Text Level 4. При наличии этого свойства, браузер старается распределить слова равномерно по строкам.

Поддержка пока: Chromium 114+, Safari 16.4+, Firefox в эксперименте.

Т.е мы добавим еще одну строку в стили:

И получим:

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

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

Идея: квантование ширины

Чтобы обойти ограничение, можно использовать подход «квантования ширины». Вместо того чтобы подгонять ширину кнопки идеально под каждое значение, мы задаём несколько «ступенек» — фиксированные диапазоны ширины.

Я создаю набор классов — размерной сетки. Они подключаются в нужные контейнера на сервере, потому js для маркировки нам не нужен.

Здесь в имени классов я зашифровал «data text length 12» — .dtl12-2 читается как «текстовая длина 12 × 2 = 24 символа». То есть если текст укладывается в 24 символа, то кнопка получает этот класс, а её ширина ограничивается 150 пикселями.

Все шаги в совокупности дают вот такой результат:

Добавили квантование ширины

Пример HTML кода:

На практике требуется 5-7 реперных точек сетки, чтобы покрыть нужный диапазон значений. Получается довольно близко к требованиям макета.

Мало букафф? Читайте есчо !

100% высоты для дочернего flex контейнера

Сентябрь 10, 2024 г.

Flex опирается на другие принципы нежели блочные контейнеры, и иной раз не понятно какими свойствами управляется дочерний контейнер во flex родителе. Рассмотрим пример, когда у нас есть flex контейнер с двумя дочерними элементами. [crayon-68f6342507be7800262990/] ...

Читать

Почему не работает стиль :: before или :: after?

Октябрь 22, 2017 г.

Замечательные псевдо-классы, которые позволяют добавить виртуальные контейнеры в начало или конец контейнера. Как они работают и почему могут "не сработать"? ...

Читать

Цвет HR - как изменить в CSS

Апрель 27, 2017 г.

Горизонтальная линия HR - независимый HTML элемент - вызывает много вопросов у начинающих. Основная проблема - установка цвета. Установка стилей ...

Читать

Простые CSS анимации, которые оживят ваш сайт

Апрель 14, 2025 г.

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

Читать
 

Комментарии к «Квантование ширины: способ балансировать текст в кнопках на CSS»

Понравилась статья? Есть вопросы? - пишите в комментариях.



Комментарий: