Как не дать длинным словам сломать мой div? - PullRequest
146 голосов
/ 26 ноября 2008

После перехода с TABLE-макета на DIV-макет остается одна общая проблема:

ПРОБЛЕМА : вы заполняете свой DIV динамическим текстом, и неизбежно появляется сверхдлинное слово, которое простирается через край столбца div и делает ваш сайт непрофессиональным.

RETRO-WHINING : Это никогда не происходило с макетами таблиц. Ячейка таблицы всегда будет расширяться до ширины самого длинного слова.

SEVERITY : я вижу эту проблему даже на самых крупных сайтах, особенно на немецких сайтах, где даже такие распространенные слова, как «ограничение скорости», очень длинные («Geschwindigkeitsbegrenzung»).

У кого-нибудь есть работоспособное решение этой проблемы?

Ответы [ 26 ]

135 голосов
/ 26 ноября 2008

Мягкий дефис

Вы можете указать браузерам, где нужно разбивать длинные слова, вставив мягкий дефис (­):

averyvery­longword

может отображаться как

averyverylongword

или

averyvery-
* 1017 длинное слово *

Хорошее регулярное выражение может гарантировать, что вы не будете вставлять их, если в этом нет необходимости:

/([^\s-]{5})([^\s-]{5})/ → $1­$2

Браузеры и поисковые системы достаточно умны, чтобы игнорировать этот символ при поиске текста, а Chrome и Firefox (не проверяли других) игнорируют его при копировании текста в буфер обмена.

<wbr> элемент

Другой вариант - ввести <wbr>, бывший IE-ism , который теперь в HTML5 :

averyvery<wbr>longword

Разрывы без дефиса:

averyvery
* длинное слово 1040 *

То же самое можно сделать с помощью символа пробела нулевой ширины &#8203; (или &#x200B).


Между прочим, есть также CSS hyphens: auto, поддерживаемые последними версиями IE, Firefox и Safari (, но в настоящее время не Chrome ):

div.breaking {
  hyphens: auto;
}

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

Ретро-ноющий раствор

<table> для разметки это плохо, но display:table для других элементов в порядке. Это будет так же странно (и натянуто), как столы старой школы:

div.breaking {
   display: table-cell;
}

overflow и white-space: pre-wrap ответы ниже тоже хороши.

41 голосов
/ 26 ноября 2008

Два исправления:

  1. overflow:scroll - это гарантирует, что ваш контент будет виден за счет дизайна (полосы прокрутки уродливы)
  2. overflow:hidden - просто перекрывает переполнение. Это означает, что люди не могут читать контент.

Если (в примере SO) вы хотите, чтобы это перекрывало отступы, вам, вероятно, потребуется создать еще один div внутри отступа для хранения вашего контента.

Редактировать: как указано в других ответах, существует множество методов усечения слов, будь то определение ширины рендеринга на стороне клиента (никогда не пытайтесь делать это на стороне сервера, так как она никогда не будет работать надежно, перекрестно платформу) через JS и вставку символов разрыва, или использование нестандартных и / или дико несовместимых тегов CSS (word-wrap: break-word не работает в Firefox ).

Вам всегда понадобится дескриптор переполнения. Если ваш div содержит еще один фрагмент контента слишком широкого типа (изображение, таблица и т. Д.), Вам потребуется переполнение, чтобы он не разрушил макет / дизайн.

Так что во что бы то ни стало используйте другой метод (или их комбинацию), но не забудьте также добавить переполнение, чтобы охватить все браузеры.

Изменить 2 (чтобы ответить на ваш комментарий ниже):

Начните с использования свойства CSS overflow, но оно не является идеальным, но оно останавливает разрушение дизайна. Сначала примените overflow:hidden. Помните, что переполнение может не нарушаться при заполнении, поэтому либо вкладывайте div s, либо используйте рамку (что вам больше подходит).

Это позволит скрыть переполненный контент и, следовательно, вы можете потерять смысл. Вы можете использовать полосу прокрутки (используя overflow:auto или overflow:scroll вместо overflow:hidden), но в зависимости от размеров div и вашего дизайна, это может не выглядеть или работать отлично.

Чтобы исправить это, мы можем использовать JS, чтобы вернуть вещи назад и выполнить некоторую форму автоматического усечения. Я был наполовину в процессе написания какого-то псевдокода для вас, но на полпути это серьезно усложняется. Если вам нужно показать как можно больше, добавьте дефис (, как указано ниже ).

Просто имейте в виду, что это происходит за счет пользовательских процессоров. Это может привести к тому, что загрузка страниц и / или изменение их размера займет много времени.

33 голосов
/ 01 апреля 2009

Это сложная проблема, как мы знаем, которая не поддерживается каким-либо общим способом между браузерами. Большинство браузеров вообще не поддерживают эту функцию.

