w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.52k stars 672 forks source link

[css-text-4] Hyphenate only overflowing words? #616

Open Nettsentrisk opened 8 years ago

Nettsentrisk commented 8 years ago

As far as I understand the spec, there is currently no proposed way of allowing a CSS author to only hyphenate words that overflow their container, instead of all words that cross the container edge.

This is especially an issue with headings, as an author may want to avoid excessive hyphenation in a larger heading text if possible.

The current implementations based on the spec will hyphenate every word that crosses the container edge opposite of what is set with the text-align property.

Relevant part of the spec: https://drafts.csswg.org/css-text-3/#hyphens-property

An example: http://codepen.io/Nettsentrisk/pen/wzYAbo

Blog post describing the problem: https://www.epinova.no/en/blog/css-hyphenate-only-overflowing-words/

frivoal commented 8 years ago

Thanks for the proposal, it makes sense to me. Out of the possible syntaxes you've suggested in your blog, I would favor adding this through the overflow-wrap property: overflow-wrap: hyphenate.

As a workaround, you can do something like this: http://jsbin.com/wisuro/edit?html,css,output but it requires messing with the markup, and is doesn't work as well anyway, so it isn't a real solution.

kojiishi commented 8 years ago

What would you suggest if the words after hyphenation still overflows?

frivoal commented 8 years ago

What would you suggest if the words after hyphenation still overflows?

Of the top of my head:

yeahforbes commented 7 years ago

It might be useful to let this behavior emerge by simply using an extreme value for a sort of "hyphens-aggressiveness" property. Right now hyphens: auto is super aggressive: it seems to hyphenate whenever there's enough room for merely the first syllable of a word. If it were possible to do something like hyphens: auto; hyphens-aggressiveness: 0.5; to get roughly half as much hyphenation (i.e., only hyphenate where there's room for the first two syllables -- or whenever container overflow would occur), that would be quite nice. The extremes would be hyphens: auto; hyphens-aggressiveness: 0; (i.e., only whenever container overflow would occur) and hyphens: auto; hyphens-aggressiveness: 1; (i.e., equivalent to not setting hyphens-aggressiveness at all -- the current behavior).

TL;DR: Why only offer extremes when we could offer a continuous gradient?

With the extreme overflow-only behavior (aggressiveness of 0) you'd get this:

 -------------
|The most     |
|extraordinar-|
|y thing.     |
 -------------

There, the gap at the end of line 1 is quite large (just as we see whenever hyphenation is disabled). To a person desiring an "overflow-avoidance-only" hyphenation scheme, that gap is what you're looking for. But it has a disastrous effect because line 3 has just a tiny sliver of a word!

With the current behavior (aggressiveness of 1) you'd get this:

 -------------
|The most ex- |
|traordinary  |
|thing.       |
 -------------

There, the gap at the end of line 1 is minimized to the fullest extent, and the line ends with just a tiny sliver of a word! (See the pattern there?)

With a nice medium aggressiveness (say, any value around 0.3-0.7), you get this:

 -------------
|The most     |
|extraordi-   |
|nary thing.  |
 -------------

In that last example, even though "nar-" could fit on line 2, the lower aggressiveness causes it to concede a bit more gap on line 2 in exchange for avoiding orphaning the very short "y" -- this is nice typesetting.

I can think of 2 quite distinct algorithms for achieving medium aggressiveness:

  1. Strive to hyphenate only near the center of a word (similar number of syllables before and after the hyphen). More aggressiveness means more imbalance is allowable.
  2. Hyphenate only when not doing so would cause an end-of-line gap more than n% of the line width. More aggressiveness means smaller n%.

Lower values would err toward allowing larger end-of-line gaps (syllabic balance), while higher values would err toward encouraging smaller gaps (syllabic imbalance).

Nettsentrisk commented 7 years ago

I think that sort of algorithm would probably be taxing on the text rendering function in browsers, although that's only a guess based on limited technical knowledge of how this works.

Using a number for this would not really clue anyone in to what you're actually trying to accomplish, it should be described plainly in a way that is understandable.

