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-3] max-lines not forwards compatible with fragmented overflow #2860

Closed
fantasai opened this issue Jul 2, 2018 · 3 comments

Comments

Projects
None yet
4 participants
@fantasai
Copy link
Collaborator

commented Jul 2, 2018

@dbaron pointed out some forwards-compatibility concerns with the proposed behavior for max-lines, which would discard extra content by default: in the future, an author would want to combine max-lines and overflow fragments (e.g. continue: fragments), and in an older client the content would get discarded.

See https://lists.w3.org/Archives/Public/www-style/2018May/0041.html

@fantasai

This comment has been minimized.

Copy link
Collaborator Author

commented Jul 2, 2018

One way to solve this would be backporting continue: auto | discard so that max-lines will not discard by default, only when continue: discard is specified. Thus an implementation of max-lines + continue: fragments will not discard the content (as the author did not intend).

However, in this case, it would end up overflowing the box, which is maybe not a great improvement.

If we do this, we'd extend line-clamp to also set continue: discard so that it preserves its current behavior.

@frivoal

This comment has been minimized.

Copy link
Collaborator

commented Jul 2, 2018

One way to solve this would be backporting continue: auto | discard so that max-lines will not discard by default, only when continue: discard is specified. Thus an implementation of max-lines + continue: fragments will not discard the content (as the author did not intend).

I support this.

If we do this, we'd extend line-clamp to also set continue: discard so that it preserves its current behavior.

This too. To make it easy to set everything in one go, we should also extend the syntax of line-clamp to none | <integer> <'block-overflow'>?

However, in this case, it would end up overflowing the box, which is maybe not a great improvement.

No, we should just say that max-lines only applies to fragmentainers. Making it apply to non fragmentainers (by limiting the height or something) looks very much like a footgun to me. Plus it means we'd have to implement something totally different for that case.

@frivoal frivoal self-assigned this Jul 2, 2018

@css-meeting-bot

This comment has been minimized.

Copy link
Member

commented Jul 5, 2018

The Working Group just discussed max-lines is not forward-compatible, and agreed to the following:

  • RESOLVED: discarded content is treated as display:none, not laid out
  • RESOLVED: block-overflow value can be set in the line-clamp shorthand
  • RESOLVED: add the longhands to the spec in whatever form you find convenient to *describe* the functionality, and add a note requesting implementation of just the shorthand.
