How to prevent long words from breaking my div?

Ever since switching from TABLE-layout to DIV-layout, one common problem remains:

PROBLEM : you fill your DIV with dynamic text and inevitably there is a super-long word that extends over the edge of your div column and makes your site look unprofessional.

RETRO-WHINING : This never happened with table layouts. A table cell will always nicely expand to the width of the longest word.

SEVERITY : I see this problem on even the most major sites, especially on German sites where even common words such as "speed limit" are very long ("Geschwindigkeitsbegrenzung").

Does anyone have a workable solution to this?


Soft hyphen

You can tell browsers where to split long words by inserting soft hyphen ( ­ ):

averyvery­longword

may be rendered as

averyverylongword

or

averyvery-
longword

A nice regular expression can ensure you won't be inserting them unless neccessary:

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

Browsers and search engines are smart enough to ignore this character when searching text, and Chrome and Firefox (haven't tested others) ignore it when copying text to clipboard.

<wbr> element

Another option is to inject <wbr> , a former IE-ism, which is now in HTML5:

averyvery<wbr>longword

Breaks with no hyphen:

averyvery
longword

You can achieve the same with zero-width space character &#8203; (or &#x200B ).


FYI there's also CSS hyphens: auto supported by latest IE, Firefox and Safari (but currently not Chrome):

div.breaking {
  hyphens: auto;
}

However that hyphenation is based on a hyphenation dictionary and it's not guaranteed to break long words. It can make justified text prettier though.

Retro-whining solution

<table> for layout is bad, but display:table on other elements is fine. It will be as quirky (and stretchy) as old-school tables:

div.breaking {
   display: table-cell;
}

overflow and white-space: pre-wrap answers below are good too.


Two fixes:

  • overflow:scroll -- this makes sure your content can be seen at the cost of design (scrollbars are ugly)
  • overflow:hidden -- just cuts off any overflow. It means people can't read the content though.
  • If (in the SO example) you want to stop it overlapping the padding, you'd probably have to create another div, inside the padding, to hold your content.

    Edit: As the other answers state, there are a variety of methods for truncating the words, be that working out the render width on the client side (never attempt to do this server-side as it will never work reliably, cross platform) through JS and inserting break-characters, or using non-standard and/or wildly incompatible CSS tags ( word-wrap: break-word doesn't appear to work in Firefox).

    You will always need an overflow descriptor though. If your div contains another too-wide block-type piece of content (image, table, etc), you'll need overflow to make it not destroy the layout/design.

    So by all means use another method (or a combination of them) but remember to add overflow too so you cover all browsers.

    Edit 2 (to address your comment below):

    Start off using the CSS overflow property isn't perfect but it stops designs breaking. Apply overflow:hidden first. Remember that overflow might not break on padding so either nest div s or use a border (whatever works best for you).

    This will hide overflowing content and therefore you might lose meaning. You could use a scrollbar (using overflow:auto or overflow:scroll instead of overflow:hidden ) but depending on the dimensions of the div, and your design, this might not look or work great.

    To fix it, we can use JS to pull things back and do some form of automated truncation. I was half-way through writing out some pseudo code for you but it gets seriously complicated about half-way through. If you need to show as much as possible, give hyphenator a look in (as mentioned below).

    Just be aware that this comes at the cost of user's CPUs. It could result in pages taking a long time to load and/or resize.


    This is a complex issue, as we know, and not supported in any common way between browsers. Most browsers don't support this feature natively at all.

    In some work done with HTML emails, where user content was being used, but script is not available (and even CSS is not supported very well) the following bit of CSS in a wrapper around your unspaced content block should at least help somewhat:

    .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) */
    }
    

    In the case of Mozilla-based browsers, the XBL file mentioned above contains:

    <?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>
    

    Unfortunately, Opera 8+ don't seem to like any of the above solutions, so JavaScript will have to be the solution for those browsers (like Mozilla/Firefox.) Another cross-browser solution (JavaScript) that includes the later editions of Opera would be to use Hedger Wang's script found here: http://www.hedgerwow.com/360/dhtml/css-word-break.html

    Other useful links/thoughts:

    Incoherent Babble » Blog Archive » Emulating CSS word-wrap for Mozilla/Firefox
    http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/

    [OU] No word wrap in Opera, displays fine in IE
    http://list.opera.com/pipermail/opera-users/2004-November/024467.html
    http://list.opera.com/pipermail/opera-users/2004-November/024468.html

    链接地址: http://www.djcxy.com/p/88100.html

    上一篇: 更改HTML表格中的文字环绕行为

    下一篇: 如何防止长篇大论打破我的div?