Open frivoal opened 2 months ago
In the 2024-09-12 I18N telecon, I was actioned to reply to this issue.
I think we assumed logical order elision. We think the right approach would be to place an RLM or LRM after the ellipsis when eliding text. The mark inserted would have the same directionality as the next (omitted) character. I am adding this issue to our agenda for Tuesday, 2024-09-17's I18N+CSS call.
In the 2024-09-12 I18N telecon, I was actioned to reply to this issue.
I think we assumed logical order elision. We think the right approach would be to place an RLM or LRM after the ellipsis when eliding text. The mark inserted would have the same directionality as the next (omitted) character. I am adding this issue to our agenda for Tuesday, 2024-09-17's I18N+CSS call.
Since in implementations the ellipsis insertion would happen as part of line breaking, could this be expressed in terms of which base embedding level the ellipsis isolate would have?
The CSS Working Group just discussed [css-overflow] Line-clamp and approaches to ellipsis insertion
, and agreed to the following:
RESOLVED: Remove characters *at* break opportunities *in* logical order, for line-break
This relates to https://github.com/w3c/csswg-drafts/issues/7708 about the value of the differences between the
continue: discard
andcontinue: collapse
approaches toline-clamp
, but looks into a narrower question.One of the ways
line-clamp
is deliberately different in the spec fromtext-overflow
as well as from the legacy-webkit-line-clamp
implementations is the way the ellipsis is inserted: where does it go, what happens to the underlying text. The differences are particularly important in the case of bidi text, though not limited to it. Alternative designs like thecontinue: collapse
proposal drafted by @andreubotella in response to the feedback from @bfgeek or @emilio have not retained that difference, and from conversations, it is not clear to me that this is deliberate, so I want to explore that aspect explicitly.text-overflow
has taken simple approach to ellipsis insertion: hide all the characters that overflow the line, plus a few more next to them at the physical end of the line to make room for the ellipsis, then paint it there. (There are nuances between the Chrome/webkit and the Firefox approaches, but I don't believe those nuances are relevant to the point I want to make here, so I'll skip over those details.) Legacy implementations of-webkit-line-clamp
reuse that logic.In my view, this design is appropriate for
text-overflow
.text-overflow
is concerned with a single line overflowing a scroll container in the inline direction. It leads to perfectly reasonable behavior when you actually scroll the box (in browsers that support that): more text is progressively revealed, everything makes sense.Taking an example of RTL text with some LTR text in it:
If the box is too small and
text-overflow: ellipsis
applies, you get this:As you scroll, more content gets revealed:
All good.
However, the situation for
line-clamp
and block ellipsis is not the same, and I don't think this approach works well. There is no content the overflows the line, so "hide all the characters that overflow the line, plus a few more next to them at the physical end of the line" doesn't make sense. you could still hide enough characters from the physical end of the line to make room for the ellipsis, but that ends up being counter intuitive to the reader. Think about the text that isn't visible: what is it? where is it? In the scrollingtext-overflow
case, it's the text at the (left) end of the line, and it's to be found by scrolling (towards the left). We can reason in spatial terms. But in theline-clamp
, the text hidden is the text of the next line(s). That text is the continuation in logical order of the text you can see.Let's look at an example:
Let's clamp it to 3 lines, using the approach used by the legacy
-webkit-line-clamp
implementations.Note that due to how the truncation happens, both the logical continuation of the text (“please!”, and the next line) and the logical start of the LTR fragment which is at the physical end of the line (“Ca’) are missing. This is confusing. Try for instance to think about what you'd show to the reader if you wanted to provide some affordance to see the hidden text, like a tooltip or something. Regardless of how you achieve that (js based, using
continue:fragments
, whatever), what would you even put in that tooltip? The best you can do is probably something like this, but that's rather strange.Instead, the approach specified for
line-clamp
removes content from the logical end of last line before the clamp to make room for the ellipsis.Here, in the reader's mind, there's no confusion about what part of the text is getting hidden: the next part, conceptually pushed to the next line if it were to exist. And if you were to show it in a tooltip, nothing would be weird (I've put an ellipsis in the tooltip, but that's a design choice that could be questioned, not inherent to the mechanism).
One might argue about the placement of the ellipsis on the last line. Here, as per spec, its position is determined by the direction of the surrounding block, which I'd argue is the right thing to do. But even if we instead decided to place the ellipsis according to the direction of the elided text, we'd still get sensible results, as we're still eliding in logical order.
Because of that, I continue to believe that for
line-clamp
(and its compatibility variant of-webkit-line-clamp
) we should stick to specified approach of eliding content in logical order on the line that gets the ellipsis (regardless of whether we follow an underlyingcontinue: discard
orcontinue: collapse
approach).As a follow up, working in logical order makes it a lot easier to also hook into line-breaking rules to decide the granularity of content that gets elided, which is how it is currently specified, and how I've done it in the examples above. Author feedback like this blog highlighted how eliding at arbitrary points could lead to awkward breaks in the middle of words, possibly leading to misunderstandings. Hooking into line breaking rules avoids this as it elides content word by word (for languages that use word-based line breaking), making it no more confusing that a regular line break. And it lets us opt into eliding up to hyphenation points, for instance. This is also robust internationally: for instance for CJK, it would honor the rules about line-break prohibition as a direct consequence of using the line breaking code, without having to reinvent it.
In simple cases, you could also re-build this on top of the
text-overflow: ellipsis
approach, but it would run into difficulties quickly as soon as bidi gets involved. For instance, consider a mixed Arabic/Japanese case:With a clamp of 1 line, the legacy approach does this (with a illustrative tooltip added):
Not only does this suffer from the same problem as earlier, where both the start and end of the Japanese fragment get elided, but in addition this separates the "じ" from the "ゃ" (and the "、"), which Japanese line breaking wouldn't do (as that distorts pronunciation). Solving that isn't a simple invocation of the usual line breaking code, as this is happening in the logical middle of the line and removing the logical start of that fragment, rather than at the logical end of the line and removing the logical end, as line breaking normally does.
Instead, following the specified approach and eliding content from from logical end, using usual line breaking rules, gives the more expected result:
or this one, if we place the ellipsis based on the direction of the elided content rather than of the block:
Even if we chose not have elision based on wrapping opportunities for now, or to have opt-ins or opt-outs for letter-by-letter elision, logical order elision makes it easier to open these possibilities.
So, as in the earlier part, I continue to believe that for
line-clamp
(and its compatibility variant of-webkit-line-clamp
) we should stick to the line-breaking approach currently specified when it comes to how much content gets elided (regardless of whether we follow an underlyingcontinue: discard
orcontinue: collapse
approach).