Skip to content

[css-text] Introduce a text-wrap-style value focused on orphans #10837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 13, 2024
92 changes: 86 additions & 6 deletions css-text-4/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -5501,7 +5501,7 @@ Selecting How to Wrap: the 'text-wrap-style' property</h3>

<pre class="propdef">
Name: text-wrap-style
Value: auto | balance | stable | pretty
Value: auto | balance | stable | pretty | reduce-orphans
Initial: auto
Applies to: [=block containers=] hat establish an [=inline formatting context=]
Inherited: yes
Expand Down Expand Up @@ -5612,9 +5612,87 @@ Selecting How to Wrap: the 'text-wrap-style' property</h3>
<dt><dfn>pretty</dfn>
<dd>
Specifies the UA <em>should</em> bias for better layout over speed,
and is expected to consider multiple lines,
and is expected to consider multiple lines
when making break decisions.
Otherwise equivalent to ''text-wrap-style/auto'',
Otherwise equivalent to ''text-wrap-style/auto''.

The user agent may among other things
attempt to avoid excessively short last lines,
similarly to ''reduce-orphans'',
but it should also improve the layout in more ways.
The precise set of improvements is user agent dependent,
and may include things such as:
reducing the variation in length between lines;
avoiding <a href="https://en.wikipedia.org/wiki/River_(typography)">typographic rivers</a>;
prioritizing different classes of [=soft wrap opportunities=], [=hyphenation opportunities=], or [=justification opportunities=];
avoiding hyphenation on too many consecutive lines…

<div class=advisement>
The necessary computations may be expensive,
especially when applied to large amounts of text.
Authors are encouraged to asses the impact on performance
when using ''text-wrap-style: pretty'',
and possibly use it selectively where it matters most.
</div>

<dt><dfn>reduce-orphans</dfn>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<dt><dfn>reduce-orphans</dfn>
<dt><dfn>avoid-orphans</dfn>

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc: @astearns The key is to find a term that indicates that the value is about getting rid of orphans, but not in all circumstances, and not at any cost.
avoid as suggested here by @fantasai is already used in CSS (see https://drafts.csswg.org/indexes/) in a number of places with the meaning "don't, unless [X]", so I think it can work: the precise criteria for when not to do it is left up to the UA, but it is there.
To me, reduce could work too, but the meaning is almost too weak: instead of a rule generally applied with exceptions as implied by avoid, it would seem to indicate a slant, a preference. It's not wholly inappropriate here, especially given that everything is largely up to the user agent anyway, but that seems weaker than the author intent we're aiming for.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m OK going with avoid for now. But I do think that authors are going to expect that all orphans will be eliminated, and UAs absolutely should not do that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

authors are going to expect that all orphans will be eliminated

If they don't think about too much, probably. But if you show them examples of cases where it would be bad to do so, and it doesn't do so, I suspect they'll be happy with the result, since forcibly doing it would be ugly.

<dd>
Specifies the UA <em>should</em> avoid excessively short last lines,
and is expected to consider more than one line
when making break decisions.
The user agent may decide against improving the last line
when it would make some prior line(s) substantially unbalanced.
The user agent should not attempt to improve other aspects of the layout
beyond what ''text-wrap-style/auto''
if that comes at a significant performance cost.

Note: In western typography, an “orphan” typically refers to a single word on the last line of a paragraph.
However, not all languages or writing systems wrap lines at word boundaries,
and even in languages that do,
a few very short words on the last line may still be undesirable,
especially if the available inline space is long.
This specification does not therefore strictly define
lines to be too short only when they are composed a single word,
and lets the user agent be the judge of what is excessively short.

Note: See also the 'orphans' property for control over fragmentation
and the other typographic meaning of “orphans”.

<div class=example>
For instance, with the given line length, the following test would be wrapped with a single word on the last line,
which could be judged too short.
<pre lang=grc style="border: solid lightgray 8px; border-bottom: none; border-top: none; width: 45ch;">
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα
πολλὰ πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον
ἔπερσεν.
</pre>
Applying ''text-wrap-style: reduce-orphans'' could yield something like this instead,
which is arguably more pleasing:
<pre lang=grc style="border: solid lightgray 8px; border-bottom: none; border-top: none; width: 45ch;">
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς
μάλα πολλὰ πλάγχθη, ἐπεὶ Τροίης ἱερὸν
πτολίεθρον ἔπερσεν.
</pre>
</div>
<div class=example>
However, the following fragment is more vexing:
<pre style="border: solid lightgray 8px; border-bottom: none; border-top: none; width: 17ch;">
Circumnavigating
the Mississippi
river
</pre>
An attempt to make the last line less short by wrapping the previous line earlier would result in the following:
<pre style="border: solid lightgray 8px; border-bottom: none; border-top: none; width: 17ch;">
Circumnavigating
the
Mississippi river
</pre>
While the last line would indeed no longer be short,
the penultimate line would be unsightly.
In such cases, user agents are expected
to prefer the first rendering
despite ''text-wrap-style: reduce-orphans'' being set.
</div>
</dl>

<!-- add a sample prioritization algorithm -->
Expand All @@ -5626,10 +5704,12 @@ Selecting How to Wrap: the 'text-wrap-style' property</h3>
UAs can experiment with better line breaking algorithms
with this default value,
but as optimal results often take more time,
''text-wrap-style/pretty'' is offered as an opt-in
''text-wrap-style/pretty'' and ''reduce-orphans'' are offered as opt-ins
to take more time for better results.
The ''text-wrap-style/pretty'' value is intended for body text,
where the last line is expected to be a bit shorter than the average line;
Both values are intended for body text,
where the last line is expected to be a bit shorter than the average line,
but ''reduce orphans'' aims to avoid excessively short last lines and to stay performant,
while ''pretty'' can sacrifice more speed in pursuit of even better layout;
the ''text-wrap-style/balance'' value is intended for titles and captions,
where equal-length lines of text tend to be preferred;
and the ''text-wrap-style/stable'' is intended for sections that are,
Expand Down