Search code examples
cssword-wrapcss-hyphens

Word wrap with css `hyphens` fails to wrap substring


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.

enter image description here

.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;
}

Solution

  • 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.