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-overflow] Consider support for multiple-line ellipsis #390

Closed
phistuck opened this issue Aug 8, 2016 · 41 comments
Closed

[css-overflow] Consider support for multiple-line ellipsis #390

phistuck opened this issue Aug 8, 2016 · 41 comments

Comments

@phistuck
Copy link
Contributor

phistuck commented Aug 8, 2016

https://drafts.csswg.org/css-overflow/
Like text-overflow: -o-ellipsis-lastline, or -webkit-line-clamp did. Details at http://stackoverflow.com/questions/6572330/is-it-possible-to-use-text-overflowellipsis-on-multiline-text

@phistuck phistuck changed the title [css-overflow] Consider support for multiple line ellipses [css-overflow] Consider support for multiple line ellipsis Aug 8, 2016
@phistuck phistuck changed the title [css-overflow] Consider support for multiple line ellipsis [css-overflow] Consider support for multiple-line ellipsis Aug 8, 2016
@frivoal
Copy link
Collaborator

frivoal commented Aug 9, 2016

This is being considered, but this is a surprisingly difficult problem to solve well. The existing solutions you refer to work in some simple cases, and fall apart in the general case.

The eventual solution is expected to use the max-lines property and the continue property (possibly renamed) to define where your content should be cut, and what happens to the remaining part after the cut, and probably a (yet to be specified) pseudo element to define what gets inserted to show the ellipsis.

@RByers
Copy link
Contributor

RByers commented Aug 10, 2017

Note that apparently a huge amount of the mobile web depends on webkit-line-clamp (we see it used on 15% of page views on Android). @miketaylr says this is one of the top web compat issues in Firefox, and so I've re-opened a chromium bug saying that (if we can't remove it) we need to specify our behavior somewhere. @tabatkins said awhile back he'd be happy to help with this.

Should we work on this in css-overflow, or would it make more sense first to just try to document the existing WebKit/blink -webkit-line-clamp behavior in the compat spec?

@tabatkins
Copy link
Member

tabatkins commented Aug 15, 2017

So I've spent some time thinking about this in the past. I think there are two modes that people realistically want when clamping, which end up being quite distinct:

  1. I want to display N lines of content, however large that ends up being. This should affect the layout size of the element, so it'll tightly fit the content (aka make it act like it was always filled with just N lines of content, no more).

  2. I want to lay out an element normally, but if this would overflow, instead clamp to the largest number of lines possible without overflowing. (And size the element as if it were overflowing; that is, make it as large as possible, even if that leaves some empty space in the content area.)

The former is easy and simple, and basically what -webkit-line-clamp does. We should be able to port over its functionality into a spec for this pretty simply, I think.

The second is closer to what people often actually want, and approximate by just guessing at the number of lines that'll display in the space they have. Maybe it's a type of overflow-style value? I dunno.

@RByers
Copy link
Contributor

RByers commented Aug 17, 2017

Thanks Tab. Given how much usage of -webkit-line-clamp there is, it's really only (1) that I consider urgent here. Even though it's not ideal and we might not choose to ship such a new API now without also doing (2), that ship has effectively sailed - might as well document and test that as a first step, then (if it's important enough) iterate on improving and extending it.

@tabatkins
Copy link
Member

I'm in agreement with this; the two can definitely ship separately, even if the first one isn't actually what's desired a lot of the time. It's Good Enough© for a first pass.

@RByers
Copy link
Contributor

RByers commented Aug 17, 2017

Excellent, thanks Tab!

So you'll work on a proposed change to css-overflow for this? Presumably you'll follow the typical CSSWG style of defining it as line-clamp and then we'll add an entry to the compat spec requiring -webkit-line-clamp as an alias, right?

Or since the existing API isn't exactly what people often want, would it be better to just define -webkit-line-clamp here, leaving the better line-clamp available? Or we could even choose a clearly poor but un-prefixed name for the CSS spec like legacy-line-clamp or line-count-clamp?

@tabatkins tabatkins self-assigned this Aug 17, 2017
@fantasai
Copy link
Collaborator

I think ideally, it would make more sense to spec this feature as equivalent to max-height, except with the ability to specify that height in terms of number of lines.

This would require using overflow: hidden in conjunction with the property in order to actually hide the lines, but that would then give the author the control to make those lines visible with overflow: scroll or, in the future, to paginate them to another fragmentainer.

So, basically, I'm agreeing with Florian about the direction to go in, but to solve the cases that -webkit-line-clamp currently solves, we don't need the additional fragmentation support, just the max-lines property itself. If there's no strong compat restriction that will require us to exactly duplicate -webkit-line-clamp, then I think this is a better direction to go in: the behavior is simple to define in terms of existing CSS models, and it is extensible to behaviors we want to allow in the future, like stying the first N lines specially.

@frivoal
Copy link
Collaborator

frivoal commented Aug 18, 2017

I think ideally, it would make more sense to spec this feature as equivalent to max-height, except with the ability to specify that height in terms of number of lines.

This would require using overflow: hidden in conjunction with the property in order to actually hide the lines, but that would then give the author the control to make those lines visible with overflow: scroll or, in the future, to paginate them to another fragmentainer.

Basically, I think that's what -webkit-line-clamp does except that:

  • it requires display: -webkit-box and -webkit-box-orient: vertical to be set as well, or it does not take effect (wtf?)
  • it also adds "…" at the end of the last (non overflowing) line.

I suppose we can work around the first part by some clever aliasing strategy that (for web compat reasons) continues to require the odd properties and values to be set when using this feature under the -webkit-line-clamp name, and not when used under the max-lines name.

When max-lines is used together with the (not yet existing) fragmentation property, it probably should not affect the height, and let that continue to be a separate thing, but I suppose we can make that behavior depend on whether the fragmentation property is used.

I am not even sure that we have to skip making it depend on fragmentation. Fragmentation (especially if we're going to discard the remaining content) is pretty well defined and supported already. If Web compat allows (which is far from a given), we could probably handle making max-lines imply continue: discard. That's not the hard part of this property: continue: fragments is, and that can be implemented later. But if that's either too complex, or undesirable as a default, I agree that it is possible to not have this connection.

On the other hand, inserting the ellipsis is probably trickier. webkit-line-clamp's ellipsis rightfully appears to be smarter than text-overflow: ellipsis, but defining exactly how it works is probably going to be interesting if we want to make it robust (interactions with floats, atomic inlines, nested blocks, font changes, ::after, transforms...). And even if in the first pass we are happy with just inserting an inert "…", we need to keep in mind that people also have usecases both for making this interactive ("click here for more"), and for using structured & stylable content instead of the "…".

I suppose this is fine though. We can just imply that the current limited ellipsis is the result of something like a max-lines-ellipsis property being auto (and possibly also introduce a none value while we're at it), and that whatever alternative better system we come up later will just build from there.

@SebastianZ
Copy link
Contributor

May I mention the use case for cropping contents in the middle again?

See https://www.w3.org/wiki/Text-overflow_middle_cropping and the discussions around it on www-style.

Sebastian

@frivoal
Copy link
Collaborator

frivoal commented Aug 18, 2017

@SebastianZ Right. I think that's also part of "we need a smarter ellipsis".

@frivoal
Copy link
Collaborator

frivoal commented Aug 18, 2017

that said, think middle cropping is more suited to text-overflow than to this

@tabatkins
Copy link
Member

...shit, I totally misunderstood this feature. It is almost exactly what fantasai suggests; it just calculates the natural height (height: auto;) based on only looking at N lines.

(To be precise, it appears to do this "pretend it's only got N lines of content for height-determination purposes" for each block of inline content in the element independently; break up the inline content with another block, and both the preceding and following will be clamped to N lines. See http://software.hixie.ch/utilities/js/live-dom-viewer/saved/5310 for a demonstration.)

I was under the impression that it actually suppressed fragment generation for everything after the Nth line, which is actually useful in a lot of ways. As it is, you have to use overflow anyway, or else the lines after the clamp will just visibly overflow!

@fantasai, sorry for misleading you yesterday in our discussion over this. :(

it requires display: -webkit-box and -webkit-box-orient: vertical to be set as well, or it does not take effect (wtf?)

It's a hack built on top of our old Flexbox implementation. Blame Hyatt. ^_^


Okay, so that brings us to a conundrum: how much of the current behavior do we want to preserve? In particular, is the "apply clamping separately to each inline formatting context child" behavior required and/or desired, or would we prefer to just spec that it applies only to the first such one, or perhaps that it continues its count across inline formatting contexts?

We can just imply that the current limited ellipsis is the result of something like a max-lines-ellipsis property being auto (and possibly also introduce a none value while we're at it), and that whatever alternative better system we come up later will just build from there.

Yes, I think that's good enough for now. Proper block-flow ellipsis is a hard problem that we need to solve at some point, but there's no reason to block this on having that solved.

@RByers
Copy link
Contributor

RByers commented Aug 19, 2017

Okay, so that brings us to a conundrum: how much of the current behavior do we want to preserve?

This obviously depends a lot on the web compat implications. The simplest answer is perhaps to get UseCounters added to chromium for behavior you might want to change and see what hits. We also now have some ability to compare screenshot diffs of the top 10k sites with and without a change. I can also easily get a list of sites that use -webkit-line-clamp in some form and digging into a random sample of ~20 would probably give us a pretty good idea of what behavior is required. Or you could also just spec what you think is probably a good tradeoff and someone could try shipping that and see how it goes :-)

@tabatkins
Copy link
Member

Okay, let me be more precise about the options as I see them, then:

  1. Each root inline formatting context descendant of the block applies the max-lines separately.

  2. The max-lines count is maintained across each root inline formatting context descendant of the block, "cutting it off" when the total number of lines hits the max.

  3. The max-lines count only applies to the first root inline formatting context descendant of the block. Any additional ones act as normal, not clamping at all.

  4. Same as (3), but any additional root inline formatting contexts act lay out as if they're empty (like max-lines: 0 was applied to them).

(1) is the current behavior of -webkit-line-clamp. (2) is perhaps closer to what authors would expect; the element sizes to accommodate exactly N lines of text total. (3) and (4) are simpler in concept, if we think that having more text in the element is a minority use-case we don't need to worry about.

@tabatkins
Copy link
Member

If there's no other constraints, I think I prefer speccing (2); I was quite surprised at the fact that (1) is the current behavior.

@atanassov
Copy link
Contributor

Option 2 solves some cases better than 1 and at the same time introduces behavior that might be unexpected to authors compared to line-clamp (if I read your proposal right).

Applying max-lines:3 to a block with few nested paragraphs <div style='max-lines:3'><div><p>[text] will apply to the inner most root inline context and clamp the number of lines to 3 - that's good.

On the other hand, if there is text between <div style='max-lines:3'>[text]<div>[text]<p>[text] option 2 suggests we need to generate a total of up to 3 lines for each root inline context. That means we are expected to produce either:
A) multiples of 3 lines
B) total of three lines that are potentially not related (for ex. one line of each root inline context).

Neither of A or B options seems great, though arguably b is a bit better but much harder to implement since there will be too much sibling related layout data that needs to be passed around.

@tabatkins
Copy link
Member

I think you've read option 2 completely backwards? I'll make them clearer with some examples.

Everyone uses the same markup:

<!DOCTYPE html>
<section>
  foo foo foo foo foo foo foo foo foo foo foo foo foo
  <hr>
  bar bar bar bar bar bar bar bar bar bar bar bar bar
</section>
<style>
section { 
  display: -webkit-box; 
  -webkit-box-orient: vertical; 
  -webkit-line-clamp: 2; 
  width: 100px;
}
</style>

Option 1 is today's behavior - the "foo" text fills out two lines, gets an ellipsis, then continues flowing for two more lines and overflowing the following content. Then the "bar" text does the same thing - fills out two lines, gets an ellipsis, then continues flowing for two more lines and overflowing

Option 2 will have "foo" text fill out two lines, get an ellipsis, then continue flowing for two more lines and overflow. The "bar" text just overflows immediately (treated as it it has 0 lines in it, because the section has already laid out two lines of text).

Option 3 will have "foo" text fill out two lines, get an ellipsis, then continue flowing for two more lines and overflow. The "bar" text lays out normally (because it's not the first inline context in the block, so it doesn't care).

Option 4 will be identical to 2 for this case, but if there was only 1 line of "foo" text, the "bar" text would still overflow immediately. (Option 2 would instead lay out one line of "bar" text before overflowing, for a total of 2 lines.)

@bfgeek
Copy link

bfgeek commented Sep 11, 2017

As a FYI, I've added a bunch of use-counters to our -webkit-box implementation to try and work out what folks are using it for.

https://www.chromestatus.com/metrics/feature/popularity

  • search for anything prefixed with WebkitBox*

These UseCounters went into our M62 branch (I think*) and should have some data by the end of October (probably).

Probably the most interesting stat will be the:
WebkitBoxLineClampOneChildIsLayoutBlockFlowInline
That is, -webkit-box has exactly one child, which is a root-inline, and -webkit-line-clamp is being applied.

How this differs to the other counters (specifically, WebkitBoxLineClamp) will give us an idea of what folks are doing.

@bfgeek
Copy link

bfgeek commented Sep 11, 2017

I should also mention that we'll probably try and deprecate and remove properties related to -webkit-box which don't have high usage or any effect.

E.g.
-webkit-box-lines
percentage version of -webkit-line-clamp
-webkit-box-ordinal-group
etc.

@css-meeting-bot
Copy link
Member

The Working Group just discussed Line Clamping.

The full IRC log of that discussion <iank_> Topic: Line Clamping
<TabAtkins> GitHub: https://github.com//issues/390
<iank_> TabAtkins: Ignore the topic of the github issue, basically many years ago, hyatt added some hacky code that turned the -webkit-box code, to allow it to do line clamping.
<iank_> TabAtkins: If you have more ignore them for sizing purposes.
<iank_> TabAtkins: The implemenation is weird, very weird behaviour, property etc.
<iank_> TabAtkins: We'd like to address this properly.
<iank_> TabAtkins: This is the only major part of the -webkit-box code that needs to be maintained.
<iank_> TabAtkins: What needs to be mapped, preserved for line-clamp, and removed.
<iank_> TabAtkins: We'd like to start up a spec to handle the line-clamping behaviour.
<smfr> q+
<iank_> eae: Would like a way to eventually alias this property over.
<iank_> eae: And would like to do this in a way that other folks can alias.
<iank_> florian: I don't remember the discussion of the spec.
<leaverou> q+
<iank_> florian: Expand on what we already have?
<iank_> TabAtkins: yes.
<astearns> ack smfr
<iank_> smfr: Would like to extend this feature a little.
<iank_> smfr: Collapses quoted text...
<iank_> smfr: Collapses in the middle of the content.
<Rossen> q?
<smfr> q-
<iank_> smfr: We would like to see this as start, end, middle.
<iank_> q+
<fantasai> q+
<iank_> florian: max-lines as currently specified is a fragmentation thing, makes the div into a fragmentainer, that breaks after a certain number of lines.
<iank_> florian: Drop the rest of the lines.
<fantasai> s/Collapses quoted text.../Mail client has a feature where it keeps some lines at the beginning, keeps osme lines at the end, and collapses in the middle of the content, with clicky in the middle to expand itall back/
<iank_> florian: Could make it such that you get additional lines.
<iank_> smfr: We did consider fragmentation to implement this feature, I don't really have opinions on how to do this.
<iank_> smfr: It does interact with fragmentation possibly
<astearns> ack leaverou
<iank_> leaverou: Why is this being discussed in terms of max-lines, and not max-height?
<iank_> florian: images inbetween for example, typically people want to clamp lines.
<fantasai> florian: and break at a fragmentation point ,not slice partway through a line
<iank_> florian: The generalized this in overflow-4 lets you deal with heights...
<gregwhitworth> q+
<iank_> florian: And let you decide if the additonal div gets dropped.
<iank_> leaverou: In most cases i've seen the clipping is visual.
<iank_> florian: But you don't want to split in the middle?
<iank_> leaverou: If an ellipsis isn't displayed, people want use this.
<iank_> florian: Its a separate issue...
<TabAtkins> s/want/won't/
<eae> ScribeNick: eae
<tantek> I am absolutely for postponining ellipsis discussion variants until CSS3-UI is a REC :)
<astearns> ack iank_
<tantek> s/postponining/postponing
<eae> iank_: One thing I'd like to stress is that we've seen a lot of demand for somehting simple like clamping the number of max-lines. Would like to keep it simple and not expand scope too much.
<eae> iank_: Clamping both start and end adds complexity as it requires layout out all of the text. Have to think about.
<eae> iank_: We're looking to remove support for percentage values for webkit-line-clamp. Behavior is bizare and there is essentially zero usage.
<astearns> ack fantasai
<eae> use counter for percentage values: https://www.chromestatus.com/metrics/feature/timeline/popularity/2139
<florian> q+
<gregwhitworth> ack gregwhitworth
<eae> fantasai: I agree that we should limit scope. A lot of thoughts are great and valid use cases. I don't want to go there right now. Want to understand actual proposal
<eae> fantasai: As I understand from proposal, treat as max lines and set height based on that. Is there more to it then that?
<eae> TabAtkins: Yon don't want the lines to still be there like with line-clamp, we want to omit the rest of the lines.
<eae> TabAtkins: Want to supress display of line boxes after the cut off.
<eae> TabAtkins: Right now they are simply considered to be of zero height for sizing but are still there
<eae> fantasai: So the ellipsis gets inserted?
<TabAtkins> https://drafts.csswg.org/css-overflow-4/#issue-6fadc074
<eae> florian: The machinery of clamping or cloning or fragmentation is invoked implicitly if set max-lines. There is an issue saying that one has to explicitly enabling the fragmentation support.
<gregwhitworth> q+
<eae> iank_: My only concern with that is that invokes a bunch of machinery that takes a lot of implementation work. A simple max-lines beahvior is potentially a lot simpler.
<eae> florian: Concerned that it would require a lot of reinvention.
<eae> Rossen: Want to reemphasis fantasais question. In my mind we keep going back and forth between two different things:
<eae> Rossen: 1) Fragmentation and stop layout at some boundary. should thing of this in css4
<eae> Rossen: 2) Existing pane, what tab is taking about. We have a a lot of requests for webkit-line-clamp support.
<eae> Rossen: My point here again. This is different. If we want to be compatible with -webkit-line-clamp then the behavior is different. Not fragmenting, consumes space differently.
<eae> Rossen: Not that different to implement as long as it doesn't involve fragmentation.
<eae> fantasai: Would like to see a concrete proposal.
<eae> TabAtkins: The goal of this was to start up something that at the bare minimum addresses the "I want n of something".
<eae> TabAtkins: All resonable things that I'd like to see addressed. Should resolve whether we want to do or not.
<eae> fantasai: line-clamp can be made to support a subset of uses cases but if you want support for more complex use cases then the problem gets a lot harder.
<eae> fantasai: Should try to tackle the problems one at a time. Have something basic that isn't quite 0webkit-ine-clamp, but without eventually supporting everything.
<Rossen> q?
<eae> TabAtkins: I would like to explore the space. Replace -webkit-line-clamp first and then, maybe, extend it later.
<astearns> ack florian
<fantasai> What I'm saying is I don't want to expand line-clamp, I would rather it stayed as some minimally simple property that could be used to build other things. not be expanded to do other things.
<eae> florian: responding to ian/rossen. When I was talking about invoking the machinery not walking about ..., to deal with fragmentation. I think we sort of have to, if not then we'd have to resolve what to do about text shadow, intruding floats etc. Would rather refer to the fragmentation spec.
<eae> florian: Would also be compatible with the rest of the spec in the future.
<eae> florian: css overflow invokes css break, max-lines already speced there.
<fantasai> https://www.w3.org/TR/css-break-3/#possible-breaks
<TabAtkins> ScribeNick: TabAtkins

