We have helper functions in our project that serve to format values to human-readable and good-looking strings.
Due to design requirements the functions return text containing various whitespace characters (e.g. U+2009 «thin space» or U+200A «hair space»).
But the same design requirements require that the formatted text to be non-breaking.
So here we are.
We can return from these helpers HTML, not plain strings (and then apply white-space: nowrap
CSS to the HTML). But this requires to refactor all code that uses the helpers and complicates using the formatted values in components (we use React).
So this is the question: how to make any Unicode whitespace character non-breaking without HTML/CSS?
There is plenty of features in Unicode to combine characters into clusters and control the visual properties of text: combining characters and marks, joiners, selectors, modifiers, and so on. Maybe at least one of this variety makes it possible to make any whitespace character non-breaking? :)
Thank you.
U+2060 WORD JOINER is an invisible, zero-width character whose only effect is that it prevents line breaks at its position. Putting WORD JOINER after any whitespace character will therefore make it non-breaking. (Putting a WJ before the whitespace is not necessary because all spaces in Unicode automatically inhibit line-breaking immediately before them.)
UPD1 from the comments below:
The Unicode Standard absolutely requires WJ to retain its break-blocking property. However, there is a 7-years-old bug in Firefox with implementing the Unicode line-breaking algorithm, so in Firefox a combination whitespace+WJ works just like the whitespace without WJ.
In Chrome and Safari WJ works according to the standard.
UPD2 from the discussion in Twitter (credit to CharlotteBuff and FakeUnicode):
It is possible to use U+034F COMBINING GRAPHEME JOINER in place of U+2060 WORD JOINER as a workaround for Firefox. It prevents line-breaking in Firefox, but not in Chrome and Safari. Also such use of U+034F CGJ is semantically dubious because CGJ has a different intended purpose. Nevertheless it is highly unlikely that U+034F CGJ can cause any kind of accessibility problems (with screenreaders and similar stuff).
It is also possible to use U+200D ZERO WIDTH JOINER to prevent line-breaking. ZWJ works fine in the "big three" (Chrome, Safari, Firefox). However, ZWJ can have undesirable effects on the appearance of the surrounding text, because its purpose is to induce cursive joining in places where it otherwise wouldn’t happen automatically (e.g. in Arabic: م + ث + ل = مثل). If there are fancy ligatures in a font of the text with ZWJ, ZWJ can (and probably will) cause them to be triggered and change the shape of symbols nearby.
Note: the Wiki denotes ZWJ as «May break: Yes», but it is mistaken.
So, here are all the options to be seen and checked in your browser:
div {
outline: 1px solid red;
width: 20px;
margin: 10px;
}
<!-- U+00A0 NO-BREAK SPACE -->
<!-- just for example -->
<div>hello world1</div>
<!-- U+200A HAIR SPACE + U+2060 WORD JOINER -->
<!-- works fine, but does not work in FF -->
<div>hello ⁠world2</div>
<!-- U+200A HAIR SPACE + U+034F COMBINING GRAPHEME JOINER -->
<!-- works, but 1) semantically incorrect and 2) does not work in Chrome and Safari-->
<div>hello ͏world3</div>
<!-- U+200D ZERO WIDTH JOINER + U+200A HAIR SPACE + U+200D ZERO WIDTH JOINER -->
<!-- works, even in FF! -->
<div>hello‍ ‍world4</div>
<!-- U+200A HAIR SPACE + U+200D ZERO WIDTH JOINER -->
<!-- works, even in FF! -->
<div>hello ‍world5</div>
You might also use U+202F narrow no-break space.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With