Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
[css-overflow] Consider support for multiple-line ellipsis #390
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.
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.
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:
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
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.
Excellent, thanks Tab!
So you'll work on a proposed change to
Or since the existing API isn't exactly what people often want, would it be better to just define
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
So, basically, I'm agreeing with Florian about the direction to go in, but to solve the cases that
Basically, I think that's what
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
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
On the other hand, inserting the ellipsis is probably trickier.
I suppose this is fine though. We can just imply that the current limited ellipsis is the result of something like a
May I mention the use case for cropping contents in the middle again?
...shit, I totally misunderstood this feature. It is almost exactly what fantasai suggests; it just calculates the natural height (
(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
@fantasai, sorry for misleading you yesterday in our discussion over this. :(
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?
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.
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 :-)
Okay, let me be more precise about the options as I see them, then:
(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.
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).
On the other hand, if there is text between
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.
I think you've read option 2 completely backwards? I'll make them clearer with some examples.
Everyone uses the same markup:
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.)
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.
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:
How this differs to the other counters (specifically, WebkitBoxLineClamp) will give us an idea of what folks are doing.
The Working Group just discussed
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.
<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.
<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.
<iank_> smfr: We would like to see this as start, end, middle.
<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...
<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...
<eae> ScribeNick: eae
<tantek> I am absolutely for postponining ellipsis discussion variants until CSS3-UI is a REC :)
<astearns> ack iank_
<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
<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?
<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.
<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.
<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.
<TabAtkins> ScribeNick: TabAtkins
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.
Integration with present and future specs:
Let us know if there's anything important that we missed.
Agenda+ to request CSSWG review.
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?
@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 requiring
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.
Bikeshedding/kibitzing about the property name:
So, something like this?
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
A few comments on the block-overflow spec (in the order of the text):
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).
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.
Does the inserted text affect
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.
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.
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.
If it is in the first lines (e.g.
Fair enough. This may be a sufficiently involved question on its own to deserve it's own issue.
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.
There is a third option -- make the ellipsis cause a line break but render it the same as a
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.
Anyway, the problem with the
I would strongly prefer to keep the
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.
@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 41bdbcd. (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:
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?
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.
I just have one meta-comment on the spec prose at the moment:
I'm concerned that the prose uses the regions terminology when:
It seems that this is cart before the horse - is there any way we can word this differently?
@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.
@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:
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.
@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
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.)