Breaking up long words in HTML with Javascript/CSS

[update 10/17: The substitution has been updated to cover more browsers. This should work on every major modern browser, EXCEPT Safari -- I can find no solution for that browser. If you find a solution for Safari, or a browser this doesn't work on, please comment. Thanks!]

Long words can create a significant layout problem, especially for widgets which have to live in a small amount of screen space.

DaysSince and DaysUntil were both having a problem where very long words in the reminder description could push the “delete item” icon and other content off the right of the widget, make the text unreadable — and unreachable, so you can no longer delete the offending item.

What would be nice is to break up long words, but what’s the easiest way to do that, given that you don’t have a knowable fixed width to display in?

For a Javascript widget, this combination of regular expression and CSS hacks might get you what you need.

First, break up your strings with non-breaking spaces (nbsp), wrapped in a span that lets us make them invisible. If x holds the string with potentially long words, this regex will return this result (splitting every 9 characters).

x.replace(/(\S{8,}?)/g, "$1<wbr/><span class='break'> </span>")

In the regex,

  • ? is to make the match not greedy — that is, it will stop after just 8+1 characters.
  • /g is to match all 8+1 character or longer sets of non-whitespace characters
  • $1 returns the matched characters, to which we add a non-breaking space within a span that we’ll format below

Next, add a new selector to your CSS for the spans you just inserted, to make them invisible (credit to Martin Kliehm for this hack).

.break {
font-size: 1px;
line-height: 1px;
float:right !important;
float: none;
}

All the styles are essential — the two apparently conflicting float styles are to set different values for IE6 vs. other browsers.

Days Since and Days Until have been updated with this fix (it may take some time for Google’s caches to update — so use a new copy Add to Google to test.

Any refinements we can make to this solution? Anyone see any problems with specific browser versions?