@fantasai
Copy link
Collaborator

fantasai commented Mar 6, 2018

BTW, I think we should make sure we fix all the issues pointed out in https://medium.com/mofed/css-line-clamp-the-good-the-bad-and-the-straight-up-broken-865413f16e5 if possible.

@phistuck
Copy link
Contributor Author

phistuck commented Mar 7, 2018

Sounds good! I hope it makes it to browsers soon.

Thank you for all of your work on this!

@jonjohnjohnson
Copy link

So this seems to cover all cases when the exact line amount is known, but am I missing the solution for when "I have an element with a set height and would like however many lines of text at whatever size font to be elided"? Or is this type of functionality waiting for work on css-fragmentation?

@fantasai
Copy link
Collaborator

fantasai commented Mar 8, 2018

@jonjohnjohnson Separate issue: it's currently being explored in CSS Overflow Level 4, and while it'll use the same underlying mechanism (fragmentation), it'll be a different feature than max-lines.

@frivoal
Copy link
Collaborator

frivoal commented Mar 8, 2018

@RByers @bfgeek @tabatkins Do you think it is possible to run an investigation on Blink's side about whether it would be web compatible for -webkit-line-clamp to take effect without requiringdisplay: -webkit-box and -webkit-box-orient: vertical?

If not, we can work out something clever in terms of aliasing/shorhanding, but I really hope we won't need to standardize (and implement everywhere, and maintain) this sort of hackery.

