Open Nettsentrisk opened 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.
What would you suggest if the words after hyphenation still overflows?
What would you suggest if the words after hyphenation still overflows?
Of the top of my head:
overflow-wrap: hyphenate break-word
if hyphenation isn't enough break anywhereoverflow-wrap: hyphenate
if hyphenation isn't enough, overflow.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:
Lower values would err toward allowing larger end-of-line gaps (syllabic balance), while higher values would err toward encouraging smaller gaps (syllabic imbalance).
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:
@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.
@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.
What values for hyphenate-limit-zone
would work for the scenarios I described above (B, C, and D)?
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?
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
.
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:
Most of the time I encounter this problem with headlines.
Agenda+ to discuss the original proposal to allow hyphenation only in the case of overflow:
Syntaxes proposed so far (see top of thread):
overflow-wrap
option:
overflow-wrap: hyphenate;
To combine hyphenation with fallback to wrapping:
overflow-wrap: hyphenate break-word;
To combine overflow hyphenation with manual hyphenation:
hyphens: manual;
overflow-wrap: hyphenation;
hyphens
option:
hyphens: overflow;
To combine hyphenation with fallback to wrapping:
hyphens: overflow;
overflow-wrap: break-word;
To combine overflow hyphenation with manual hyphenation:
hyphens: overflow manual;
The CSS Working Group just discussed [css-text-4] Hyphenate only overflowing words?
.
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 ­
(or its unicode character) can be difficult to input because it is often not visible (for example, in MS Word).
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:
The hyphens
approach :
The hyphenate-limit-zone
approach:
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…
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
?
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.
Ah, yes, thank you.
Is there any progress on this? 😊
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/