Either you: A. break words as they hit the container edge opposite to the text-align property (e.g. right edge if text-align is left), regardless of whether it's needed or not B. break only words that cannot fit within the container, by breaking them at the first container edge after they begin C. ditto as B, but break them at the last container edge they cross D. ditto as B, but break them them in the middle (or divided evenly across number of lines needed to fit within container)

hyphens: auto now only does A.

My proposed solution hyphens: overflow was trying to solve B, but there might need to be a more granular approach to allow B, C or D, not just B.

Maybe something like:

kojiishi commented 7 years ago

@yeahforbes, CSS Text Level 4 defines some finer controls. Though its implemention is still limited, it's great if you can review them and see if they can suffice what you need.

yeahforbes commented 7 years ago

@kojiishi Aha! Those text level 4 properties seem to be plenty for what I described. I just wasn't successful in searching before commenting. Thanks.

@Nettsentrisk For sure, it would be a sizable increase in computation over what we have now. I agree that a number might not be intuitive (I was basing it off of values for properties like opacity) but on the other hand the value of hyphenate-limit-zone is defined as "the maximum amount of unfilled space (before justification) that may be left in the line box before hyphenation is triggered" and can be a percentage, i.e., at least loosely proportional to the type of number I'd suggested. While a few target setpoints available as words rather than exclusively a number are always nice, I think under the hood there's still the argument that they're simply special cases of a granular sliding scale.

Nettsentrisk commented 6 years ago

What values for hyphenate-limit-zone would work for the scenarios I described above (B, C, and D)?

fantasai commented 6 years ago

Reading through this issue, it seems like hyphenate-limit-zone would solve the problem. AFAICT, to make it only hyphenate words that can't be moved to the next line would be hyphenate-limit-zone: 100%. It's also possible to set it to a lesser amount, e.g. 3em or 25%.

Balancing lines is a separate control, text-wrap: balance. (It might be worth clarifying how it interacts with hyphenate-limit-zone, though.)

@Nettsentrisk Let me know if this seems to solve your problem?

Nettsentrisk commented 6 years ago

The explanation in the draft isn't all that clear, it would be great to see some examples.

From the explanation given there, it's not all that clear that 100% would produce scenario B, C or D that I listed above, or which of them it would produce in any case... 100% would seem to mean that you can have a completely empty line before triggering hyphenation, but would that mean that only words who cannot fit in the container on their own line will be hyphenated? That doesn't come across in the explanation.

My scenario B from above seems like the opposite of what is attained by using hyphenate-limit-last: always.

manuelmeister commented 2 years ago

I think this is still relevant and could make styling less fragile. With German, we have this problem especially often, because several words can easily be strung together without spaces:

"Berufsbildungszentrum", "Krankenhausempfang" or "Finanzdienstleistungsunternehmen" "Berufs-bildungs-zentrum", "Kranken-haus-empfang" or "Finanz-dienstleistungs-unternehmen" "Be•rufs•bild•ungs•zen•trum", "Kran•ken•haus•emp•fang" or "Fi•nanz•dienst•leis•tungs•un•ter•neh•men"

Most of the time I encounter this problem with headlines.

fantasai commented 1 year ago

Agenda+ to discuss the original proposal to allow hyphenation only in the case of overflow:

Syntaxes proposed so far (see top of thread):

css-meeting-bot commented 1 year ago

The CSS Working Group just discussed [css-text-4] Hyphenate only overflowing words?.

