word wrap in css / js

I'm looking for a cross-browser way of wrapping long portions of text that have no breaking spaces (e.g. long URLs) inside of divs with pre-determined widths.

Here are some solutions I've found around the web and why they don't work for me:

  • overflow : hidden / auto / scroll - I need the entire text to be visible without scrolling. The div can grow vertically, but not horizontally.
  • Injecting ­ into the string via js / server-side - ­ is supported by FF3 now, but copying and pasting a URL with a ­ in the middle will not work in Safari. Also, to my knowledge, there isn't a clean method of measuring text width to find out the best string offsets to add these characters to (there's one hacky way, see next item). Another problem is that zooming in Firefox and Opera can easily break this.
  • dumping text into a hidden element and measuring offsetWidth - related to the item above, it requires adding extra characters into the string. Also, measuring the amount of breaks required in a long body of text could easily require thousands of expensive DOM insertions (one for every substring length), which could effectively freeze the site.
  • using a monospace font - again, zooming can mess up width calculations, and the text can't be styled freely.

Things that look promising but are not quite there:

  • word-wrap : break-word - it's now part of CSS3 working draft, but it's not supported by either Firefox, Opera or Safari yet. This would be the ideal solution if it worked across all browsers today :(
  • injecting <wbr> tags into the string via js/ server-side - copying and pasting URLs works in all browsers, but I still don't have a good way of measuring where to put the breaks. Also, this tag invalidates HTML.
  • adding breaks after every character - it's better than thousands of DOM insertions, but still not ideal (adding DOM elements to a document eats memory and slows downs selector queries, among other things).

Does anyone have more ideas on how to tackle this problem?


Css yo!

.wordwrap {
    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+ */ 
}

Also I just found this article http://www.impressivewebs.com/word-wrap-css3/

So you should use

.wordwrap {  
    word-wrap: break-word;
}  

.no_wordwrap {  
    word-wrap: normal;
}  

I've typically handled this using a combination of word-wrap and the <wbr> idea. note there are a few variants. as you can see, &#8203; is probably your best bet for compatibility.

word-wrap browser support isn't terrible, all things considered, Safari, Internet Explorer, and Firefox 3.1 (Alpha Build) all support it (src), so we may not be all that far off.

In regards to the server side breakage, I've used this method pretty successfully (php):

function _wordwrap($text)   {
    $split = explode(" ", $text);
    foreach($split as $key=>$value)   {
        if (strlen($value) > 10)    {
            $split[$key] = chunk_split($value, 5, "&#8203;");
        }
    }
    return implode(" ", $split);
}

Basically, for words over 10 characters, I split them at 5 characters each. This seems to work for all use cases I've been handed.