@bradkemper
Copy link
Contributor

Forward-compatible with regions and overflow-fragments (see the CSS Overflow Level 4 draft).

The latest draft of fragment overflow, I believe. The one you linked to has an obsolescence notice and older syntax.

@bradkemper
Copy link
Contributor

block-overflow property, taking the same syntax as text-overflow.

Bikeshedding/kibitzing about the property name:

block-overflow sounds like a possible logical version of overflow-y, and would be confusing if we had overflow-block for that. And it doesn’t really bring an association of text-overflow to my mind. I think text-line-overflow would work better in both regards.

@bradkemper
Copy link
Contributor

@jonjohnjohnson Separate issue: it's currently being explored in CSS Overflow Level 4, and while it'll use the same underlying mechanism (fragmentation), it'll be a different feature than max-lines.

So, something like this?

height: 100px;
continue: fragments;
block-overflow: ellipsis;

@frivoal
Copy link
Collaborator

frivoal commented Mar 11, 2018

So, something like this?

height: 100px;
continue: fragments;
block-overflow: ellipsis;

Almost if you just want things to stop like it would be with max-lines, but after 100px instead of n lines, then you'd use continue: discard instead of continue:fragments, otherwise the remaining content gets injected in a sibling box (created for that purpose).

@MatsPalmgren
Copy link

