tags:

views:

6179

answers:

6

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?

A: 

There was a loosely related problem here http://stackoverflow.com/questions/33933/textarea-with-100-width-ignores-parent-elements-width-in-ie7

Don't know if any conclusive solution was ever found, but it seems like the closest was word-break:break-all , which might do the job in Internet Exploder.

I also found this http://petesbloggerama.blogspot.com/2007/02/firefox-ie-word-wrap-word-break-tables.html buried in my bookmarks, which indicates a work around for most other browsers, which might help.

CSS3 will be great if it ever gets here...

Hope that helps, will be interested to see what you come up with. Sorry I can't offer anything tested or more specific.

seanb
+13  A: 

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 succesfully (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.

Owen
thank you thank you thank you so very much
Peter Perháč
A: 

Using a regular expression in PHP should be faster to breakup long words. I have created a function that handles htmlspecialchars and breaks up words with &shy; Here is the function for anyone who is interested. Just pass the string, and the max word length (leave as 0 if you dont want to break up words with &shy;) and it will return a string with html special chars converted and the words broken up with &shy;

function htmlspecialchars2($string = "", $maxWordLength = 0)
{
 if($maxWordLength > 0)
 {
  $pattern = '/(\S{'.$maxWordLength.',}?)/';
  $replacement = '$1&shy;';
  $string = preg_replace($pattern, $replacement, $string);
 }

 //now encode special chars but dont encode &shy;
 $string = preg_replace(array('/\&(?!shy\;)/','/\"/',"/\'/",'/\</','/\>/'), array('&amp;','&quot;','&#039;','&lt;','&gt;'), $string);

 return $string;
}
A: 

You can use table layout +word-wrap CSS attribute which now works in IE7-8 and FF3.5. It will not solve the issue but at least your design will not be broken.

Artem
+2  A: 

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;
}  
Jake Scott