Open hftf opened 5 years ago
I believe the intent of the spec with hyphens: none
is to do what you expect, and that the fact that browsers don't suppress the wrapping opportunity around U+002D is a bug.
At the same time, I can see how the definition about hyphens: none
only talks about suppressing hyphenation opportunities, which isn't defined, and could be interpreted as only suppressing things that inject a hyphen, not suppressing wrapping opportunities around hyphens that are already there.
I think we should clarify that definition to make it more clear (possibly by defining hyphenation opportunity, possibly by rephrasing the whole thing).
Does this affect CSS Text Module Level 3 or Level 4, or neither?
Level 4 will eventually include everything that's in 3, but for now it focuses on additions. If we solve this by clarifying that this is already the expected behavior, this is a level 3 thing. If we solve it by adding a new control, it is a level 4. I'll start by tagging as level 3, under the assumption that what we want is a clarification.
Will it impact the Last Call?
We'll deal with all issues, including this one, before going to CR.
Usage data https://developer.microsoft.com/en-us/microsoft-edge/platform/usage/css/hyphens/ None is pretty high on the list, so I'm a bit concerned about changing its behavior.
U+002D is a break opportunity, not a hyphenation opportunity. A hyphenation opportunity inserts a hyphen if the line was broken there. U+002D doesn't do it. ­
is a hyphenation opportunity.
So maybe you want to tweak one of break opportunity properties.
@hftf Wow, this issue is incredibly well researched and detailed. Thank you so much for taking the time to gather all this information and write up the issue!
The CSS Working Group just discussed Prevent line breaking after explicit hyphens
, and agreed to the following:
RESOLVED: add a clarifying note to L3 and discuss a potential new value in L4
So, based on the teleconf discussion minuted above, we've agreed that the behavior currently observed in browsers (hyphens:none
does not suppress wrapping after U+002D or U+2010) was what the spec intended, and I just clarified that in https://github.com/w3c/csswg-drafts/commit/806cd4e5fa53507d14f8860cf41aa438d2b07e93
Now, as to whether we should have a separate control for this in level 4, everybody agreed that this was a useful thing to do in certain occasions, and we looked at different scenarios:
white-space:nowrap
is appropriate when there's a semantic justification for having a wrapping elementThe remaining question is whether there are case where you want to suppress wrapping at hyphenation that don't fall in any of these.
I think the answer is yes. Doing <code style="white-space:nowrap">grid-template-rows</code>
works fine to suppress the wrapping opportunity in that single word, but <code style="white-space:nowrap">grid-template-rows: 1fr min-content 2fr</code>
would also suppress wrapping at spaces, which isn't necessarily desired, and there's no particular justification for having wrapper elements around each token in a code sample. Similarly, code samples are often styled with white-space: pre-wrap
, and short of adding wrapper elements around every token, we cannot prevent wraps after hyphens.
Another example could be turning off wrapping after hyphens on people's names, to make sure there's no confusion about whether the hyphen is part of the name or inserted at layout time. But names can also contain spaces, and we don't want to suppress that wrapping opportunity.
Any other situation where the semantic of the phrase/paragraph/block (any piece of text that might contain spaces as well), rather than the semantic of the individual word calls for turning off wrapping after hyphens cannot be addressed without adding an explicit control. So I think we should have it.
Bikeshedding time? hyphens: nowrap
?
Thank you for investigating my issue!
I just clarified that in 806cd4e
I think this commit contains a typo: a visually indication
. I am also somewhat concerned that this only begins to define what a “hyphenation opportunity” is not, rather than what it is. Maybe explicitly contrasting the “hyphenation” mechanism with line breaking behavior would be a helpful addition here, as well as an explicit, unambiguous sentence that literally begins “A hyphenation opportunity is a….”
- For words like e-mail or T-shirt, the UA is already allowed to be smart enough and decide that hyphens after a single letter do not introduce a breaking opportunity, or some similar heuristic.
To clarify, is this independent of hyphenate-limit-chars
, which was suggested in the teleconf? From what I gather, that property only controls “hyphenation opportunities,” and so, as newly redefined, only could affect whether email
gets hyphenated to e-
and mail
, but not whether e-mail
breaks apart.
<dael> fantasai: Seems really weird that you'd take hyphenated phrase like one in issue, forbid breaking in a long term is unusually strict. I can see not breaking at a point that's not the hyphen, but breaking at hyphen I don't imagine you'd want to suppress.
<dael> fantasai: t-shirt could be a case where you don't break if it's less then 2 char on other side. You can control that for hyphenation in L4. <dael> fantasai: long-term breaking there is less likely to be because each half is too short
etc.
It’s not about whether the parts of a hyphenated compound are shorter than a threshold. In general, most hyphenated compounds are conceived as a single unit (and inflected atomically when spoken out loud). Personal names and hyphenated keywords in code are two good examples to add to my meager sample of three frequent English words. But I think the use case is much broader and is not “weird” or “unusual.” Keeping compounds together avoids interrupting or misleading the reader (a miscue or false scent or garden path) and increases legibility. Some style advice is collected below (not all relevant):
his commit contains a typo
Fixed in ecc7db8f62175d6ffff13b78171669ee38b44bcb. Thanks.
I am also somewhat concerned that this only begins to define what a “hyphenation opportunity” is not, rather than what it is.
Right, I agree the current text is still a bit hand-wavy about hyphenation opportunities. I thought it was worth lifting this particular ambiguity anyway, even if we later want to revisit to make the whole definition clearer, as that's where confusion has been. If you've got a suggestion for a complete rephrasing, I'm all ears.
I think cases like T-shirt or e-mail can be covered by the UA with the specification as it is, since the specification does not mandate that the break-after (BA) unicode line-breaking class be always respected, and so the UA could decide that (in English?) hyphen-minus should not introduce a wrapping opportunity when it is preceded by only one letter. Currently, Chrome and Safari do not do that, but Firefox does, as can be seen in this little demo: https://jsbin.com/hoqufobeje/edit?html,css,output.
Maybe we want to mandate that behavior specifically, but I suspect not, as such rules probably need to be language dependent (not to mention full of corner cases), and researching line-breaking best practices in all of the world's languages is beyond the scope of what we can hope to do in this specification. Maybe an note? Or, given that the spec already expects UAs to "do the right thing" for each language, even if the rules aren't spelled out explicitly, maybe the spec as it is is sufficient to consider that disallowing a break after the hyphen in “e-mail” is already must-do, and I can write a wpt test to check if it is being done.
As for the rest, yes, I'm with you. The links/quotes you gave show that there are situations where it's not desired to break after a hyphen. Since it's not universal, I don't think it would be the default, but a hyphens: nowrap
value, which would turn off hyphenation AND wrapping opportunities after hyphens, seems to be a very reasonable possibility to me.
Thank you, I agree with all of that. I don’t have enough expertise to suggest a better rephrasing though.
I don’t think anything needs to be mandated for cases like T-shirt or e-mail (at least, once there is an explicit control like hyphens: nowrap
for it). It could be informative to note that UAs can experiment.
Pushed some rephrasing in https://github.com/w3c/csswg-drafts/commit/723a74e442f4aada947c8f0bccb33a7186235432
Note the section quoted in https://github.com/w3c/csswg-drafts/issues/3463#issuecomment-450520488 is also relevant here wrt breaking “e-mail” and other words with similarly short segments.
Remaining things we could do:
nowrap
value to hyphens
in L4.All three of these make sense to me. Agenda+ for WG discussion/resolution.
The CSS Working Group just discussed Prevent line breaking after explicit hyphens
, and agreed to the following:
RESOLVED: Accept text for hyphenation in L3
Minor point but for nowrap
, I have a mild preference to add it to one of existing (or new) line breaking properties, so that we could add line breaking control for other characters than U+002D in future.
Regarding breaks after explicit hyphens: what about adding an optional fourth value to hyphenate-limit-chars, which is the minimum distance to the nearest hyphen - either explicit or automatically inserted.
This would allow users to allow or disallow hyphenation at all in a word containing an explicit hyphen (which is common practice I believe), or optionally allow it only for long words. See discussion of this at https://www.princexml.com/forum/topic/3316/hyphenation-of-overlong-words
Note they state:
Oxford University Press (Hart's Rules) is to allow hyphenating words in the phrase, but no closer than 6 letters from the closest in-text hyphen...
So there is precedence for this sort of logic.
Chromium issue: https://crbug.com/974470
Hi. I came across this thread as I need to transform this:
To this:
And I am not willing to use any of the workarounds (like adding extra HTML wrapper/element or using non-breaking hyphen), as my texts are coming from JSON translation files, and I'm not considering them as HTML.
My first go-to thought was word-break
property.
Links to selected style manuals and authorities
I have to commend you @hftf for well and thoroughly researched responses! I thought I was concise and detailed, but your prose in this forum is certainly a cut above and a model for others to imitate. Bravo!
Hi. I came across this thread as I need to transform this:
To this:
And I am not willing to use any of the workarounds (like adding extra HTML wrapper/element or using non-breaking hyphen), as my texts are coming from JSON translation files, and I'm not considering them as HTML.
My first go-to thought was
word-break
property.
Excellent illustration of what I believe @hftf is talking about. This is also exactly what I am trying to accomplish. I tried white-space: nowrap
, but it doesn't do what I expected. Then I found this post and reading the whole thread explained a lot. Thanks for the graphic!
This is a major issue with composed names like cities and first names. Ex.: Jean-François, Saint-Pamphile, etc.
Lots of writing guides and stylistic guides mention to never split a name like this. And just like @aghArdeshir mentioned, most of the times, I don't have control on the content itself so replacing manually or parsing the content before outputting it to the HTMl character is very much unviable.
The best solution would be a new value to the word-break property.
I personally would like the option to disable wrapping of hyphens-in-content, because of email addresses (e.g. an-email@example.com
) that I need to print to the page within a sentence, but have no control over the surrounding HTML (only CSS).
Given the high likelihood of the email address being copy-pasted, I cannot just replace the hyphen with a non-wrapping, visually-identical variant, and the enclosing sentence must still wrap in general, so I can't use white-space: nowrap
, either (so in my specific case, I'd expect the automatic wrapping to happen before the email address).
I noticed that word-break: keep-all
works in Safari and Firefox, but not in Chrome.
Test page: https://jsbin.com/zakacav/edit?html,css,output
Perhaps the behavior of Safari and Firefox for word-break: keep-all
should be codified so that Chrome follows suit. Seems like the simplest way to go about this.
I don't think the definition of keep-all
, as currently written, calls for that.
implicit soft wrap opportunities between typographic letter units (or other typographic character units belonging to the NU, AL, AI, or ID Unicode line breaking classes [UAX14]) are suppressed
But it may be argued that in spirit, this is a break within a word, and that keep-all
should handle that.
I think we have now several candidates, at least:
word-break: keep-all
to suppress breaks around explicit hyphens within wordshyphens
(nowrap
?)work-break
(no-hyphens
?)line-break
(no-hyphens
?)hyphenate-limit-chars
to make it apply to breaks after explicit hyphens, not just inserted onesThinking of this in terms of cascading and inheritance, which of these properties would be the best fit?
I want to prevent hyphenation/line breaking of words containing hyphens (hyphenated compounds). Some common examples of hyphenated compounds in English are T-shirt, long-term, and so-called.
Why?
This behavior is important for documents that prioritize legibility over aesthetics, such as:
These documents may want to apply the behavior to the entire document, not on a case-by-case basis.
¹ This very spec once faced a similar issue in which unwanted hyphenation led to confusion: #2307
Current status
CSS Text Module Level 3 does not define what hyphenation opportunities are:
Under
hyphens
, it says:However,
hyphens: none
does not give the expected result in most browsers. For example, see how Chrome 70/Mac renders this JSFiddle:I am concerned that the current spec gives authors very little control over a simple display requirement. For example, it never mentions the behavior of U+002D HYPHEN-MINUS, the most widespread hyphen character by far, even once.
Some workarounds
Wrap all hyphenated compounds in
<span style="white-space:nowrap;">
or<nobr>
(nonstandard).Cons:
Surround all hyphens with U+2060 WORD JOINER.
Cons:
Replace all hyphens with U+2011 NON-BREAKING HYPHEN.
Cons:
The Unicode Line Breaking Algorithm (UAX 14) recommends this method, but it seems rare in practice:
Possible solutions
hyphens: none
hyphens: none-including-hyphens
Questions
I can’t find any previous discussion on this topic; sorry if it’s a duplicate.
Thank you for considering this feedback – it’s my first time engaging with the standards process.
Further reading
616, #618, #1040