В некоторых работах, выполненных с электронными письмами в формате HTML, где использовался пользовательский контент, но сценарий недоступен (и даже CSS не очень хорошо поддерживается), следующий фрагмент CSS в обертке вокруг вашего свободного пространства блока контента должен как минимум помочь несколько:

.word-break {
  /* The following styles prevent unbroken strings from breaking the layout */
  width: 300px; /* set to whatever width you need */
  overflow: auto;
  white-space: -moz-pre-wrap; /* Mozilla */
  white-space: -hp-pre-wrap; /* HP printers */
  white-space: -o-pre-wrap; /* Opera 7 */
  white-space: -pre-wrap; /* Opera 4-6 */
  white-space: pre-wrap; /* CSS 2.1 */
  white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
  word-wrap: break-word; /* IE */
  -moz-binding: url('xbl.xml#wordwrap'); /* Firefox (using XBL) */
}

В браузерах на базе Mozilla упомянутый выше файл XBL содержит:

<?xml version="1.0" encoding="utf-8"?>
<bindings xmlns="http://www.mozilla.org/xbl" 
          xmlns:html="http://www.w3.org/1999/xhtml">
  <!--
  More information on XBL:
  http://developer.mozilla.org/en/docs/XBL:XBL_1.0_Reference

  Example of implementing the CSS 'word-wrap' feature:
  http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/
  -->
  <binding id="wordwrap" applyauthorstyles="false">
    <implementation>
      <constructor>
        //<![CDATA[
        var elem = this;

        doWrap();
        elem.addEventListener('overflow', doWrap, false);

        function doWrap() {
          var walker = document.createTreeWalker(elem, NodeFilter.SHOW_TEXT, null, false);
          while (walker.nextNode()) {
            var node = walker.currentNode;
            node.nodeValue = node.nodeValue.split('').join(String.fromCharCode('8203'));
          }
        }
        //]]>
      </constructor>
    </implementation>
  </binding>
</bindings>

К сожалению, Opera 8+ не похоже ни на одно из вышеуказанных решений, поэтому JavaScript должен быть решением для этих браузеров (например, Mozilla / Firefox.) Другое кросс-браузерное решение (JavaScript), которое включает в себя более позднюю версию. редакции Opera будут использовать скрипт Хеджера Вана, найденный здесь: http://www.hedgerwow.com/360/dhtml/css-word-break.html

Другие полезные ссылки / мысли:

Incoherent Babble »Архив блога» Эмуляция CSS-переноса слов для Mozilla / Firefox
http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/

[OU] В Opera нет переноса слов, отлично отображается в IE
http://list.opera.com/pipermail/opera-users/2004-November/024467.html
http://list.opera.com/pipermail/opera-users/2004-November/024468.html

27 голосов
/ 12 января 2011

CSS кросс-браузерный перенос слов

.word_wrap
{
    white-space: pre-wrap; /* css-3 */
    white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
    white-space: -pre-wrap; /* Opera 4-6 */
    white-space: -o-pre-wrap; /* Opera 7 */
    word-wrap: break-word; /* Internet Explorer 5.5+ */
}
14 голосов
/ 09 августа 2010

Используйте стиль word-break:break-all;. Я знаю, что это работает на столах.

13 голосов
/ 26 ноября 2008

Вы имеете в виду, что в браузерах, которые его поддерживают, word-wrap: break-word не работает?

Если включено в определение тела таблицы стилей , оно должно работать во всем документе.

Если переполнение не является хорошим решением, только пользовательский javascript может искусственно разбить длинное слово.

Примечание: есть также <wbr> тег Word Break . Это дает браузеру место, где он может разбить строку. К сожалению, тег <wbr> работает не во всех браузерах, только в Firefox и Internet Explorer (и Opera с трюком CSS).

9 голосов
/ 25 августа 2010

Только что проверил IE 7, Firefox 3.6.8 Mac, Firefox 3.6.8 Windows и Safari:

word-wrap: break-word;

работает для длинных ссылок внутри div с установленной шириной и без объявления переполнения в css:

#consumeralerts_leftcol{
    float:left;
    width: 250px;
    margin-bottom:10px;
    word-wrap: break-word;
}

Я не вижу проблем с несовместимостью

6 голосов
/ 16 июля 2012

После долгих боев у меня сработало:

.pre {
    font-weight: 500;
    font-family: Courier New, monospace;
    white-space: pre-wrap;
    word-wrap: break-word;
    word-break: break-all;
    -webkit-hyphens: auto;
    -moz-hyphens: auto;
    hyphens: auto;
}

Работает в последних версиях Chrome, Firefox и Opera.

Обратите внимание, что я исключил многие из white-space свойств, которые предлагали другие, - которые фактически нарушили отступ pre для меня.

6 голосов
/ 26 ноября 2008

Я только что узнал о переносе из этого вопроса . Это может решить проблему.

5 голосов
/ 06 марта 2013

Для меня на div без фиксированного размера и с динамическим контентом это работало, используя:

display:table;
word-break:break-all;
...