СДЧПВС: слишком длинный чтобы поместиться в строчку

Иллюстрация

Новый день и новая велеречивая статья о CSS от сноба-приверженца JavaScript. :) Сегодня, однако, постараюсь быть краток.

В этот раз мы поговорим о переносе слов. Если конкретнее, то о том, как с помощью CSS заставить текст поместиться в контейнер, даже если придётся применить перенос в неестественных (не соответствующих границам слов) местах. Можно сказать, это задача, противоположная поставленной в моей предыдущей статье «Сокращение текста».

Пример:

http://www.urbandictionary.com/define.php?term=the%20meaning%20of%20life

Браузер добавляет перенос в длинный URL, но полученный результат оставляет желать лучшего.

Добавление переносов в текст вручную

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

С помощью JavaScript в куске текста, например, твите или информационном сообщении, можно добавить элемент-подсказку после каждого энного количества символов. Однако следует учесть некоторые возможные загвоздки:

  1. Чаще всего перенос требуется добавить только в длинные слова (то есть, добавление переноса в середине слова из двух символов не желательно), в таком случае слепое помещение элемента-подсказки после каждого энного символа не совсем подходит. Больше подошло бы указание вроде «следует найти строку, состоящую более чем из 10 символов, отличных от пробела, и добавить в неё элемент-подсказку». Регулярное выражение JS для этого будет выглядеть примерно так: text.split(/(\s*\S{10}\s*)/g).join("…"), где "…" — элемент-подсказка для добавления переноса.
  2. Если перед вами не просто текст, а, к примеру, html-разметка, придётся быть более осторожным, чтобы избежать добавления переноса в фрагменты html. В противном случае можно повредить теги или имена атрибутов, что приведёт к их невалидности. Из этого следует, что сначала лучше с помощью цикла перебрать значения, которые возвращает split(..) и по контексту определить, нужно ли в этом месте добавлять элемент-подсказку или нет (написание соответствующего кода я оставляю читателю в качестве домашнего задания).

Если мы решим выбрать этот путь, какой элемент следует использовать в качестве подсказки для переноса?

(пробел)

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

Можно добавить элемент <span class='break'> </span> и в стилях прописать ширину, с которой он будет невидимым.

<style>
p { font-family:sans-serif; font-size:15px; padding:3px; background-color:yellow; width:85px; }
.break { font-size:0px; }
</style>

<p>Пришло вре<span class="break"> </span>мя для всех достойных людей…</p>

Пришло время для всех достойных людей…

Однако этот приём откровенно отвратителен и может привести к проблемам в старых версиях браузеров (если вам, конечно, на них не наплевать!).

Новые возможности

Как насчёт тега «Возможного деления слова» <wbr>? На первый взгляд, подходит идеально. Это невидимый элемент, помогающий браузеру понять, где уместен перенос.

Вы можете столкнуться с тем нюансом, что при использовании тега <wbr> символ переноса в месте разделения слова не будет добавлен браузером. Такой результат может быть удобным в зависимости от обстоятельств.

Несколько лет элемент не поддерживался в Safari. Однако, команда Safari первой ввела поддержку элемента &shy; (тогда он не поддерживался другими браузерами), который представляет собой «мягкий перенос», используемый в качестве подсказки для браузера, предлагающей возможные позиции для переноса строки. Если перенос добавляется в месте расположения &shy;, отображается символ переноса -, если нет, он остаётся невидимым. Именно то, что нам нужно.

Из-за проблем с поддержкой браузерами, раньше приходилось проводить проверку на поддержку браузера и, соответственно, выбирать, какой элемент использовать: <wbr> или &shy;. В наше время поддержка значительно улучшилась, и уже можно выбирать, какой из них использовать, исходя из того, нужен вам символ переноса или нет. Например, вам вряд ли потребуется символ переноса внутри URL, разделённого на две строки, а вот в обычном тексте для читателей, особенно тех что привыкли к разметке, имитирующей печатные издания (в онлайн журналах, газетах и т.д.), гораздо удобнее, если символ переноса присутствует.

CSS спешит на помощь!

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

Средство word-wrap:break-word реализует то, что нам нужно, то есть оно даст браузеру возможность выполнить перенос в середине слова там, где сочтёт это уместным.

<style>
#container { word-wrap:break-word; background-color:yellow; padding:10px; width:200px; }
</style>

<div id="container">

http://www.urbandictionary.com/define.php?term=the meaning of life

http://www.urbandictionary.com/define.php?term=the%20meaning%20of%20life

Примечание: Это свойство появилось уже давно, однако недавно в спецификации CSS3 было переименовано в overflow-wrap:break-word; новая версия поддерживается только самыми последними версиями браузеров. Будьте осторожны, используя его, и, наверное, стоит ещё некоторое время прописывать оба правила.

Ещё одно похожее свойствоword-break. С точки зрения семантики, нам стоит отдать предпочтение word-break для управления разделением слов, о котором идёт речь, вместо word-wrap или overflow-wrap, однако … не суть важно. В любом случае, видимо во всех международных языках для управления переносом слов используется word-break, поэтому стоит ли вообще рассматривать его семантику — спорный вопрос.

Что думаете вы?

Является ли запись в CSS исчерпывающей? Небольшая семантическая неувязка с word-break и word-wrap не должна играть большой роли. Тем не менее, судя по всему, CSS не даёт нам контроль над расстановкой символа переноса в том же объеме, как &shy;.

Нужно ли усовершенствовать стандарт CSS или же достаточно радоваться и тому, что уже есть? Поделитесь вашим мнением в комментариях!