A few comments on the block-overflow spec (in the order of the text):

clip
The content is not altered.

I'd suggest "The rendering is unaffected." instead. (Some people might read "content" as "DOM" which might give them the wrong idea that the other property values modify the DOM).

If there is no next fragmentation container and thus the remainder of the content after the break would be discarded, then the UA may visually replace the contents of the line, as it does for text-overflow.

I think this "may" should be changed to a "must", or alternatively, the entire sentence be removed. I don't see any upsides to allowing UAs to have incompatible behavior for this common case.

[...] and the block overflow ellipsis inserted and laid out exactly as if it were part of the in-flow contents of the line.

Does the inserted text affect ::first-letter/::first-line in any way? (even if it doesn't, it'd be good to spell that out explicitly for clarity)

The means of breaking any resulting cycles is up to the UA.

Again, vague spec text like this will likely lead to incompatible behavior in different UAs. I'd prefer the spec to say something concrete about how to solve it and make that behavior mandatory.

If the block overflow ellipsis is too long to fit in the line, the result is undefined. (The UA may, for example, treat the block overflow ellipsis as an unbreakable string, or it may lay out the string across more than one line, replacing content in earlier lines as well.)

Again, this is too lenient IMO. The spec should say exactly how to handle this case and make that mandatory. Authors deserve to have compatible rendering across compliant UAs.

@frivoal
Copy link
Collaborator

frivoal commented Mar 11, 2018

I'd suggest "The rendering is unaffected." instead.

done: 9e6c64e

I think this "may" should be changed to a "must", or alternatively, the entire sentence be removed.

The idea was that the behavior allowed by this "may" sentence was worse, and that we wanted browsers to do the full thing, but that it was quite a bit more involved, and that doing it as a visual replacement was a tolerable approximation (only in the case of no subsequent fragmentainer).

If implementors are OK with going with the full thing, I'd be happy about deleting that.

Does the inserted text affect ::first-letter/::first-line in any way?

If it is in the first lines (e.g. max-lines:1), then it should take the styles that affect the first line. Otherwise, we'll get weird and inconsistent typography in the first line. I believe that is already a consequence of "placed [...] as a direct child of the block container’s root inline box", but it doesn't hurt to say so if we agree (or to argue it out and then spec it if we don't).

For ::first-letter, I am less sure. I'm not what sure what the use case would be, and neither of what the implementation complexity would be. Any suggestion?

The means of breaking any resulting cycles is up to the UA.
Again, vague spec text[...]. I'd prefer the spec to say something concrete [...].

Fair enough. This may be a sufficiently involved question on its own to deserve it's own issue.

If the block overflow ellipsis is too long to fit in the line, the result is undefined.
this is too lenient IMO

I suspect there's a significant difference in implementation complexity between treating as an unbreakable string that overflows and climbing back up the previous lines. I suppose we could start by specifying it as unbreakable string that overflows, and later expose a pseudo element to let people switch to different behavior(s?) by applying some style. But this is a point where I'd be most interested to hear author / designer / evangelist feedback.

@bradkemper
Copy link
Contributor

@frivoal you’re right. I originally meant to type in continue: discard, but was apparently typing and pasting too fast. Though I suppose continue: fragments could be combined with block-overflow: “continued below…” or similar, and it could make sense that way.

@MatsPalmgren
Copy link

MatsPalmgren commented Mar 12, 2018

we wanted browsers to do the full thing, [...] and that doing it as a visual replacement was a tolerable approximation

There is a third option -- make the ellipsis cause a line break but render it the same as a text-overflow ellipsis (in all cases). This would allow us to reuse existing code for the rendering part. Something like this:

  1. flow the block as if block-overflow doesn't exist
  2. if it caused overflow, then shorten the available space to accommodate the size of an ellipsis and flow the last line again
  3. repeat 2 until there is no additional overflow or the line is empty
  4. during painting, render an ellipsis in the reserved space in the last line (same as a text-overflow ellipsis)

If it is in the first lines (e.g. max-lines:1), then it should take the styles that affect the first line.

OK, but I disagree that that follows from "placed [...] as a direct child of the block container’s root inline box". It really is necessary to point that out explicitly if that's the behavior you intended.
Please note that list-style-position:inside ::marker boxes does not affect ::first-letter/line in current implementations, fwiw.

Anyway, the problem with the ::first-* pseudos is that some UAs construct boxes for them in the box construction phase, which happens before the layout phase, so if the inserted ellipsis should be affected by these styles then it might affect boxes that were already constructed. For example, if the ellipses is so wide that it requires the entire length of the line then any existing ::first-letter/line boxes needs to be undone somehow. For ::first-letter there's also the case where leading punctuation on the line should be included together with the first character of the ellipsis. The implementation of these pseudos is already quite messy (and buggy) in Gecko and I suspect that might be the case for other UAs too. This is why I'm asking for a detailed spec about how the interaction (or not) between these boxes should work, because otherwise we'll almost certainly end up with incompatible implementations.

I would strongly prefer to keep the block-overflow property simple though, i.e. not interacting with boxes other than shortening the last line. We can introduce a more general "::fragment-before/::fragment-after" in the future, that would magically appear at fragmentation boundaries (possibly with additional conditions that an author can control). For example, it's quite common in printed newspapers to insert a "continued from page N" at the start of a fragment when it continues from an earlier page.

I suspect there's a significant difference in implementation complexity between treating as an unbreakable string that overflows and climbing back up the previous lines.

Indeed, and I suspect the estimated size of the ellipsis as a single line is likely too small if it needs line breaks after being inserted. An ellipsis that doesn't fully fit on the last line is an edge case anyway, so I think it's ok to restrict its layout heavily to simplify implementations.

@foolip
Copy link
Member

foolip commented Mar 14, 2018

Hi all,

@rakuco and I are looking into normative spec changes that don't have tests this quarter, in this tracking doc, and this week I ended up here via 41bdbcd24. (The point of the exercise is to understand what might still be missing to make testing the web platform easier.)

The string "webkit-line-clamp" doesn't appear anywhere in web-platform-tests, and "line-clamp" appears in these places:
css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-single-line-clamp-1.html
css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-single-line-clamp-2.html
css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-single-line-clamp-3.html

Per https://wpt.fyi/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox those are all passing in everywhere, but I don't know how deep they go.

@frivoal, do you have some sense for the required test coverage for (-webkit-)line-clamp? Would it be useful to just add a test that ensures that the webkit property is supported? 'webkitLineClamp' in document.body.style is the most trivial thing possible. A proper test would set style.webkitLineClamp and see what happens to style.lineClamp, but it looks like only Chrome and Safari support the prefixed property, and nobody the unprefixed one...

@foolip
Copy link
Member

foolip commented Mar 14, 2018

There are some tests in https://chromium.googlesource.com/chromium/src/+/dfeaf5302452eba172998d2a31383d1e5cfd7489/third_party/WebKit/LayoutTests/fast/overflow, but not sure if any of those are in line with the spec.

@bfgeek
Copy link

bfgeek commented Mar 15, 2018

I just have one meta-comment on the spec prose at the moment:

I'm concerned that the prose uses the regions terminology when:

  • Not all implementations have regions support.
  • Implementations that do have -webkit-line-clamp, (and will support max-lines) don't have regions support.

It seems that this is cart before the horse - is there any way we can word this differently?

@frivoal
Copy link
Collaborator

frivoal commented Mar 19, 2018

@foolip tests will be required for this, but it's still too early to write them, as there is still a significant risk of design churn.

The 3 tests you found in imported mozilla tests are false positive, using the phrasing line clamp for unrelated purposes in the description of the test.

Tests from chrome are unlikely to be aligned with the spec, since the spec is brand new and intentionally different from legacy code, as that design was seriously hacky.

@frivoal
Copy link
Collaborator

frivoal commented Mar 19, 2018

@bfgeek This is fairly unfortunate terminology. The spec actually uses terminology from css-break, not from css-regions. It does reuse the word "region" because that's what css-break uses, but that's not really a dependency on any region-related behavior.

The word region is only used as a classifier for forced breaks: they can be "page breaks" (break pages), "column breaks" (breaks multicol), or "region breaks" (break any other kind of css-induced fragmentainers).

If you support neither regions nor fragmentation on overflow nor max-lines, then you will have had no occasion yet to run into that kind of breaks, so if you implement max-lines first then this will be an addition. But the addition does not involve bringing over any of the css-region spec. All you need to do is:

  • be able to fragment
  • classify these boxes as "category3" (i.e. not pages nor multicol) for the purpose of forced breaks.

I think what we should probably do is actually file an issue on css-break to rephrase (and rename) the description of region breaks so that it no longer appears to depend on the regions spec, and instead is just an anchoring point for "category3" breaks, to be invoked from other specs.


Note: while this does not depend on region, it is designed to be compatible with regions if anyone ever wants to support them again, or with fragmentation-on-overflow if anyone wants to support that, or on any potential mechanism that involves flowing content from one place to another in the box tree. But again, we don't require this to be supported, just define things to behave in a sane way if it is supported.

@fantasai
Copy link
Collaborator

Wrt ::first-line and ::first-letter, I think the ellipsis should be considered part of the first line, but not the first letter pseudo. The ::first-letter pseudo behaves much more like an inline element, and the ellipsis is placed outside of any elements. Meanwhile ::first-line encompasses the entire line, it would be weird if something on it were somehow exempted.

@MatsPalmgren Your third option for placing the ellipsis seems pretty reasonable to me. When drafting up the spec we wanted to allow implementations to re-use as much of the existing text-overflow machinery as possible, hence the MAY -- as long as you're otherwise discarding content after the break, placing it effectively “underneath” the ellipsis for event handling is fine. It's only when the content needs to be pushed to another container that we need to make the ellipsis replace it layout-wise rather than just paint-wise.

In typical cases, the author will not be able to tell the difference between the two behaviors. But layout replacement can affect the height of the line, which makes it a more complicated mechanism to implement correctly (and as noted, can introduce cycles, which then need to be broken). I would rather not require that extra complexity for this case, where it is not needed and the behavior change in real layouts is slight. (At some point, as we expand CSS's ability to break flows between boxes, we may want to require layout replacement here, to make discarded flows consistent with continued ones; but since such a change seems unlikely to break pages, it seems safe to allow the easier thing now.)

@frivoal
Copy link
Collaborator

frivoal commented Jul 11, 2018

Closing. The discussion here has touched on numerous points, many of which have have been addressed already, and the rest has been reported in separate github issues.

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