The full IRC log of that discussion <TabAtkins> Topic: max-lines is not forward-compatible
<astearns> github: https://github.com//issues/2860
<TabAtkins> florian: Issue raised by dbaron
<TabAtkins> florian: The way we've specified, max-lines automatically makes the thing into a fragmentainer that discards the leftover content.
<TabAtkins> florian: The problem is that in experimental L4, we have a property that lets you turn arbitrary elements into fragmentatiners. One possibility is discarding, another is the content goes into a generated pseudo-element sibling.
<TabAtkins> florian: So if someone is trying to use l4 to say "3 lines in first, put rest in cloned element", it'll work in browsers that work in l4, and discard the content in l3 browsers.
<TabAtkins> florian: The way elika and I propose to solve this is to backport the proeprty only with "auto" and "discard", so max-lines is changed to only apply to fragmentainers.
<fantasai> s/so/and/
<TabAtkins> florian: So if you turn on continue:discard, max-lines will work, otherwise it won't.
<TabAtkins> heycam: This has some implication on the names of values in block-overflow, right? Maybe "clip" should be "none"?
<TabAtkins> heycam: block-overflow prop has ellipsis/clip
<TabAtkins> heycam: But clip sounds like something you want to apply to the fragmentainer concept.
<TabAtkins> florian: Yeah, these are different, but if you think the anmes are confusing, i can't disagree that bikeshedding might be useful
<TabAtkins> florian: Additionally, shorthanding...
<TabAtkins> florian: We have max-lines (triggers fragmentation breaks after X lines), block-overflow (at that fragmentation break, insert ellipsis or not), and a shorthand called line-clamp, which sets both.
<TabAtkins> florian: To amke it easy to use, line-clamp would also set continue:discard, making it a fragmentainer.
<TabAtkins> florian: And to set it all in one go, you could set the block-overflow part in line-clamp
<TabAtkins> florian: So `line-clamp: 3 ellipsis`, etc
<TabAtkins> Rossen: Is this model... if i have `max-lines: 2` and `widows: 3`, what happens?
<TabAtkins> fantasai: It trigges a forced break, any avoid-break controls, like break-inside/widows/etc are overridden.
<TabAtkins> Rossen: So it disables all of the smarts
<TabAtkins> fantasai: To an extent.
<TabAtkins> fantasai: If you have max-lines:5, and a float next to it, the triggering a forced break after the five lines, widows/etc doesn't affect where we break.
<TabAtkins> fantasai: But once we do that, there's no forced break in the float, it's just told where the container's size is. If there's content there, widows/etc applies.
<TabAtkins> Rossen: Second question, what happens to discarded content?
<TabAtkins> Rossen: Assume we have abspos element used for a sidebar. Its left position depends on static position, with top:0, but it comes somewhere at the end of content.
<TabAtkins> Rossen: So if max-lines discards the linebox that the abspos's anchor is in, what's the static pos?
<TabAtkins> fantasai: Open issue. I'm happy to perform layout in the discarded parts, tho.
<TabAtkins> fantasai: Main reason to not do layout are for perf. But most use-cases are small amounts of content, or that you're gonna reveal anyway.
<TabAtkins> fantasai: So my inclination is to say we do layout, and if there's problems with that in the future we can do something about that.
<TabAtkins> Rossen: If we continue to layout it'll be fine, even if subsequent fragments aren't the same size...
<TabAtkins> Rossen: I think in most cases UAs can optimize away without having to do full layout
<TabAtkins> q+
<TabAtkins> Rossen: Even for purposes of object model, if i ask for bounding rect of something after the limit, do I get anything?
<TabAtkins> florian: The discard behavior that we're talking about alreayd exists in regions, in the last region. There's a switch there.
<TabAtkins> florian: For the purpose of the discussion, this is same thing.
<TabAtkins> fantasai: We're replacing that property.
<TabAtkins> florian: Right, we renamed it here.
<astearns> ack TabAtkins
<fantasai> TabAtkins: I don't think we can do layout
<fantasai> TabAtkins: Because the absence of those lines can affect other layout on the page
<fantasai> TabAtkins: Such as how other floats position
<fantasai> TabAtkins: A later or longer float...
<fantasai> Rossen: Fragmentainers are BFCs.
<fantasai> TabAtkins: Oh, ok.
<fantasai> TabAtkins: I suspect there are some things that would amke it problematic
<fantasai> TabAtkins: because we're changing the size of stuff
<tantek> s/amke/make
<fantasai> Rossen: Things that are problematic
<fantasai> Rossen: Obvious we're trying to hide this from render an dhit test
<fantasai> Rossen: Computing static position for elements
<fantasai> Rossen: Fulfilling OM calls in subsquent content
<florian> q+
<fantasai> Rossen: Also whatever needs to happen in such cases is whatever is already supposed to happen in Regions
<heycam> q+
<fantasai> myles: You could potentially happen position: relative thing that's farther down and moves up
<fantasai> Rossen: Similar issue with static postion
<florian> q-
<fantasai> florian: Doing the layout would be problematic because stuff would interact with stuff below
<fantasai> florian: I don't think this is the case.
<fantasai> florian: E.g. in multicol, the content in subsequent columns doesn't impact content below the first columns
<fantasai> florian: We just place it differently. In this case we don't place it all
<fantasai> florian: You need to do layout within the columns to do the layout of the content in the columns. You don't need to position the columns then
<fantasai> TabAtkins: 4 lines of content, down in 20th line, static postioned abspos
<fantasai> TabAtkins: Container is shrunken down, you have to do full layout?
<fantasai> florian: Yes.
<fantasai> florian: But that layout isn't going to impact the rest of the page
<fantasai> florian: You might see the top half of content if it's above the fold, but it won't disturbe subsequent content
<fantasai> iank_: It seems like doing a layout would be too much work for something like static pos
<fantasai> Rossen: For the same purposes, we have to figure out what to do for a11y
<fantasai> TabAtkins: Can still bey in AT
<fantasai> Rossen: There's visiblty: hidden; and display: none
<fantasai> florian: Currently specified as display: none. Can change if needed
<fantasai> Rossen: If already done that way, then we don't care
<fantasai> Rossen: In that case would say don't do layout
<astearns> ack heycam
<fantasai> heycam: Related things, like selections that go into the laid out but not actually rendered framse or boxes, might be a bit tricky
<fantasai> Rossen: You can't for same reasons for AT
<fantasai> Rossen: If you consider the content that goes inside of the max lines
<fantasai> Rossen draws on the board
<fantasai> <f max-lines=5>
<fantasai> Rossen: In here you have whole bunch of text with other things
<fantasai> Rossen: What Florian's saying is that you do layout, consume some of this text
<fantasai> Rossen: And then pretend tha there was a <span display=none> on the rest of this, and that's it
<fantasai> Rossen: You cannot hit test here, you cannot expose to A11y
<fantasai> Rossen: Just as if span with display: none
<fantasai> Rossen: If this is the model, makes sense. Less computationally intensive
<fantasai> Rossen: Just need to verify that it's acceptable to a11y
<fantasai> Rossen: Once you hit your max-lines, you're done
<fantasai> heycam: I think I would prefer that.
<fantasai> florian: I think that's what's in the spec, but didn't work out the implications
<fantasai> iank_: Also need to figure out what to say for CSSOM APIs
<fantasai> Rossen: This is mostly sorted out by display: none
<fantasai> myles: Ian's comment about laying out all that crap so figure out static pos not worth it makes sense
<fantasai> heycam: This would be the first time when we would have some fragments of a box be display: none and others not.
<fantasai> astearns: Hearing consensus that we're going to take what's proposed in the issue
<fantasai> astearns: Clarify that the discarded content is display: none, and hwat are the implications of that.
<TabAtkins> ScribeNick: TabAtkins
<TabAtkins> fantasai: So first is that discard content is display:none, not laid out
<TabAtkins> RESOLVED: discarded content is treated as display:none, not laid out
<TabAtkins> fantasai: Second is that block-overflow value can be specified in the line-clamp shorthand.
<TabAtkins> fantasai: It currently takes a number and affects max-lines and block-overflow; right now block-overflow is reset-only.
<TabAtkins> RESOLVED: block-overflow value can be set in the line-clamp shorthand
<TabAtkins> fantasai: Third is to add continue:[auto|discard] to Overflow3, make max-lines depend on the element being a fragmentainer (such as from continue:discard), and making continue:discard be set by line-clamp.
<TabAtkins> heycam: What are the implications of being a fragmentainer? What if continue:discard without max-lines?
<TabAtkins> fantasai: It establishes an FC, and causes the element's overflow to be discarded. This is a new feature
<TabAtkins> astearns: Take the element's height, and whatever lines fit into there, it's like max-lines:X for that number.
<TabAtkins> florian: So the effect is very similar to multicol with hidden overflow columns.
<TabAtkins> koji: What happens to abspos?
<TabAtkins> astearns: Gone, same as previous topic.
<fantasai> TabAtkins: It's the same as a one-column multicol, except all of the oveflow columns are display: none
<TabAtkins> astearns: So an auto-height would have all the content unless there was a forced break
<fantasai> astearns: So if auto height, would not discard any contents unless there's a forced break
<TabAtkins> Rossen: Selection, works on dom ranges, in the absence of actual element computed to display:none, selection would go into that range.
<TabAtkins> florian: Selection is a thing, yes, but depends on what you do.
<TabAtkins> Rossen: Like caret selection, if you get to the segment that's discarded it'll continue into there.
<TabAtkins> Rossen: But a display:none element just gets skipped over.
<TabAtkins> florian: This is like a multicol with visibility:hidden in the later columns, your caret will go into there.
<TabAtkins> heycam: So this means selection code will ahve to ask what line it's in.
<TabAtkins> myles: So previously selection depended on DOM and computed style. Now it also depends on layout.
<TabAtkins> astearns: Anyone want to revisit the display:none issue, or leave it as it is and think thru the selection issues?
<TabAtkins> Rossen: In any script-based editor, they're laying out a magazine and want an article to be five lines, they continue navigating thru content, suddenly their cursor goes into the void.
<TabAtkins> florian: You already have to depend on layout. If you press down, you need layout to know what character you'll be going down into on the next line.
<TabAtkins> myles: News website is common use for max-lines. In this facility, you'd get the first para or so of the article.
<TabAtkins> myles: If the selection included the missing parts and they copied, it either wouldn't contain the display:none part and depends on layout, or it woudl contain parts that they don't see.
<TabAtkins> heycam: Don't we already have this with text-overflow?
<TabAtkins> florian: Yeah.
<TabAtkins> florian: If selection is a domrange, you can make it cover the discarded part. But the copy operation itself can be smart and skip over.
<TabAtkins> heycam: So this isn't just about recasting existing functionality. Now I have to worrya bout implementing continue:discard without max-lines, and worry about other work...
<TabAtkins> florian: If you ahve max-lines:3e6, it also basically is a fragmentainer, but unlikely to actually trigger the forced break.
<TabAtkins> heycam: I have a div with continue:discard and a fixed height, I have to worry about dropping more stuff.
<TabAtkins> koji: I understand you saying it's similar, but defining limits by number of lines but also by height is different code.
<TabAtkins> florian: But max-lines *already* says you['re a fragmentainer that discards things, so continue:discard isn't new code.
<TabAtkins> myles: BAck to selection. If user does select with mouse, they'll drag over the discarded part, if we want to keep that out of the selection we need multirange
<TabAtkins> florian: No, it's the same as today if you drag over a display:none. One range, but copy can skip the discarded part.
<TabAtkins> astearns: It's not possible to set continue directly from the shorthand. Is there any concern that 'continue' by itself might have applications that are separate from max-lines, so that it's weird that line-clamp will override?
<TabAtkins> fantasai: In that case you'd probably want to not use line-clamp, but use max-lines directly
<TabAtkins> Rossen: If the height of your element with continue:discard depends on its siblings, like it's a grid item, every time you adjust the height you have to relayout everything inside.
<TabAtkins> Rossen: And by doing so you might bring stuff in which is now affecting your width.
<TabAtkins> fantasai: The way fragmentation is defined is that min-content and max-content is constant across all fragmentainers.
<TabAtkins> fantasai: That should remain true for discarded content.
<TabAtkins> fantasai: And we should make that clear.
<fantasai> Rossen: I'm concerned about relayout that has to pull content up because of resizing due to siblings e.g. in grid rows
<fantasai> TabAtkins: it's the same as if you put a multicol in the grid
<fantasai> Rossen: I have two grid items, one iwth contineu: discard. The one that is not sets the height
<fantasai> Rossen: You have to go and re-layout the second one which is continue: discard, because you don't know what's next
<fantasai> Rossen: If that was a normal grid item, you'd have laid everything out, but now ou have to juggle thing.
<fantasai> TabAtkins: This is exactly the same a a multicol
<fantasai> TabAtkins: It's not a new thing.
<TabAtkins> astearns: So are we at the point we can decide that continue is a property?
<TabAtkins> Rossen: Any other option?
<TabAtkins> fantasai: We can define line-clamp as if the longhands existed, but not expose them yet, so L4 would introduce continue.
<TabAtkins> TabAtkins: So if we did that, if you just want ellipsis, you'd ahve to say `line-clamp: infinity ellipsis`?
<TabAtkins> florian: Yeah
<TabAtkins> fantasai: And note that as soon as we started doing this, authors were asking for "as many lines as fit into <length>"; that's what 'continue' does
<TabAtkins> fantasai: My prefernce is to put these three into the draft now, but with a note asking implementors to just implement 'line-clamp' shorthand right now; but becuase we do need to figure out these interactions we shoudl go ahead and keep them in the draft to help work them out.
<TabAtkins> fantasai: So any concerns about implementability can be figured out later
<TabAtkins> astearns: So proposed resolution is to add the longhands to the spec in whatever form you find convenient to *describe* the functionality, and add a note requesting implementation of just the shorthand.
<TabAtkins> skk: In this context, ruby is a line?
<TabAtkins> fantasai: It's part of a line.
<TabAtkins> myles: So if you said max-lines:1, you don't just get the ruby annotations...
<TabAtkins> fantasai: And we'll revisit in TPAC
<TabAtkins> astearns: Objections
<TabAtkins> ?
<TabAtkins> RESOLVED: add the longhands to the spec in whatever form you find convenient to *describe* the functionality, and add a note requesting implementation of just the shorthand.
<myles> S/ruby annotations/ruby text/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.