The full IRC log of that discussion <bramus> s/`updateCallbackDone /`updateCallbackDone`
<fantasai> https://github.com/w3c/csswg-drafts/issues/616#issuecomment-1368091416
<bramus> fantasai: link to comment
<bramus> fantasai: can you turn on hyphenation but only if it overflows?
<bramus> fantasai:
<bramus> fantasai: we could do this by adding keyword to overflow-wrap or hyphens property
<bramus> fantasai: hyphens controls hyphentation. values none/manual/auto
<bramus> fantasai: overflow-wrap controls what you are going to do with overflow
<bramus> fantasai: want to know if we want this addition and which one we prefer
<florian> q+
<bramus> astearns: fine with adding. slight preference for value in hyphens
<astearns> ack florian
<bramus> florian: opposite slight preference for adding to overflow-wrap. but otoh hyphens prop also related of course
<jfkthame> q+
<astearns> ack jfkthame
<bramus> florian: between line-break/word-break/overflow-wrap, lots of properties. [missed] adding extra keyword to that property keeps it that way.
<jensimmons> q+
<bramus> jfkthame: not sure if this is a good idea. its a very specific property. we already have other properties for authors, e.g. hyphenate-limit-zone
<bramus> astearns: you propose to setting that property to something close of width to only allow hyphentation in overflow cases?
<astearns> ack jensimmons
<bramus> jfkthame: i think it would have that effect
<bramus> jensimmons: seems like a valid use case.
<bramus> jensimmons: I can see ppl putting this in their default stylesheets and turning it on for everything. not sure on how exactly to do it
<bramus> fantasai: we should take back and check with hyphenate-limit-zone
<bramus> florian: same
<bramus> astearns: let’s take back to issue with jfkthame’s proposal
manuelmeister commented 1 year ago

I would still like this feature. I would prefer overflow-wrap: hyphenate;. If the language does not match or a word can't be sensible hyphened, I would expect it to just break-word.

This would be a suitable default for German because I have seen many German websites with headlines that overflow and make the page horizontally scroll. The use of &shy; (or its unicode character) can be difficult to input because it is often not visible (for example, in MS Word).

frivoal commented 1 year ago

So, we have 3 proposals, the two listed in https://github.com/w3c/csswg-drafts/issues/616#issuecomment-1368091416, and a third by @jfkthame, which I understand to be:

Syntaxes proposed so far (properties not listed assumed at initial value):

overflow-wrap hyphens hyphenate-limit-zone
Auto Overflow hyphenation overflow-wrap: hyphenate; hyphens: overflow; hyphenate-limit-zone: 100%;
hyphens: auto
Manual Overflow hyphenation overflow-wrap: hyphenate manual;
hyphens: none;
hyphens: overflow manual; hyphenate-limit-zone: 100%;
Overflow hyphenation,
fallback to wrapping
overflow-wrap: hyphenate break-word; hyphens: overflow;
overflow-wrap: break-word;
hyphenate-limit-zone: 100%;
overflow-wrap: break-word;

The overflow-wrap approach:

Pro
All options about what to do in case of overflow are in one property.
lets you have a choice of manual vs none for hyphenation when not overflowing on top of turning auto hyphenation when overflowing
Con:
would require `overflow-wrap` to acquire multiple keywords related to hyphenation, as we cannot use `hyphens: auto` vs `hyphens: manual` to chose the type of overflow hyphenation, since that already controls non-overflow hyphenation.

The hyphens approach :

Pro:
Only needs to add a signle keyword to hyphens about overflowing
Con:
Doesn't lets you have a choice of manual vs none for hyphenation when not overflowing on top of turning auto hyphenation when overflowing

The hyphenate-limit-zone approach:

Pro
Falls out of a property we already plan to have, nothing else is needed.
Con:
(Subjective) Not an obvious place to look for this control
Doesn't lets you have a choice of manual vs none for hyphenation when not overflowing on top of turning auto hyphenation when overflowing

Also, in any case, we might need a control to decide if hyphenation in case of overflow affects the minimum intrinsic size, as I think there's use cases for both: the general answer should be no, but inside tables the opposite is usually true, and for flex or grid, I think it might depend…

benface commented 9 months ago

we might need a control to decide if hyphenation in case of overflow affects the minimum intrinsic size

overflow-wrap: break-word currently doesn't have such a control (it never affects the minimum intrinsic size); why do you feel it would be needed for overflow-wrap: hyphenate?

frivoal commented 9 months ago

overflow-wrap: break-word currently doesn't have such a control

There is. If you use overflow-wrap: anywhere, that's the same as overflow-wrap: break-word, except for affecting intrinsic sizing.

benface commented 9 months ago

Ah, yes, thank you.

tarjep commented 2 months ago

Is there any progress on this? 😊