Перенос длинных слов с помощью CSS
Интернет состоит из контента, контент состоит из слов, а слова могут быть очень и очень длинными. И рано или поздно вебмастер сталкивается с проблемой переноса длинных слов. Эта проблема особенно актуальна для адаптивного дизайна, и для небольших блоков контента. Итак, как же справиться с этой проблемой?
Дефис
Первое решение для переноса длинных слов – с помощью дефиса.
Код CSS
.defisi { -webkit-hyphens: auto; -moz-hyphens: auto; -ms-hyphens: auto; hyphens: auto; }
Поддержка браузерами: CSS-дефисы поддерживаются почти всеми современными браузерами, за исключением Chrome, Opera, Android. Также, очень часто дефис вставляется в местах, ошибочных с грамматической точки зрения.
Обрыв слова
Обрыв слова – это свойство CSS, указывающее на то, следует ли разрывать строки внутри слов.
Код CSS
.obriv-slova { -ms-word-break: break-all; word-break: break-all; word-break: break-word; }
Поддержка браузерами: Обрыв слов поддерживается во всех браузерах, за исключением Opera Mini и старых версий Opera.
Обертка переполнения
Следующее решение – это использование Обертки переполнения (overflow-wrap).
Код CSS
.obertka-perepolneniya { word-wrap: break-word; overflow-wrap: break-word; }
Поддержка браузерами: поддерживается практически во всех браузерах. Примечание: Некоторые браузеры требуют использования «word-wrap» вместо «overflow-wrap».
Многоточие
Еще один вариант – использование многоточий.
Код CSS
.mnogotochiye { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
Поддержка браузерами: поддерживается всеми современными браузерами.
Это работающий метод, но далеко не идеальный.
Финальное решение: Использование Обертки переполнения и дефиса.
Код CSS
.finalnoye-resheniye { overflow-wrap: break-word; word-wrap: break-word; -webkit-hyphens: auto; -ms-hyphens: auto; -moz-hyphens: auto; hyphens: auto; }
Это решение позволит браузеру, который поддерживает его, вставлять дефис, а для не поддерживающих его браузеров вставлять разрыв строки.
Передряги при переносах — CSS-LIVE
Перевод статьи Word Wrapping Woes с сайта jonibologna.com, опубликовано на css-live.ru с разрешения автора — Джони Трайтел.
Почему-то мне как-то особенно «везет» на странные, неожиданные фокусы с переносом текста.
Я написала электронную книгу, и решать, как переносить строки кода в блоках — это был кошмар! Порой блок текста из-за переноса выбивался по высоте из контейнера. А одни слишком длинные ссылки чего стоили!
Вставлять дефис в месте переноса или нет? Здесь переносим, там не переносим. Тут вставляем дефис, там нет. Одно свойство ни в какую не хочет работать без другого. И почему этот горизонтальный скроллинг упорно не хочет пропадать?
/me бьется об стол
Бывает множество ситуаций, с которыми здесь можно столкнуться, требующие слегка разного подхода к оформлению стилями, так что в этой статье мы рассмотрим типичные свойства, используемые для решения таких проблем, а также пару сценариев из реальной жизни, в которых, по-моему, особенно ярко проявляются проблемы с переносом/переполнением текста.
Свойства
В конце концов при решении проблем с переносом текста остается некий типичный «список подозреваемых». Одни довольно очевидные и логичные, а другие — нет. Одни делают свое дело сами по себе, а другие не очень.
Итак, давайте взглянем.
word-wrap
/overflow-wrap
Свойство word-wrap
принимает в виде значений два ключевых слова: normal
(по умолчанию) и break-word
. Это в дополнение к трём глобальным значениям inherit
, initial
и unset
.
По умолчанию слишком длинное слово не разрывается. Браузер не влияет на такое слово, что выглядит замечательно, пока мы не сталкиваемся с мобильными. Хотя размер контейнера может подстраиваться под слово, оно в итоге вывалится из его границ и приведёт к страшной горизонтальной прокрутке на всей странице.
В первом примере этого демо можно наглядно увидеть поведение по умолчанию:
Второй пример на этом демо включает объявление overflow-wrap: break-word;
, приказывающее браузеру разбить слово перед возможным переполнением своего контейнера.
Важно заметить: в текущем черновике спецификации CSS3 Text word-wrap
было заменено на overflow-wrap
, но значения остались прежними. И взгляните на текущую поддержку браузерами этого изменения.
word-break
Насколько я поняла, свойство word-break
нужно только для того, чтобы как-то по-особому форматировать текст на китайском, японском и корейском языках.
Я применяла word-break
для разбивки длинных слов, но правильным свойством (если вы не работаете с дальневосточным текстом) будет более общее вышеупомянутое overflow-wrap
.
hyphens
Свойство hyphens рассказывает браузеру, как расставлять дефис при переносе, и допускает следующие значения: none
, manual
и auto
, которые в настоящий момент плохо поддерживаются браузерами, поэтому вам, видимо, придётся запустить FireFox.
Значение none
гарантирует, что в слова никогда не будет подставляться символ переноса.
При значении manual
дефис выставляется в месте переноса только при наличии указывающего на это символа. Указать это можно, вставив символ либо жёсткого, либо мягкого переноса в нужное место в разметке.
Жёсткий перенос (-
) прикажет слову разорваться в определённом месте при необходимости, но всё в любом случае будет отображаться на экране.
Мягкий перенос (­
) делает тоже самое, но фактически не отображает дефис на экране, что, как правило, предпочтительнее.
auto
слова можно разбивать либо в явно указанных местах, либо автоматически, в соответствии с правилами расстановки переносов для конкретного языка, указанными в специальных файлах (если они предусмотрены в браузере). Расстановка переносов специфична для языка, и для документа нужно определять атрибут lang
.white-space
У каждого из нас есть любимые CSS-свойства, на которые можно положиться, словно на запасной выход с надписью «При аварии разбить стекло молотком», чтобы выбраться из запутанной ситуации; см. также overflow: hidden
и display: none
. Для меня таким свойством является white-space
.
Это свойство указывает правила обработки пробельных символов (пробелы, табы, переводы строки) в элементе. Что порой может вдруг оказаться невероятно полезным, например, при отладке, или чтобы лучше контролировать содержимое ячеек таблицы.
У этого свойства бывает пять значений: normal
nowrap
, pre
, pre-wrap
и pre-line
.Взглянуть на эти свойства в действии можно в примере ниже: учитывайте добавочные пробельные символы в разметке.
По умолчанию пробельные символы схлопываются в один пробел и строки разбиваются, чтобы уместиться в контейнер; как видно в первом демо-примере, в тексте есть лишние пробелы, но они не отображаются.
nowrap
(пример 2) также игнорирует дополнительные пробелы, но зато не разбивает строку текста на границах контейнера.
pre
учитывает все пробельные символы в разметке, и не разбивает строки (как видно выше в примере 3).
pre-wrap
(пример 4) учитывает добавочные пробелы, но заставляет строку разбиваться.
pre-line
(последний пятый пример) схлопывает пробельные символы (кроме перевода строки) и принуждает «цепочку» текста умещаться в контейнер.
На
Строки кода в блоке
Строки кода в теге pre
по умолчанию не переносятся. Это может вызвать неприятности в статьях блога и технических электронных книгах на мобильном, например.
По моему опыту, обычно решение зависит от того, на каком языке этот код, и вообще от задачи, но эти проблемы можно обойти при помощи принудительных переносов (без дефиса!) или горизонтального скроллинга. Методом проб и ошибок можно понять, какое точное сочетание свойств нужно тому или иному браузеру. Убедитесь, что значение white-space
случайно не переопределилось на одно из тех, при которых пробелы схлопываются, потому что это может оказаться значимым для синтаксиса кода.
Также я нарвалась на проблемы с адаптивностью при оформлении кода для github (gist), который особенно коварен из-за того, что это table. В таких случаях я понимаю, что мне придётся применить особенное оформление для переопределения контейнера таблицы.
Многоточие со смыслом
Как по мне, CSS-объявление text-overflow: ellipsis;
— какая-то шляпа. Оно очень капризное и работает только при сочетании с группой других свойств. К тому же оно применяется только к единственной строке текста, что делает его не особо полезным.
С jQuery-плагином dotdotdot можно расставить многоточие в нескольких строках текста и даже добавить в конце ссылку для продолжения чтения.
Вот быстрый примерчик:
Перенос только в строго определенном месте
Порой необходимо, чтобы слова разрывались только в строго определённых местах, где в этом есть смысл, что добавляет ещё один уровень сложности; как же сообщить эти точки разрыва браузеру?
Сделать это можно с помощью мягкого или жёсткого переносов, которые, как обсуждалось ранее, размещаются в определённом месте разметки.
Не сомневайтесь, что если мягкий дефис поддерживается в браузере, то при необходимости
­
.Эй, чем ты занимался на вы­ходных? Я рисовал по керамике, это выглядело натурально.
Слишком длинные ссылки
Я постоянно сталкивалась с проблемой слишком длинных ссылок, снова, при подготовке электронной книги (да, при публикации электронной книги это буквально худшее) с множеством целых ссылок в сносках.
По умолчанию такие ссылки не разрываются и вызывают всяческие неприятности на небольших экранах. При необходимости URL’ы должны разрываться без дефиса, поскольку ссылка в таком случае будет нерабочей. Также здесь нужно быть осторожным, поскольку, если вы такое допустите, то разорвутся не только URL’ы, но и все слова.
overflow-wrap: break-word;
на ссылке гарантирует, что URL разорвётся в границах контейнера и переполнения не будет, хотя добиться кроссбраузерности тут не так просто, как можно было бы подумать.
Заключение (Ха!)
Бывает непросто выстроить точно необходимое сочетание этих свойств, чтобы справиться с внезапно возникшей исключительной ситуацией, но более глубокое знание возможных вариантов и умение быстро распознавать типичные примеры определенно помогут обойтись без лишнего гадания.
P.S. Это тоже может быть интересно:
Перенос слов в CSS
Каскадные стили позволяют управлять переносом слов в выбранном контейнере. Для этих целей служат два свойства — word-wrap и word-break. Работу с ними и небольшие хитрости рассмотрим в данной статье.
Разбивка и перенос длинных слов.
Допустим, в нашем ограниченном по ширине контейнере, необходимо учесть такую коллизию как длинный текст.
[пример 1]
На картинке мы видим, что текст вылазит за границу контейнера (элемента DIV). Для него написаны следующие свойства:
div { width: 150px; height: 100px; padding: 10px; background-color: #00f000; }
div { width: 150px; height: 100px; padding: 10px; background-color: #00f000; } |
Если мы применим к нему дополнительно стиль
то информация, выходящая за границы будет просто обрезана. А нам нужен перенос.
Для указания, что в данном случае нам нужен перенос, воспользуемся word-wrap. По-умолчанию, значение этого свойства — normal, это соответствует случаю в примере 1. Давайте установим для него следующие значение:
div { … word-wrap: break-word; }
div { … word-wrap: break-word; } |
[пример 2]
Так мы достигаем желаемого результата — переноса длинного слова. Перенос выполняется с учетом внутренних отступов (padding).
Перенос слов не по границе слов.
Если бы мы наш пример разбавили пробелами, то задавать значение word-wrap не пришлось бы, т.к. браузер автоматически выполняет нужные переносы. То есть вот так:
[пример 3]
То как происходит разбивка управляется свойством CSS word-break. В примере 3 его значение установлено по умолчанию, оно соответствует вот такой установке:
div { … word-break: keep-all; /* или normal */ }
div { … word-break: keep-all; /* или normal */ } |
Т.е. разбивка текста производится на границе слов. Но мы можем заставить браузер разбивать фразу в любом месте предложения:
div { … word-break: break-all; }
div { … word-break: break-all; } |
[пример 4]
Благодаря такой разбивке предложение испытало перенос посреди слова «Constant».
Специальные «непереносимые» пробелы.
Возникают ситуации, когда нужно запретить перенос слов, но и пробелы между словами оставить.
Для этого случая в HTML существует спец символ — Non-breakable-SPace — « ». Если в третьем примере мы заменим все пробелы данным символом, то получим похожую на пример № 1 картинку:
[пример 5]
HTML код последнего примера:
<div > very Long Word Or Constant<br /> 3.14159 26535 89793 23846 26433 83279 50288 41971 </div>
<div > very Long Word Or Constant<br /> 3.14159 26535 89793 23846 26433 83279 50288 41971 </div> |
Как осуществить с помощью flexbox перенос на новую строку: позиционирование элементов
От автора: вот проблема: если вы хотите создать макет с несколькими строками элементов, как вы можете контролировать во flexbox перенос элементов на новую строку?
Предположим, вы хотите создать макет, который выглядит примерно так, с чередующимися строками из трех элементов и одним элементом на всю ширину:
Распространенным способом управления позиционированием и размером flex-элементов является использование width или flex-basic; если мы установим для четвертого элемента width 100%, он будет расположен в отдельной строке. Но что, если мы не хотим или не можем установить ширину отдельных элементов? Или есть ли способ просто указать flexbox разрыв строки в определенных точках?
Нет никакого свойства, которое мы могли бы установить для flex, чтобы оно переносило элементы на новую строку, но мы можем вставить перенос строки (вы можете представить это, как br) между двумя flex-элементами для достижения чего-то похожего:
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее/* Вставка разрыва строки между двумя flex-элементами заставит * flex-элемент, который расположен после него переноситься на новую строку */ .break { flex-basis: 100%; height: 0; }
/* Вставка разрыва строки между двумя flex-элементами заставит * flex-элемент, который расположен после него переноситься на новую строку */ .break { flex-basis: 100%; height: 0; } |
<div> <div></div> <div></div> <!— break —> <div></div> </div>
<div> <div></div> <div></div> <!— break —> <div></div> </div> |
Давайте рассмотрим некоторые сценарии, когда вы, возможно, захотите использовать это, а также некоторые интересные методы компоновки, которые позволяет нам это использовать.
Обратите внимание , что все примеры кода ниже, требуют и предполагают, что у вас есть контейнер с display: flex и flex-wrap: wrap и flex-элементы добавляются в этот контейнер:
.container { display: flex; flex-wrap: wrap; }
.container { display: flex; flex-wrap: wrap; } |
<div> <div></div> <div></div> <div></div> … </div>
<div> <div></div> <div></div> <div></div> … </div> |
Вставка элемента разрыва
Использование элемента для перехода к новой строке flexbox дает интересный эффект: мы можем пропустить указание ширины любого элемента в макете и полностью полагаться на разрывы строк для определения потока сетки.
Давайте начнем с простого примера. Скажем, у нас есть два элемента, отображаемые рядом (они будут растягиваться с помощью flex-grow: 1, и для них не определены ни width, ни flex-basis):
Мы можем вставить элемент разрыва строки между элементами, чтобы они оба заняли 100% доступного пространства:
<div>…</div> <div></div> <!— перенос на новую строку —> <div>…</div>
<div>…</div> <div></div> <!— перенос на новую строку —> <div>…</div> |
Это создает макет с двумя вертикальными элементами полной ширины (я добавил границу к элементу .break, чтобы проиллюстрировать его положение и поведение):
Как это работает? Так как мы указали, что .break должен занимать 100% ширины контейнера (потому что мы установили flex-basis: 100%), flex-элемент переноса должен размещаться в собственном ряду, чтобы достигнуть этого. Он не может размещаться в одном ряду с первым элементом, поэтому перейдет к новой строке, в результате чего первый элемент останется один в одной строке. Первый элемент будет растягиваться, чтобы заполнить оставшееся пространство (так как мы установили flex-grow: 1). Та же логика применима ко второму элементу.
Мы можем использовать эту технику для компоновки макета, описанного в начале статьи, разбивая последовательность до и после каждого четвертого элемента:
<div>…</div> <div>…</div> <div>…</div> <div></div> <!— разрыв —> <div>…</div> <div></div> <!— разрыв —> <div>…</div> <div>…</div> <div>…</div>
<div>…</div> <div>…</div> <div>…</div> <div></div> <!— разрыв —> <div>…</div> <div></div> <!— разрыв —> <div>…</div> <div>…</div> <div>…</div> |
Это создаст нужный макет. По сути, элемент не будет переноситься на новую строку, если мы не вставим элемент разрыва строки:
Опять же, нам не нужно было указывать ширину ни для одного из этих элементов. Тот же самый метод будет работать для столбцов, если у нас есть гибкий контейнер с flex-direction: column, и установлено значение width 0 (вместо height) для элемента разрыва строки:
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее/* Используем столбец разрыва для переноса в новый столбец */ .break-column { flex-basis: 100%; width: 0; }
/* Используем столбец разрыва для переноса в новый столбец */ .break-column { flex-basis: 100%; width: 0; } |
Такой подход с использованием элементов разрыва для определения макета добавляет некоторое раздутие и шум в HTML, но он может быть мощным инструментом при правильном использовании. Мы можем, например, использовать его для верстки макета кладки с помощью чистого CSS и динамически размещать разрывы с помощью свойства order. Мы также можем перейти к новой строке, не изменяя ширину какого-либо элемента содержимого, и мы можем полагаться исключительно на распределение пространства в макете сетки с помощью flex-grow.
Предположим, что мы хотим создать этот макет:
И предположим, что мы хотим сделать это, задав разные значения flex-grow для распределения пространства (вместо использования flex-basis или width, которые вам придется пересчитывать, когда вы добавляете или удаляете элементы):
.item { flex-grow: 1; } .item-wide { flex-grow: 3; }
.item { flex-grow: 1; } .item-wide { flex-grow: 3; } |
<div></div> <div></div> <div></div>
<div></div> <div></div> <div></div> |
Если затем мы хотим добавить еще одну строку элементов ниже этой:
Мы не сможем сделать это, не устанавливая flex-basis или width, по крайней мере, для некоторых элементов (или не создавая вложенный макет flexbox с одним flex-элементом для каждой строки). Если все элементы имеют разные значения flex-grow, и ничто не заставляет их переноситься на новую строку, они все просто втиснутся в одну строку:
Неплохо. Однако, если мы вставим элемент разрыва строки, мы можем построить этот макет, распределяя все пространство с помощью flex-grow:
.item { flex-grow: 1; } .item-wide { flex-grow: 3; }
.item { flex-grow: 1; } .item-wide { flex-grow: 3; } |
<div></div> <div></div> <div></div> <div></div> <!— разрыв —> <div></div> <div></div>
<div></div> <div></div> <div></div> <div></div> <!— разрыв —> <div></div> <div></div> |
Это задает нужный макет, со всеми размерами, определенными пропорционально через flex-grow:
И если будет сценарий, когда нам нужно пять элементов в первой строке, нам не нужно менять какой-либо CSS-код, чтобы это заработало, мы можем просто добавить эти элементы до разрыва строки:
<div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <!— разрыв —> <div></div> <div></div>
<div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <!— разрыв —> <div></div> <div></div> |
Все, что вам нужно добавить в CSS, чтобы использовать элементы разрыва строки — это эти два класса (единственное различие между этими двумя классами состоит в том, что для width (а не для height) необходимо установить 0, чтобы элемент разрывал столбец при использовании в макете столбцов):
/* Использование разрыва строки между двумя flex-элементами заставит * flex-элемент, который расположен после него, перенестись в новую строку */ .break { flex-basis: 100%; height: 0; } /* Используем разрыв столбца, чтобы перенести элемент в новый столбец */ .break-column { flex-basis: 100%; width: 0; }
/* Использование разрыва строки между двумя flex-элементами заставит * flex-элемент, который расположен после него, перенестись в новую строку */ .break { flex-basis: 100%; height: 0; }
/* Используем разрыв столбца, чтобы перенести элемент в новый столбец */ .break-column { flex-basis: 100%; width: 0; } |
Вы, безусловно, может достичь того же или подобного эффекта с помощью вложенных flexbox, когда для каждого ряда будет задан отдельный flexbox, но во многих случаях простое использование flex-basis, width или контента в пределах flex-элементов, вероятно, будет предпочтительным способ управления потоком элементов в макете flexbox. Вставка элементов разрыва является доступной и простой в использовании, она работает, и данная техника обладает некоторыми уникальными характеристиками, которые могут вам пригодиться.
Автор: Tobias Bjerrome Ahlin
Источник: https://tobiasahlin.com
Редакция: Команда webformyself.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнееPSD to HTML
Практика верстки сайта на CSS Grid с нуля
Смотреть