421

I'm looking to prevent a line break after a hyphen - on a case-by-case basis that is compatible with all browsers.

Example:

I have this text: 3-3/8" which in HTML is this: 3-3/8”

The problem is that near the end of a line, because of the hyphen, it breaks and wraps to the next line instead of treating it like a full word...

3-
3/8"

I've tried inserting the "zero width no break character",  with no luck...

3-3/8”

I'm seeing this in Safari and thinking it will be the same in all browsers.

The following is my doctype and character encoding...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

Is there any way I can prevent these from line-breaking after the hyphen? I do not need any solution that applies to the whole page... just something I can insert as needed, like a "zero width no break character", except one that works.

Here is a Demo. Simply make the frame narrower until the line breaks at the hyphen.

http://jsfiddle.net/RagKH/

Brandon Rhodes
  • 83,755
  • 16
  • 106
  • 147
Sparky
  • 98,165
  • 25
  • 199
  • 285
  • @EricLeschinski, that's already been posted as an answer: http://stackoverflow.com/a/12362315/594235 – Sparky Nov 02 '16 at 20:04
  • With charset=utf-8 you can put in ‑ a non breaking hyphen – QuentinUK Dec 13 '18 at 01:00
  • @QuentinUK, right... isn't that already the accepted answer? `‑` is a non-breaking hyphen. – Sparky Dec 13 '18 at 04:09
  • 1
    ‑ is ordinary ASCII, so utf-8 is not necessary. With a utf-8 encoding of the page it is possible to put in the actual characters. ‑ is not the same character as - although it looks the same. – QuentinUK Dec 14 '18 at 01:33
  • The correct HTML for what you wrote, would be `3-3/8″` or `3-3/8″`. Quotes are not primes. If you want it in pure ASCII, just use straight double quotes instead (`"`). Preferably, if it is going to be presented as good, legible text, you would instead use `33/8″`, displaying ‘3⅜″’ – Canned Man Aug 08 '19 at 11:21
  • This duplicate question [provides a very useful answer](https://stackoverflow.com/a/34791403/4575793). – Cadoiz Feb 21 '22 at 10:59

7 Answers7

675

Try using the non-breaking hyphen &#8209;. I've replaced the dash with that character in your jsfiddle, shrunk the frame down as small as it can go, and the line doesn't split there any more.

CanSpice
  • 34,814
  • 10
  • 72
  • 86
  • 12
    I figured it was something like the non-breaking space, so I just searched for 'non-breaking dash', and [ended up here](http://www.cs.sfu.ca/~ggbaker/reference/characters/#dash). :-) – CanSpice Oct 07 '11 at 18:53
  • Ahhh... I did a _"no break character"_ search and hit the wall with that ``. It just never occurred to me that there was a stand-alone hyphen character that won't break. – Sparky Oct 07 '11 at 18:58
  • 7
    In IE8/9 this character renders longer than a typical hyphen. It appears to be the same size as an en-dash. – mrtsherman Dec 06 '12 at 17:42
  • 30
    The reason why the result may differ from a normal hyphen is that many fonts do not contain the non-breaking hyphen. This forces browsers to use a different font, and while the non-breaking hyphen looks the same as normal hyphen in *that* font, there is no guarantee that it matches a normal hyphen from a different font. – Jukka K. Korpela Mar 26 '13 at 08:31
  • 6
    I think Deb's answer is the best. – Ray Cheng Mar 17 '14 at 16:12
  • This sounds like the answer I need, though the below answer from Deb is what I originally solved the problem with. Until I saw xmojmr's comment, so now I am back to this answer, except the above does not work. Recognizing @Jukka K. Korpela's comment, I am now wondering if most web safe fonts such as Helvetica, and Arial, don't have this character, as I can't seem to get this to work with these fonts. – NinjaKC Oct 02 '15 at 20:32
  • Not everyone can use Deb's answer due to restrictions on what content you can enter into a CMS. – Chris Hayes Jun 23 '22 at 13:44
  • Also, beware that since the non-breaking hyphen is indeed a different character from the regular dash, copy-pasting it into source code or other contexts where exact equality tends to matter, you can run into trouble. Similarly, using Ctrl-F in the browser and typing a regular dash won't find the non-breaking hyphens. (However, this could be the best answer depending on one's situation, so I upvoted both this and Deb's answer.) – Aasmund Eldhuset Sep 01 '23 at 08:30
324

You could also wrap the relevant text with

<span style="white-space: nowrap;"></span>
Deb
  • 3,305
  • 1
  • 12
  • 2
  • 19
    Yes, this is a better answer than the accepted one imho. Thanks @Deb. – CMH Sep 16 '13 at 17:47
  • 53
    @CMH this does not help if you want to wrap whitespaces (blank places where user sees white space - nothing) but you don't want to split words with hyphens, e.g. word "e-mail". Accepted answer helps in this case – xmojmr May 08 '14 at 18:17
  • 14
    In that case you can just use span only around "e-mail". – guirto Oct 02 '14 at 12:12
  • 4
    @CMH, this is a good answer that also works, so I up-voted it. However, I chose not to accept this answer because I asked for a character that wouldn't automatically break to the next line. The fact that a "non-breaking hyphen" (`‑`) ***might*** render slightly longer than a regular hyphen in certain browsers was trivial to me. – Sparky Jun 16 '15 at 19:57
  • 18
    @Sparky One problem with using different characters is that it messes up search results. Trying to find "3-3/8" on the page will not find the nonbreaking hyphen. – Mr Lister Sep 04 '15 at 17:45
  • 1
    While IMO this is the best answer for webpages, in html emails at least Outlook 2013 doesn't respect that CSS. The non-breaking hyphen solution from @CanSpice though works in Outlook. – savehansson Sep 23 '15 at 10:35
  • Does not work on a modal/dialog (angular material) in Chrome. Created horizontal and vertical scroll bars. – jojo Sep 30 '15 at 22:37
  • I'm finding this causes the span element to break out of its container, instead of the whole thing inside the span wrapping to the next line. Behaviour seems to be: Wherever nowrap span starts, and no matter how long its content, just keep extending the line, regardless of parent container dimensions. – JKim Mar 08 '21 at 01:54
  • Of course this is not *always* a solution, but it worked for me to do this in the css to avoid annoying line breaks in my short `` snippets: `code { white-space: nowrap; }`. – njlarsson Apr 11 '23 at 09:41
  • I agree that this is a far better solution than the accepted one, especially when used in `` snippets that users can copy and paste. – David May 12 '23 at 01:08
29

IE8/9 render the non-breaking hyphen mentioned in CanSpice's answer longer than a typical hyphen. It is the length of an en-dash instead of a typical hyphen. This display difference was a deal breaker for me.

As I could not use the CSS answer specified by Deb I instead opted to use no break tags.

<nobr>e-mail</nobr>

In addition I found a specific scenario that caused IE8/9 to break on a hyphen.

  • A string contains words separated by non-breaking spaces - &nbsp;
  • Width is limited
  • Contains a dash

IE renders it like this.

Example of hyphen breaking in IE8/9

The following code reproduces the problem pictured above. I had to use a meta tag to force rendering to IE9 as IE10 has fixed the issue. No fiddle because it does not support meta tags.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=9" />
        <meta charset="utf-8"/>
        <style>
            body { padding: 20px; }
            div { width: 300px; border: 1px solid gray; }
        </style>
    </head>
    <body>
        <div>      
            <p>If&nbsp;there&nbsp;is&nbsp;a&nbsp;-&nbsp;and&nbsp;words&nbsp;are&nbsp;separated&nbsp;by&nbsp;the&nbsp;whitespace&nbsp;code&nbsp;&amp;nbsp;&nbsp;then&nbsp;IE&nbsp;will&nbsp;wrap&nbsp;on&nbsp;the&nbsp;dash.</p>
        </div>
    </body>
</html>
mrtsherman
  • 39,342
  • 23
  • 87
  • 111
  • 7
    Using `nobr` is the most cross-browser way and works independently of fonts and CSS. The `nobr` element is not defined in HTML specs, but this should be regarded as a formality only. But if you *must* write by HTML specs, then Deb’s answer, using CSS, is the best option. – Jukka K. Korpela Mar 26 '13 at 08:34
  • 5
    I'm curious why you couldn't use the CSS solution. – Ryan Ahearn Jul 25 '13 at 01:35
  • 2
    @RyanAhearn - I'm using a third party tool that does not give me much control over html. It does not support inline tag declarations. – mrtsherman Jul 25 '13 at 13:56
  • Instead of the '' could you have not just used a span with a class and controlled it using the CSS? – StephenESC Mar 12 '15 at 18:41
  • @StephenESC - I couldn't use an alternate hyphen character (as I pointed out in my answer because it displays incorrectly). A span would not have prevented breaking on a hyphen either. You can take the code example I provided and try it for yourself. That is, if you can find IE8/9. Getting rarer to see it these days. – mrtsherman Mar 12 '15 at 18:46
  • 3
    Note that the `nobr` tag is non-standard and might break any time. The MDN documentation does not recommend to use this tag: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nobr – Philipp Nov 05 '17 at 17:17
24

You can also do it "the joiner way" by inserting "U+2060 Word Joiner".

If Accept-Charset permits, the unicode character itself can be inserted directly into the HTML output.

Otherwise, it can be done using entity encoding. E.g. to join the text red-brown, use:

red-&#x2060;brown

or (decimal equivalent):

red-&#8288;brown

. Another usable character is "U+FEFF Zero Width No-break Space"[⁠&hairsp;⁠1&hairsp;]:

red-&#xfeff;brown

and (decimal equivalent):

red-&#65279;brown

[1]: Note that while this method still works in major browsers like Chrome, it has been deprecated since Unicode 3.2.


Comparison of "the joiner way" with "U+2011 Non-breaking Hyphen":

  • The word joiner can be used for all other characters, not just hyphens.

  • When using the word joiner, most renderers will rasterize the text identically. On Chrome, FireFox, IE, and Opera, the rendering of normal hyphens, eg:

    a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z

    is identical to the rendering of normal hyphens (with U+2060 Word Joiner), eg:

    a-⁠b-⁠c-⁠d-⁠e-⁠f-⁠g-⁠h-⁠i-⁠j-⁠k-⁠l-⁠m-⁠n-⁠o-⁠p-⁠q-⁠r-⁠s-⁠t-⁠u-⁠v-⁠w-⁠x-⁠y-⁠z

    while the above two renders differ from the rendering of "Non-breaking Hyphen", eg:

    a‑b‑c‑d‑e‑f‑g‑h‑i‑j‑k‑l‑m‑n‑o‑p‑q‑r‑s‑t‑u‑v‑w‑x‑y‑z

    . (The extent of the difference is browser-dependent and font-dependent. E.g. when using a font declaration of "arial", Firefox and IE11 show relatively huge variations, while Chrome and Opera show smaller variations.)

Comparison of "the joiner way" with <span class=c1></span> (CSS .c1 {white-space:nowrap;}) and <nobr></nobr>:

  • The word joiner can be used for situations where usage of HTML tags is restricted, e.g. forms of websites and forums.

  • On the spectrum of presentation and content, majority will consider the word joiner to be closer to content, when compared to tags.


• As tested on Windows 8.1 Core 64-bit using:
    • IE 11.0.9600.18205
    • Firefox 43.0.4
    • Chrome 48.0.2564.109 (Official Build) m (32-bit)
    • Opera 35.0.2066.92

Pacerier
  • 86,231
  • 106
  • 366
  • 634
16

Late to the party, but I think this is actually the most elegant. Use the WORD JOINER Unicode character &#8288; on either side of your hyphen, or em dash, or any character.

So, like so:

&#8288;—&#8288;

This will join the symbol on both ends to its neighbors (without adding a space) and prevent line breaking.

Eckstein
  • 785
  • 9
  • 27
  • 1
    I was able to get this to work using ALT+0173 (soft hyphen) for some reason on Windows 10. – pspahn Jan 28 '19 at 21:55
  • Wonderful solution! This is certainly the best way to ensure it will work without worrying about whether your font supports non-breaking characters. – Andron Nov 27 '22 at 19:04
4

Following on from @den’s useful JSX solution, this worked for me:

<h2>{props.name.replace('-', '-\u2060')}</h2>
Toby T
  • 81
  • 3
  • 1
    Also `replace('-', '\u2011')` which is equal to the non-breaking hyphen or `‑` (mentioned in the accepted answer) is a good option. – Shahriar Nov 28 '21 at 23:14
  • Nice answer. I would just add RegExp to replace all hyphens in text instead of the first one: `.replace(/-/gm, '-\u2060');` – Vincente Dec 02 '21 at 13:09
1

JSX solution example using word joiner unicode character:

<div>{`This is JSX-${'\u2060'}related example`}</div>
den
  • 336
  • 2
  • 12