Show hyphens only when necessary? (the soft hyphen won't cut it off)
P粉225961749
P粉225961749 2023-08-25 11:10:51
0
2
630
<p>Is it possible to use hyphens or soft hyphens in CSS so that hyphens are not rendered unnecessarily? </p> <p>My goal is to keep the original text as much as possible and break out any words unless absolutely critical because they are too long to fit in the container width. </p> <h3>My specific case</h3> <p>I want to render the text "Hi Superman" like this: </p> <p>If the word "Superman" is too long to fit into the container, I want to hyphenate it somehow, like: </p> <pre class="brush:php;toolbar:false;">Hi Super- man</pre> <p>However, if the word "Superman" can fit into the container, it must be rendered without hyphens</p> <pre class="brush:php;toolbar:false;">Hi Superman</pre> <p>If the above situation is possible ("Superman" can be hyphen-free), then adding <em>unnecessary hyphens</em> is not acceptable: </p> <pre class="brush:php;toolbar:false;">Hi Super- man</pre> <p>I can change the HTML if needed. I can insert hyphens in a meaningful way (as long as there are more than 3 letters between each hyphen. "Superma-n" is never good)</p> <h3>What I tried</h3> <p>I think soft hyphens are the solution. So I used:<code>Hi Super­man</code></p> <p>But I find that this leads to the unacceptable situation of "unnecessary hyphens" shown above. </p> <h3>Show failed snippet: </h3> <p> <pre class="snippet-code-css lang-css prettyprint-override"><code>body { margin-left: 30px; } div { border: solid 1px black; } .wide { border: solid 1px blue; width: 500px; } .narrow { border: solid 1px red; width: 360px; } h2 { font-family: 'Courier New'; font-weight: 400; font-size: 87px; } code { background-color: #eee; }</code></pre> <pre class="snippet-code-html lang-html prettyprint-override"><code><p> <code>Super&amp;shy;man</code> looks good in really narrow containers where the full word "Superman" would not fit</p> <p> <div class="narrow"><h2>Hi Super&shy;man</h2></div> <p>But in this case the word "Superman" would fit unhypenhated on the second row. But the damn CSS decides to add hyphens anyway. Unacceptable in my case! Again, this uses the same code as the previous example <code>Super&amp;shy;man</code></p> <div class="wide"><h2>Hi Super&shy;man</h2></div> <p>I even tried adding a wordbreak tag before "Superman", like this <code>Hi <wbr> Super&amp;shy;man</code> but it does not help</p> ; <p> </p> <div class="wide"><h2>Hi <wbr>Super&shy;man</h2></div></code></pre> </p> <p>Can I solve the above example using just CSS? (Tried different <code>word-break</code> attributes with no success)</p> <p><strong>My guess</strong> is that due to the nature of CSS, it is impossible to solve this problem using just plain HTML and CSS. I'm assuming CSS just parses text line by line, it can never know if a word "fits better" in the next line of text. If a hyphen is found, it will try to fit the maximum number of characters in the current line of text. </p> <p>I would like to solve this problem using only HTML and CSS, or not at all. </p> <p>Best:</p> <ul> <li><p>Does not use JavaScript for text parsing. </p> </li> <li><p>I don't want to have to set different CSS properties for each div based on the width of the div and whether I think the text needs a hyphen. </p> </li> <li><p>Don’t want to add wrapping around my text</p> </li> <li><p>Not having auto-hyphens results in ridiculous hyphens like "Superma-n" (but in a pinch I can use auto-hyphens as long as there are 3 characters between each hyphen .For example "Sup-erman" )</p> </li> </ul></p>
P粉225961749
P粉225961749

reply all(2)
P粉701491897

CSS 3 includes a "hyphens" property that sets hyphens based on the specified lang property. But this is just a working draft, so support is a bityet.

You can set it to

  • None, so hyphens will not be displayed
  • Manually, so it will only break words where the special character &shy is declared, or
  • auto, which will automatically add hyphens where needed based on localization.

Works fine in Firefox, Edge and even IE, but the main problem is that webkit doesn't support the "auto" value. Except on Mac and Android, this is the only value they accept. Yes, this is a weird bug.

This is an example, if you are running windows/linux be sure to check the difference between Firefox and Chrome.

p { 
  width: 55px;
  border: 1px solid black;
 }
p.none {
  -webkit-hyphens: none;
  -ms-hyphens: none;
  hyphens: none;
}
p.manual {
  -webkit-hyphens: manual;
  -ms-hyphens: manual;
  hyphens: manual;
}
p.auto {
  -webkit-hyphens: auto;
  -ms-hyphens: auto;
  hyphens: auto;
}
<ul>
    <li><code>auto</code>: hyphen where the algorithm is deciding (if needed)
    <p lang="en" class="auto">An extremelyasdasd long English word</p>
  </li> 
  <li><code>manual</code>: hyphen only at &amp;hyphen; or &amp;shy; (if needed)
    <p lang="en" class="manual">An extreme&shy;lyasd long English word</p>
  </li>
  <li><code>none</code>: no hyphen; overflow if needed
    <p lang="en" class="none">An extreme&shy;lyasd long English word</p>
  </li>
</ul>

A common workaround for webkit's lack of "auto" support is to use hyphens:auto with webkit's work-break:break-all, so the text will be connected using hyphens:auto on browsers that support it. Character concatenation and no hyphen wrapping on webkit.

P粉950128819

Use containers with display: inline-block around long words.

body { 
  margin-left: 30px;
}
div {
   border: solid 1px black;
}
.wide {
  border: solid 1px blue;
      width: 500px;
}
.narrow { 
  border: solid 1px red;
  width: 360px;
}
 h2 {
   font-family: 'Courier New';
    font-weight: 400;
    font-size: 87px;
  }
code {
 background-color: #eee;
}

.unbreakable {display:inline-block}
<p> <code>Super&amp;shy;man</code> looks good in really narrow containers where the full word "Superman" would not fit</p>
<p>
<div class="narrow"><h2>Hi <span class="unbreakable">Super&shy;man</span></h2></div>

<p>And in this case the word "Superman" would fit unhypenhated on the second row.<br/>
This uses the same code as the previous example</p>
<div class="wide"><h2>Hi <span class="unbreakable">Super&shy;man</span></h2></div>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template