Why hyphens don't work with inner <span>?
Asked Answered
P

3

5

I'm trying to get hyphens working on text that has <span> elements inside for highlighting. This seems to break the hyphen algorithm. Is there any way to fix the behaviour so that hyphens are placed the same as without <span> elements? I'm not asking about a workaround like &shy;

enter image description here

The Code (sandbox: https://codepen.io/anon/pen/ayzxpM):

.limit {
  max-width: 50px;
  hyphens: auto;
  font-size: 20px;
  background-color: #eee;
}

span {
  color: red;
}
<div class="limit">
  <p>
    Appletreefruitthing
  </p>
  <p>
    Apple<span>tree</span>fruitthing
  </p>
</div>

Using the lang attribute

Adding the lang attribute as Vadim Ovchinnikov suggested (<div class="limit" lang="en">) can lead better results on some platform/browser combinations. On Firefox 54, Windows 10 this is the result:

enter image description here

But even that seems buggy. The hyphen should be black in my opinon and the hyphen algorithm seems to miss the chance to make a line break between "fruit" and "tree", also completly ignoring the max-width that is set for the container.

Panicle answered 26/7, 2017 at 7:15 Comment(4)
In which browser/OS does it happen? On Windows, Firefox hyphenates both words the same way, and Chrome, unfortunately, still doesn't support hypens at all there. Also, I had to set lang="en" to outer div to make it work in Firefox.Constantan
By the way, you want to make it work in all browsers or you just want to know why?Gismo
I see that hyphens in your example for p (regardless of inner span presence) doesn't work in Chrome, Firefox, IE and Edge (Win10).Gismo
Screenshot is from Chrome on OSX. Firefox Nightly on OSX does not work at all. Ideally a solution would be possible that works everywhere.Panicle
G
1

Chrome has only partial support for hyphens property (only Mac and Android platforms), so you can't make it work on Windows.

I don't see any difference between span presence and absence in Firefox, IE and Edge (all on Windows) for this code.

To make it work there you'll need set lang for container and add vendor prefixes (for -ms-hyphens IE/Edge and -webkit-hyphens for Safari). Demo:

.limit {
  max-width: 50px;
  font-size: 20px;
  /* Safari */
  -webkit-hyphens: auto;
  /* IE, Edge */
  -ms-hyphens: auto;
  hyphens: auto;
  background-color: #eee;
}

span {
  color: red;
}
<div class="limit" lang="en">
  <p>
   Appletreefruitthing
  </p>
  <p>
    Apple<span>tree</span>fruitthing
  </p>
</div>

To work in all browsers you may shouldn't use CSS hyphens property, just insert &shy; manually where you want hyphens.

.limit {
  max-width: 50px;
  font-size: 20px;
  background-color: #eee;
}

span {
  color: red;
}
<div class="limit">
  <p>
   Apple&shy;tree&shy;fruitthing
  </p>
  <p>
    Apple&shy;<span>tree</span>&shy;fruitthing
  </p>
</div>
Gismo answered 26/7, 2017 at 7:37 Comment(5)
Thanks! Although this is a valid workaround I am really inquring about the behaviour of the hypthens algorithm.Panicle
@Panicle Added details about hyphens property.Gismo
Did not know that the lang tag was required. Thought that setting it on the HTML should be enough. Slightly weird that the hyphen gets the highlighting from the next line. And why is there suddenly an overflow. It could split between "tree" and "fruit"?Panicle
@Panicle I'm not English language expert. Is this long word valid or should be split into separate shorter words to get desired results?Gismo
I updated the question to highlight some of the problems that remain even when setting the lang attribute. Seems like this is the best that one can get with all the browser/platform combinations I tested this morning.Panicle
G
2

Actually, it does work with spans, in a number of browsers. You just used a word that is not recognized. Here's an example with a normal English word, that works in IE (should also work in Edge) and FF on Win7:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1">
    <title>Demo</title>
<style>
div {
    max-width: 50px;
    -webkit-hyphens: auto;
    -moz-hyphens: auto;
    -ms-hyphens: auto;
    hyphens: auto;
    font-size: 20px;
    background-color: #eee;
}
span {
    color: red;
}
</style>
</head>
<body>
    <div>
        <p>Incomprehensibilities</p>
        <p>Incom<span>pre</span>hensibilities</p>
    </div>
</body>
</html>

It does not work in Chrome on Win, because that currently (June 2018) still does not support hyphens at all. It also does not work in any iOS browser. So you will have to use soft hyphens after all. But as you stated that you were curious about the mechanism, I thought it worthwhile to still post this answer.

Goldberg answered 28/6, 2018 at 21:3 Comment(0)
G
1

Chrome has only partial support for hyphens property (only Mac and Android platforms), so you can't make it work on Windows.

I don't see any difference between span presence and absence in Firefox, IE and Edge (all on Windows) for this code.

To make it work there you'll need set lang for container and add vendor prefixes (for -ms-hyphens IE/Edge and -webkit-hyphens for Safari). Demo:

.limit {
  max-width: 50px;
  font-size: 20px;
  /* Safari */
  -webkit-hyphens: auto;
  /* IE, Edge */
  -ms-hyphens: auto;
  hyphens: auto;
  background-color: #eee;
}

span {
  color: red;
}
<div class="limit" lang="en">
  <p>
   Appletreefruitthing
  </p>
  <p>
    Apple<span>tree</span>fruitthing
  </p>
</div>

To work in all browsers you may shouldn't use CSS hyphens property, just insert &shy; manually where you want hyphens.

.limit {
  max-width: 50px;
  font-size: 20px;
  background-color: #eee;
}

span {
  color: red;
}
<div class="limit">
  <p>
   Apple&shy;tree&shy;fruitthing
  </p>
  <p>
    Apple&shy;<span>tree</span>&shy;fruitthing
  </p>
</div>
Gismo answered 26/7, 2017 at 7:37 Comment(5)
Thanks! Although this is a valid workaround I am really inquring about the behaviour of the hypthens algorithm.Panicle
@Panicle Added details about hyphens property.Gismo
Did not know that the lang tag was required. Thought that setting it on the HTML should be enough. Slightly weird that the hyphen gets the highlighting from the next line. And why is there suddenly an overflow. It could split between "tree" and "fruit"?Panicle
@Panicle I'm not English language expert. Is this long word valid or should be split into separate shorter words to get desired results?Gismo
I updated the question to highlight some of the problems that remain even when setting the lang attribute. Seems like this is the best that one can get with all the browser/platform combinations I tested this morning.Panicle
S
0
hyphens: manual

togteher with

&shy;

might work see documentation here https://css-tricks.com/almanac/properties/h/hyphenate/

this code on codepen seems to work

<div class="limit">
  <p>
   Appletreefruitthing
  </p>
  <p>
    Apple&shy;<span>tree</span>&shy;fruit&shy;thing
  </p>
</div>

CSS

.limit {
  hyphens: manual;
}
Sealer answered 26/7, 2017 at 7:32 Comment(3)
Thanks! Although this is a valid workaround I am really inquring about the behaviour of the hypthens algorithm.Panicle
theres a bit of info here, try looking into 'hyphenation resource' w3.org/TR/2011/WD-css3-text-20110412/#hyphensSealer
I am surprised that this use-case isn't covered in more detail. Texts frequently need additional formatting and why should that change anything about the way the words are hypthenated. Perhaps I should open an issue for this use-case. Would be nice to set a property on the <span> that tells the hyphens algorithm to ignore this element and just read the text.Panicle

© 2022 - 2024 — McMap. All rights reserved.