Skip to content

[css-overflow-4] How do -webkit-line-clamp and line-clamp interact when both are specified? #10439

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

Open
andreubotella opened this issue Jun 13, 2024 · 12 comments

Comments

@andreubotella
Copy link
Member

andreubotella commented Jun 13, 2024

In the current spec text for css-overflow-4, which only describes continue: discard (not yet continue: collapse as described in #7708), both line-clamp and the legacy -webkit-line-clamp property are shorthands for other properties, including max-lines. This means that if both are specified on some element, whichever wins in the cascade will be applied.

However, this leads to unexpected results. Consider the following:

display: block;
line-clamp: 3;
-webkit-line-clamp: 4;

Since line-clamp and -webkit-line-clamp are shorthands for the same set of properties, -webkit-line-clamp will win. This means that max-lines will have a specified value of 4, but also that continue will have a specified value of -webkit-discard – which will cause the continue property (and by extension, max-lines) to not take effect, because display is not set to -webkit-box.

My current implementation of continue: collapse in Blink (see #7708) implements both line-clamp and -webkit-line-clamp as longhands which don't alias. If both are present (and not specified to none) on some box, line-clamp wins. AFAIU this behavior wouldn't be possible to specify while making (-webkit-)line-clamp shorthands, unless we make a separate -webkit-max-lines property.

If we want to keep the shorthands, while making the code above actually work, my understanding is that -webkit-line-clamp would have to be specified such that it sets the longhands if display: -webkit-box and -webkit-box-orient: vertical are set, and to not be a shorthand for anything otherwise.

cc @frivoal

@frivoal
Copy link
Collaborator

frivoal commented Aug 30, 2024

Since line-clamp and -webkit-line-clamp are shorthands for the same set of properties, -webkit-line-clamp will win. This means that max-lines will have a specified value of 4, but also that continue will have a specified value of -webkit-discard – which will cause the continue property (and by extension, max-lines) to not take effect, because display is not set to -webkit-box.

That doesn't bother me: there really isn't a point in going around setting -webkit-line-clamp on elements which do not have the -webkit-box and -webkit-box-orient preconditions. And since #10324 (comment), the unprefixed line-clamp also blockifies -webkit-box when -webkit-box-orient is there too, so there's no need to do it manually. In other words, for a new site that's not trying to activate legacy browsers, there's no reason to have -webkit-line-clamp at all, and for a site that wants to target old and new browsers, there should be -webkit-line-clamp as well as -webkit-box and -webkit-box-orient.

My current implementation of continue: collapse in Blink (see #7708) implements both line-clamp and -webkit-line-clamp as longhands which don't alias. If both are present (and not specified to none) on some box, line-clamp wins.

I think it's more typical for CSS to have the cascade order determine the winner.

If we want to keep the shorthands, while making the code above actually work, my understanding is that -webkit-line-clamp would have to be specified such that it sets the longhands if display: -webkit-box and -webkit-box-orient: vertical are set, and to not be a shorthand for anything otherwise.

You could do that, but conditional shorthands seem unusual. Might be tricky to implement.

I think the following alternative would work, without the full set of longhands:

You could have some simplified version of the longhands, not exposed to web authors. One would have to be continue: auto | discard | -webkit-discard, but the other could be a simplified combination of max-lines and block-ellipsis, which basically means having the same value space as line-clamp.

cc: @fantasai

@Loirooriol
Copy link
Contributor

It it sets the longhands if display: -webkit-box and -webkit-box-orient: vertical are set, and to not be a shorthand for anything otherwise.

Note that we need to expand shorthands into longhands at parse time, but we may not know the value of display until computed-value time (e.g. when using variables).

Also I don't think a property should sometimes be a longhand and sometimes a shorthand, that would be problematic e.g. because [...getComputedStyle()] only includes longhands.

Like Florian says I think it's fine if -webkit-line-clamp wins over a preceding line-clamp.

@andreubotella
Copy link
Member Author

andreubotella commented Sep 19, 2024

There is a 4% of page loads where -webkit-line-clamp is specified and does nothing because the other properties aren't set. This is likely because it was set once in some selectors and then forgotten about. I worry that if some new selectors are added which use line-clamp, and there are cases where both selectors apply to the same element, the fact that line-clamp might not take effect either would be completely unexpected.

But maybe making sure that the devtools show indications about this would be enough to make this not an issue.

@astearns astearns moved this to FTF agenda items in CSSWG January 2025 meeting Jan 22, 2025
@astearns astearns moved this from FTF agenda items to Regular agenda items in CSSWG January 2025 meeting Jan 22, 2025
@astearns astearns moved this from Regular agenda items to Thursday afternoon in CSSWG January 2025 meeting Jan 28, 2025
@astearns astearns moved this to Regular agenda in CSSWG April 2025 meeting agenda Mar 27, 2025
@astearns astearns moved this from Regular agenda to Oldest unslotted in CSSWG April 2025 meeting agenda Mar 28, 2025
@astearns astearns moved this from Oldest unslotted to Wednesday Morning in CSSWG April 2025 meeting agenda Mar 28, 2025
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-overflow-4] How do `-webkit-line-clamp` and `line-clamp` interact when both are specified?, and agreed to the following:

  • RESOLVED: Add a "-webkit-legacy" value to line-clamp, and define -webkit-line-clamp to be a shorthand of line-clamp that adds the keyword
The full IRC log of that discussion andreubotella: usually when you have -webkit prefixes they're alias or legadcy shorthand
andreubotella: so there's always a way to replace the -webkit prefix with the modern one
andreubotella: even if the parsing is different
andreubotella: this is not the case for -webkit-line-clamp, due to web compat constraints
andreubotella: -webkit-line-clamp only works with -webkit-box and vertical on the same element
andreubotella: over 4% of page laods are using it wrong and we'd change their behavior if we changed this
andreubotella: so what happens if you set both on the same element?
andreubotella: currently they're both defined as shorthands over some longhands, including 'continue'
andreubotella: the keyword of 'continue' that triggers the legacy behavior is "continue: -webkit-discard"
andreubotella: and a similar "-webkit-collapse"
andreubotella: so if you ahve "line-clamp: 3; -webkit-line-clamp: 4", then "continue" will have -webkit-discard
q+
andreubotella: so even tho the unprefixed version is set, it'll still require -webkit-box
andreubotella: do we want this behavior?
andreubotella: there's also the fact that in chromium this is only possible to implement if we actually have the longhands
andreubotella: but we've said the longhands must not be web-exposed currently. this would require changing chrome's property reoslution. not insurmountable, but I'd like to not do it, it's new territory
ack florian
q+
florian: indeed, we say in the spec that this is defined in terms of shorthand/longhands, but dont' expose the longhands yet
florian: the intent when we did it wasn't that the longhands were wrong, but that we thought the shorthand was good and we wanted room to tweak the longhands
florian: but the interaction of th eprefixed and unprefixed do happen in the longhands
florian: so we either need to expose some interaction, or double down
florian: assuming we can get longhand to work, the situation that Andreu is concerned about is that you have both versions set, and the prefixed version is last in cascade, and you don't have the legacy special properties that make the legacy version work
florian: you start with line-clamp:3, then you add the -webkit-line-clamp one, and you lose clamping entirely
florian: i think that's ok? if you don't want it, don't have the legacy thing last on the cascade
florian: there are a bunch of websites that have the legacy and it works, and a bunch that have the legacy and it doesn't work and they need it to not work
florian: but at the point where you also have the new syntax, that's where you need to be careful. yo udon't add the new syntax with the intent that it doesn't work
florian: it's a little weird, but i think it's fine
florian: so do we want to double-down on the longhand syntax, do we really want non-exposed longhands, or do we want to change how we define this?
fantasai: it's comitting to the longhands ahving independent effects
fantasai: if you just specify max-lines and not the others, will that have an effect?
fantasai: i think we want to go there ultimately, whatever we decide ehre has to be compatible
fantasai: so we'd have to expose each longhadn
florian: if we think we want to go there but we're not ready, maybe go for private longhand version
ack emilio
emilio: it feels weird - it's unfortunate that we can't just make -webkit-line-clamp an alias, that sucks
s/it's comitting/it's not just committing to the syntax, but also /
emilio: but it feels like this should be implementable without having weird internal longhands, if we add the ability to specify the legacy behavior to 'line-clamp'
s/will that have an effect?/then that needs to have its intended effect/
emilio: and that seems workable
emilio: that way -webkit-line-clamp would just be a shorthand of line-clamp in the interim
florian: i think that would work
emilio: that seems fairly easy to implement
emilio: prevents having two longhands that do different things that interact weirdly
emilio: it might be a keyword or something at the end of 'line-clamp', it causes the weird legacy stuff
+1 emilio
emilio: i think that's simpler and doesn't preclude us from breaking down line-calmp into shorthands in the future
florian: agree
+1 as well
andreubotella: i want to be careful that the syntax - in the utopian case where we can remove the legacy behavior, we want this legacy syntax to still work
andreubotella: that would still require implementing the legacy syntax in engines
emilio: that's the same as can we ever remove continue:-webkit-discard
florian: either people are not using it anymore and we can remove it regardless of syntax, or they are using it and we can't remove it regardless of syntax
q+ to reply to fantasai
fantasai: is this flag actualy something in the syntax that an author can specify, or is it just something we store internally? it woudln't strictly round trip
ack emilio
emilio, you wanted to reply to fantasai
florian: think we can keep it simple, just slap a legacy keyword on it
emilio: yeah unless this is partiuclarly annoying, i think we should just add a keyword to the syntax so it round trips
emilio: too many things that iterate over properties and copy them, would be weird if that didn't work
emilio: so if you copied the computed display value...
q+
emilio: display and line-clamp, it wouldn't work
emilio: you'd put a standard line-clamp on a -webkit-box
ack florian
florian: I suggest we just make the keyword sipmle and not magic
florian: there's no good reason for people to directly use it. it'll trigger from teh prefixed proeprty; people could write it themselves but why woudl they
florian: the only thing you get from this keyword is the requirement to also set these other stupid properties
TabAtkins: agree, we can just give it a dumb name
andreubotella: and make sure it's listed as deprecated in MDN to help push authors away
astearns: so if an author specifies line-clamp, then after specifies -webkit-line-clamp, it still won't clamp becuase the other properties aren't set
astearns: but the value of line-clamp is set to the legacy thing. we're just specifying the interaction and making it as normal as possible wrt the cascade
astearns: proposed resolution: Add a "legacy" value to line-clamp, and define -webkit-line-clamp to be a shorthand of line-clamp that adds the keyword
fantasai: can it be a -webkit prefix? make it ugly?
TabAtkins: yeah let's
-webkit-legacy
s/ugly/obviously linked to the -webkit- weirdness/
astearns: objections?
RESOLVED: Add a "-webkit-legacy" value to line-clamp, and define -webkit-line-clamp to be a shorthand of line-clamp that adds the keyword
astearns: there's no problem with line-calmp resetting -webkit-line-clamp to its initial value?
florian: [shrugs]
fantasai: since line-calmp is a shorthand of continue, and in the longhandy version of this the weirdness is tied to a -webkit-* keyword...
florian: we're speccing two versions in parallel right now, a collapse and a discard
florian: we're about to switch from discard to collapse
florian: jsut havent' decided it yet
fantasai: well my point was going to be to use that keyword name, since that's usually how keywords work, but sounds complicated. never mind

@andreubotella
Copy link
Member Author

andreubotella commented Apr 22, 2025

We didn't discuss how the -webkit-legacy keyword would map to the three longhands. The easiest way is probably to replace the existing -webkit-collapse keyword for the continue property with -webkit-legacy, with no change in behavior.

Do we want to make this an async resolution?

andreubotella added a commit that referenced this issue Apr 22, 2025
@andreubotella
Copy link
Member Author

andreubotella commented Apr 22, 2025

I just realized that if an element has display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3, which does clamp, and you copy the styles to a different element using JS (assuming line-clamp is exposed and its longhands aren't), you'd get a result that doesn't clamp. This is because clamping relies on the specified value of display being -webkit(-inline)-box, but (as of #10435) its computed value is changed to flow-root.

I wonder if, given this, we might want to make -webkit-legacy resolve to either none or a non-legacy value at computed value time.

@andreubotella
Copy link
Member Author

When implementing this resolution in Chromium, @andruud pointed out that this runs into the compat risk when shorthandifying well-established properties (#8398), because -webkit-line-clamp has been implemented as a longhand in all browsers for a long time.

@fantasai
Copy link
Collaborator

fantasai commented May 13, 2025

@andreubotella @andruud Is that a significant risk for this property in particular, or just generally a concern to think about?

@andreubotella
Copy link
Member Author

andreubotella commented May 13, 2025

@andreubotella @andruud Is that a significant risk for this property in particular, or just generally a concern to think about?

I don't think the risk is significantly higher than for other properties that have been implemented as longhands for a long time, and in fact it might be lower because of the fact that it's vendor-prefixed. So it's more about the general concern.

Something that should also be part of the discussion, though, is that unprefixed line-clamp should be implemented as a shorthand (since the plan is to eventually expose some longhands for it, whether it's the ones currently described in the spec or not), but currently there are no longhands that line-clamp would be short for. This doesn't seem to be an issue implementation-wise in Chromium, but I don't know whether it is for other browsers, or whether it would be for developers.

@frivoal
Copy link
Collaborator

frivoal commented May 14, 2025

Unless there is specific evidence of breakage, I think this remains the right thing to do. Systematically avoiding shorthandification seems to extreme to me, and blocks a rare and significant means of extending and evolving the language. I guess that it's not safe in all cases, but I think it's worth doing here (unless we know of something specific that breaks)

andreubotella added a commit that referenced this issue May 23, 2025
@andreubotella
Copy link
Member Author

So we have two questions to solve here:

  • Should -webkit-line-clamp, which was previously behaving like a longhand in getComputedStyle(), switch to behaving like a shorthand? It has been shipping for long (in Webkit since 2009) as a longhand, but there's no evidence that this is relied on. From the conversation above, the answer seems to be yes.
  • Should line-clamp behave like a shorthand, given that it's currently specified as a shorthand even though its longhands shouldn't be exposed, since the plan is to expose them in the future. The answer would probably be yes, to avoid a future web compat situation, but it raises the issue that the state of getComputedStyle().lineClamp would not be able to be computed based on the CSSStyleDeclaration's declarations, since those wouldn't include the longhands. Is this okay?

I'd like to hear some answers to both of these questions, to hopefully make this an async resolution.

tabatkins added a commit that referenced this issue Jun 3, 2025
* [css-overflow-4] Draft spec for `continue: collapse` (#7708)

* Clarification about float clearance in the automatic block size

* Update to only allow clamping after a line

* Apply suggestions from code review

Co-authored-by: Florian Rivoal 

* Update css-overflow-4/Overview.bs

Co-authored-by: Florian Rivoal 

* Update css-overflow-4/Overview.bs

* Update css-overflow-4/Overview.bs

* Update css-overflow-4/Overview.bs

* Update css-overflow-4/Overview.bs

* Update css-overflow-4/Overview.bs

* Update for #10439

* Update for #11962

* Update for #10868

---------

Co-authored-by: Florian Rivoal 
Co-authored-by: Tab Atkins Jr. 
@frivoal
Copy link
Collaborator

frivoal commented Jun 6, 2025

Should -webkit-line-clamp, which was previously behaving like a longhand in getComputedStyle(), switch to behaving like a shorthand?

I'd say yes

Should line-clamp behave like a shorthand, given that it's currently specified as a shorthand even though its longhands shouldn't be exposed, since the plan is to expose them in the future.

I'd say yes. On top of that, we had said several years ago that we were choosing not to expose the longhangs to keep ourselves some flexibility in case we wanted to change their name or syntax. In the meanwhile, there's been significant rework of the proposal (with the introduction of collapse and all), but the syntax has staid stable the whole time, with no counter-proposal. I think we might want to lift that restriction on the longhands, and just have them be regular longhands.

Also, one more question:
Since line-clamp now also has a value of -webkit-legacy, we have a choice: -webkit-line-clamp can be a shorthand of the same longhands as line-clamp (what we've said so far), or it could be a shorthand of line-clamp itself. Initially, it had to be a shorthand of the longhands, since there was not -webkit-legacy keyword on line-clamp, but now there is. Which one do we want to go with?

I don't care strongly either way, but it's a choice we now have, so I thought I'd ask.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Wednesday Morning
Status: Thursday afternoon
Development

No branches or pull requests

5 participants