50

I have an HTML table 360px wide, which works great. The challenge is that sometimes a url appears http://this/is/a/really-really-really-really-really/long/url in the text. This causes the table to expand horizontally and a scroll bar appears on the bottom.

I don't think overflow:hidden will work because half of the text would be hidden.

What is the best way to force breaking the line on slashes (/) and dashes (-) in CSS (hopefully)?

It should work with IE7+, Chrome, Firefox and Safari.

Working in Rails 3 and jQuery.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
B Seven
  • 44,484
  • 66
  • 240
  • 385
  • 1
    This can also be done by using jQuery. See http://jsfiddle.net/EkfUR/ and duplicate question http://stackoverflow.com/questions/15159278/wrap-text-in-td-without-breaking-the-word – estrar Mar 01 '13 at 15:11

3 Answers3

74

tl;dr; (edited Apr 2022)

Use <wbr> word-break-opportunity element before each /. See first link in further reading below.

Details (original from 2014)

While the css word-wrap: break-word; does work, its implementation is different across browsers.

If you have control of the content and want exact breakpoints, you can insert

  • a <wbr> word break (supported in all major browsers except IE8 CanIUse.com);
  • &#8203; zero-width space (U+200B) - ugly in IE<=6
  • &shy; soft hyphen - though of course this adds a hyphen when breaking which is not always what is desired.

I have a large corporate user base who still have to use IE8, so when I hit this problem I used the C# someString.Replace("/", "/&#8203;") in the server-side code.

Gotcha: If you insert a zero-width space in an email address, when a user copies and pastes into their email client, the space gets copied too and the email will fail with no way for a user to see why (the space is zero width ...)

References

Further Reading

Ruskin
  • 5,721
  • 4
  • 45
  • 62
15

You can use word-wrap : break-word; like so:

    div {
        width : 50px;
        border : 1px solid #000;
        word-wrap : break-word;
    }
    <div>http://www.aaa.com/bbb/ccc/ddd/eee/fff/ggg</div>

I tested this in: I.E. 6/7/8, Firefox 7, Opera 11, Safari 5, Chrome 15

Here is a jsfiddle: https://jsfiddle.net/p4SxG/

Community
  • 1
  • 1
Jasper
  • 75,717
  • 14
  • 151
  • 146
  • 15
    Unless I'm misunderstanding the question, this doesn't appear to work in Chrome 21. I'm seeing the break happen at the last character that will fit rather than at slashes – Davy8 Sep 26 '12 at 18:07
  • 11
    Yeah, this solution definitely doesn't break at the slashes. – peter Dec 22 '12 at 00:01
  • 3
    The implementation is different in every browser. Even using the latest few versions of Chrome result in different behaviors. If you want something that's definitely going to break on slashes then I think you'll need to use JavaScript and replace the `/` characters with `/
    ` or something. I believe this answer got accepted because it solved the O.P.s issue, maybe not exactly as worded, but it rendered a fix.
    – Jasper Dec 22 '12 at 00:15
  • @Ghan I does for me and I'm using Chrome 44.0. Is the JSFiddle not breaking the URL properly for you? – Jasper Aug 27 '15 at 21:33
  • Hey @Jasper, not sure why but the solution here worked for me: https://kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css/ – Ghan Aug 28 '15 at 01:01
  • @Ghan You didn't really answer my question. Does the JSfiddle not correctly break the text for you? Because it does and I'm using Chrome 44. – Jasper Aug 31 '15 at 15:12
  • @Jasper fiddle works, but it wasn't working in my app. Again, not sure why. The method described in the above post was able to fix it for me. – Ghan Aug 31 '15 at 15:43
  • @Ghan Gotcha, it's an implementation issue. In that link you posted the only issue is that the `div` element has had it's `display` property set to `table-cell`. Removing that line of CSS makes `word-wrap : word-break` function correctly. Although based on what you're trying to do it may not be what you're looking for. – Jasper Aug 31 '15 at 20:14
  • The solution to use only "word-wrap: break-word;" fails in the above jsFiddle example on my phone using Chrome. The reason is because it will be forcing the "ddd" word to break on the first character and wrap the last two characters to the next line. – justdan23 Oct 21 '21 at 16:06
  • jsFiddle example does not work for me in latest desktop Chrome (major version 97). One of the line breaks lands between the first two 'b's. – Tim Sparkles Jan 26 '22 at 20:45
3

If you don’t really care where the breaks happen, the simplest method is to add the style overflow-wrap: break-word;. This will allow long words to break without affecting the breaking of other words.

But if you want to break at specific characters, such as the slash character, you can’t do that with CSS, you have to do it in HTML. If you have access to the HTML code you can choose any of these solutions:

  • <wbr> word break opportunity tag
  • &#8203; zero width space
  • &ZeroWidthSpace; zero width space

But you don’t always have access to the HTML code. Some web applications won’t allow you to enter code into certain fields; for example, WordPress will filter out any code you enter into a post title. In these situations you may be able to insert a zero-width-space character directly. One way to do this is to use Character Viewer (Mac) or Character Map (Windows), although of course they are a bit tricky to use when it comes to spaces because spaces are invisible. In the case of Character Viewer, when you search for arrow, lots of matches appear, but when you search for zero width space, it appears that no characters were found. But if you click where the blue square is in the second image below, you’ll discover that the character was found, it’s just invisible.

enter image description here

Another way to insert a zero-width-space character directly is to copy and paste one from somewhere else. Between the two hash symbols below is a zero-width-space character. Just copy the hash symbols, paste them where you need the zero-width-space, then carefully delete the symbols without deleting the invisible character between them.

#​#

A snippet to demonstrate that these various methods all work:

h1 {
  width: 15rem;
  border: 1px solid black;
}
.b {
  overflow-wrap: break-word;
}
A title which is too long
<h1>Seminars/Workshops</h1>
Breaking with CSS
<h1 class="b">Seminars/Workshops</h1>
Breaking with HTML: code-based solutions
<h1>Seminars<wbr>/<wbr>Workshops</h1>
<h1>Seminars&#8203;/&#8203;Workshops</h1>
<h1>Seminars&ZeroWidthSpace;/&ZeroWidthSpace;Workshops</h1>
Breaking with HTML: character-based solution (zero width space characters have been inserted directly both before and after the slash)
<h1>Seminars​/​Workshops</h1>

Here is a script to process your links and automatically add zero width spaces before every slash, except those in the initial ://

document.querySelectorAll('.breakify').forEach(e => {
  e.innerHTML = e.innerHTML.replaceAll(/(?<=[^:\/])\//g, '&ZeroWidthSpace;/')
})
p {
  max-width: 30em;
}
<p>Here is a really long link <a href="https://google.com">http://this/is/a/really/really/really/really/really/really/really/really/really/really/really/really/really/really/really/really/long/url</a> which does not break on the slashes.</p>

<p>Here is a really long link <a class="breakify" href="https://google.com">http://this/is/a/really/really/really/really/really/really/really/really/really/really/really/really/really/really/really/really/long/url</a> which now that we have added the breakify class to it, will break on the slashes.</p>
Brett Donald
  • 6,745
  • 4
  • 23
  • 51