Skip to content
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

[css-text] Interaction of text-wrap-style: balance and fragmentation #9431

Open
jfkthame opened this issue Oct 2, 2023 · 5 comments
Open

Comments

@jfkthame
Copy link
Contributor

jfkthame commented Oct 2, 2023

The spec for text-wrap-style: balance does not say anything about how it interacts with fragmentation, but I think it probably should.

What happens when a block with, say, four lines of text and text -wrap-style: balance applied is broken across pages? The point of balance is to improve the visual appearance of the block as a whole by harmonizing its line lengths (as far as possible), but if the block is broken into two (or more!) fragments, they are probably not visually adjacent and I'm not sure "balancing" the entire block makes much sense.

The implementation of balance recently landed in Gecko explicitly disables balancing for fragmented blocks. This is at least easy to understand, and probably won't interfere with most real-world uses of balance, but might sometimes be a frustrating limitation.

Experimentation indicates that Blink's current behavior is (IMO) a bit weird: when the block is fragmented, the first fragment gets the line-breaks that would result from applying balance to the entire (unfragmented) block (so e.g. what appears on the first page is affected by how full the lines on the second page would have been); but the subsequent fragment(s) get the default greedy line-breaking applied to whatever text was left.

What behavior do we actually want here? I can think of a few possibilities that could make sense to authors:

(1) balance does not apply to fragmented blocks
(2) balance applies before fragmentation, and fragmentation does not affect its outcome
(3) balance applies after fragmentation, so the lines within each fragment are balanced independently

My gut feeling is that (3) would be the most desirable behavior, but it may be trickier to implement and I'm not sure the use case (balancing lines in blocks that are being fragmented) is strong enough to warrant a more complex implementation. (1) is what Gecko's initial implementation does. Blink seems to start out trying to do (2), but then re-wraps the content after the fragmentation break, which doesn't make sense to me.

@frivoal
Copy link
Collaborator

frivoal commented Oct 2, 2023

For the related but different text-wrap-style: pretty, I'm pretty sure (3) is the right answer. (2) is probably not that different when each fragmentainer is the same width, but if when they're not, I don't think (2) makes a whole lot of sense.

But balance is not meant to apply to large pieces of text, and allows the UA to give up on things with two many lines. So maybe the use cases are different enough.

I think I'd still go with (3) as the general expected behavior, but would extend the allowance to give up when there are more than 10 lines to also be allowed (but not required) to give up if the block is fragmented.

@jfkthame
Copy link
Contributor Author

jfkthame commented Oct 2, 2023

For the related but different text-wrap-style: pretty, I'm pretty sure (3) is the right answer.

I'm not so sure. E.g. if pretty is attempting to avoid a very short last line, but the last fragment of the paragraph only contains two lines, it may have very little scope to improve things. OTOH, (2) would allow it to optimize the entire paragraph so as to get a "nice" last line even if this requires adjusting breaks several lines earlier.

FWIW, (2) would correspond to how TeX behaves: line-breaks are chosen for the paragraph as a whole, prior to any page- or column-breaking.

@frivoal
Copy link
Collaborator

frivoal commented Oct 2, 2023

I don't understand how (2) works if the fragment containers have a different width (which is not the typical case, but can happen).

if pretty is attempting to avoid a very short last line

That's only one of the things it's supposed to do, along with avoiding rivers, picking good wrapping points to avoid excessive hyphenation, excessive or justification…

But as you say, this is one of the things it needs to do, so it may indeed need to work across the fragmentation break. So (3) isn't quite right either.

I guess what we actually need is neither really (2) nor (3). (2) seems impossible: you can wrap then fragment if fragmenting can cause re-wrapping. But (3)'s idea of treating each fragment independently may be wrong too: as you said, we may want to adjust lines before the break for the sake of lines after the break.

@fantasai
Copy link
Collaborator

fantasai commented Jan 9, 2024

I think you want to optimize across the whole paragraph, across all fragments, but the line lengths might not be the same across fragments -- just like they aren't when floats intrude. So your algorithm needs to account for that.

@frivoal
Copy link
Collaborator

frivoal commented May 29, 2024

Should the resolution we passed in #9310 have an influence over what we do here? In that issues, we decided that for (-webkit-)line-clamp, we'd clamp first, and then balance. I'm inclined to do the same here: fragment first, and then balance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants