I recently switched from overflow-wrap
to hyphens
for breaking text between lines. However, I have encountered a case that seemingly fails to hyphenate any words before a certain substring. I am at a loss as to why this could be.
Observe the gif below, the full string to be displayed is /people/type:astronauts/name-gregory-chamitoff/profile
however when the width is less than about 210px
none of the words in the substring /people/type:astronauts/name-
are ever hyphenated and pushed to the next line. But, longer that 210px
the hyphenation works fine. It's almost like it's treating this substring as a continuous word.
.test {
font-size: 20px;
width: 210px;
/* adding this works but defeats the use of hyphens
overflow-wrap: break-word;
*/
hyphens: auto;
overflow: hidden;
background-color: white;
}
html {
background-color: black;
}
<div class="test">/people/type:astronauts/name-gregory-chamitoff/profile</div>
The only thing I have found that fixes this is to use something like that below as a catch-all. This is great however, it does not prioritize hyphenating over breaking of the words. I am looking for other solutions than this that makes hyphens
work for all or most strings, or even this one case!
.test {
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
hyphens: auto;
}
As @Salman A has pointed out, quite a lot of characters (e.g like slashes or colons, undescores etc.) are not recognized as proper word/syllable joints. Strings like "chamitoff/profile" will be treated as one long compound word "chamitoffprofile".
When it comes to URL like strings, you don't want to overflow – you'd still be better off with something like word-break: break-word;
Speaking of css hyphens
property: its capabilities are still 'limited' (at least in 2021).
E.g. Chrome has introduced support for this feature in version 88 (according to caniuse).
Here's a resizable snippet:
*{
box-sizing:border-box;
}
body{
font-family: 'Segoe UI';
font-size: calc(1.75vw + 1.75vh / 2);
padding: 10px;
}
.resizable{
width: 20ch;
height: 10em;
hyphens: auto;
resize:both;
overflow:auto;
padding-right:1em;
border: 1px solid #ccc
}
.resizable p{
hyphens: auto;
}
.break-words{
hyphens: none;
word-break: break-word;
}
<h2>Example</h2>
<div class="resizable">
<p>people/type:astronauts/name-gregory-chamitoff/profile <br /><strong>Original</strong></p>
<p>peopletype:astronautsname-gregory-chamitoffprofile <br /><strong>Dash replaced by hyphens</strong></p>
<p>peopletype_astronautsname_gregory_chamitoff_profile <br /><strong>Dash replaced by underscores</strong></p>
<p>peopletype astronautsname-gregory-chamitoffprofile <br /><strong>Dash and colons replaced by hyphens</strong></p>
<p>peopletype astronauts name gregory chamitoff profile <br /><strong>Dash replaced by spaces</strong></p>
<p class="break-words">people/type:astronauts/name-gregory-chamitoff/profile <br /><strong>Dash replaced by spaces</strong></p>
</div>
<h2>URLs</h2>
<div class="resizable">
<p><a href="#">https://www.maybeweshouldhaveoptedfor ashorterdomain.com/contact/specialinterest?product_id=1234567878</a> <br /><strong>URL – "hyphenated"</strong></p>
<p class="break-words"><a href="#">https://www.maybeweshouldhaveoptedfor ashorterdomain.com/contact/specialinterest?product_id=1234567878</a> <br /><strong>URL – word-break</strong></p>
<p class="break-words"><a href="#">contact@maybeweshouldhaveoptedfor ashorterdomain.com</a> <br /><strong>Email example</strong></p>
</div>
Unless browsers/css-implementations widely support improved hyphenation concepts like hyphenate-limit-chars
(... formerly existent) or hyphenation exception rules you should really curb your enthusiasm.
Conclusion
(2021 – hopefully we'll see improvements the next years)
You still have to choose between an imperfect 'brute-force' method like word-break – at least preventing undesired overflows
and an inelaborate (... to be very polite) css based hyphenation property/feature that's still missing any mandatory fine grained controls.