-
Notifications
You must be signed in to change notification settings - Fork 711
[css-position-3] Containing block formed by fragmented inlines #8284
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
Comments
This was last discussed in #609 ; see also dbaron's multi-directional test suite. |
(And the spec now reflects the resolution from #609, which is to just take Chrome's behavior. We're just not completely convinced it's the best behavior.) |
We discussed this and while, as expected, we didn't come up with any simple solutions, I'll summarize our opinions and ideas: We broke the containing block down into it's four coordinates: inline-start: the start edge of the first visual fragment of the first line (equal to specified single line behavior) *"line box end edge" could be defined in different ways with regard to how it interacts with floats. **"end edge of the first line" is something we were not able to define. Using the end edge of the last fragment of the first line didn't seem right, as we already actively ignore that fragment for inline-end. One colleague brought up a more out-of-the-box approach that we feel worth discussing: To enable anchoring boxes both at the (visual) start as well as the end of the multi-line inline in all cases a conditional behavior could be introduced. |
The CSS Working Group just discussed
The full IRC log of that discussion<emilio> scribenick: emilio<fantasai> https://www.software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Cp%3E%3Cdiv%20style%3D%22background%3A%20gray%3B%20width%3A%20100px%3B%20height%3A%201em%3B%20display%3A%20inline-block%22%3E%3C%2Fdiv%3E%3Cspan%20style%3D%22position%3A%20relative%3B%20border%3A%20solid%20blue%22%3E%3Cspan%20style%3D%22position%3A%20absolute%3B%20inset%3A%200%3B%20border%3A%20orange%20solid%22%3E%3C%2Fspan <fantasai> %3Efirst%20and%3Cbr%3Esecond%20line%20that%27s%20very%20long%20and%3Cbr%3Ethird%3C%2Fspan%3E%0A%3Cp%3E%3Cspan%20style%3D%22position%3A%20relative%3B%20border%3A%20solid%20blue%22%3E%3Cspan%20style%3D%22position%3A%20absolute%3B%20inset%3A%200%3B%20border%3A%20orange%20solid%22%3E%3C%2Fspan%3Efirst%20and%3Cbr%3Esecond%20line%20that%27s%20very%20long%20and%3Cbr%3Ethird%3C%2Fspan%3E <emilio> fantasai: what do we do when the absolute positioned box is an inline but it spans multiple lines <emilio> [describes test-case] <emilio> ... firefox and chrome disagree <emilio> ... so... on a single line the abspos cb is the line's bounds <emilio> ... when it spans multiple lines we could use join the top-left of the first fragment and the bottom-right of the last <emilio> ... but if the last line is to the left of the first it creates a negative area <emilio> ... chrome / webkit collapse the width to zero <emilio> ... firefox does [missing] <emilio> ... there are pros and cons to both approaches <emilio> ... the four things we think we can do are in the bullet list in the last comment <fantasai> Use the first line's fragments only (so the entire containing block is contained by its generating box). <fantasai> Anchor at the start/start corner of the first line box and extend to the end/end corner of the last line box, but clamp the inline size at zero (so the end/end corner might not overlap with a fragment). <fantasai> Anchor at the start/start corner of the first line box and extend to the end/end corner of the last line box, and allow inversions (so the corners are pinned to actual fragment corners, but the containing block might end up between fragments). <fantasai> Anchor at the start/start corner of the first line box and extend to the end/end corner of either the last line box (if that's endward of the start line) or of the first line box (otherwise). <dbaron> There's some old discussion of this in https://bugzilla.mozilla.org/show_bug.cgi?id=489100 and maybe also the somewhat-related https://bugzilla.mozilla.org/show_bug.cgi?id=489207 <emilio> TabAtkins: my preferred behavior is to anchor the top left of top left of the first fragment, anchor bottom to the bottom of the last fragment, and anchor right to the right-edge of either the whole fragment, or line box edge if there are multiple <emilio> ... allows cb to be as tall as the whole multi-line text box <emilio> ... and also as wide as the whole text <emilio> ... if there's text going further on later lines it'd be good to include that on the box left <emilio> ... so top-left to top-left of first fragment (matches webkit + blink + ff) <iank_> q+ <emilio> ... bottom matching blink/webkit <emilio> ... and right edge to the right edge of line box (if multi-line) or end of fragment if it's single-fragment <astearns> ack dbaron <fantasai> ... rather than whereever the first fragment happened to break <emilio> dbaron: this is something I thought about a good bit about a decade ago <fantasai> Tab's proposal seems reasonable to me... <emilio> ... two things I wanna point out <emilio> ... one is that it's worth being reasonably careful about directionality <emilio> ... I think we all do this based on the direction prop of the inline <iank_> we've fixed stuff <emilio> ... iirc chrome didn't handle rtl well but edge did <emilio> ... related issue issue is: how do auto-offsets behave for absposes inside inlines <emilio> ... maybe it's not that related but there are a few interesting aspects to it <astearns> ack iank_ <astearns> q+ <emilio> iank_: worth retesting Chrome because we've fixed a lot of these <emilio> ... one thing to note is the start and end is complicated, because the IFC can have different direction to the inline CB <emilio> ... I _believe_ we use the direction of the IFC <TabAtkins> Yeah, I'd think the IFC is probably the most coherent thing to take the directions from? <emilio> ... we don't necessarily want to do that but it makes sense given all the edge cases <emilio> ... when you say linebox we don't quite want that <emilio> ... you probably want the max IFC inline edge coordinate <emilio> ... because you can have multiple fragments in one line <emilio> ... and those might not go at the end of the line box <emilio> TabAtkins: if the inline starts at the left edge of the text area and it covers multiple lines the CB should fill the box <emilio> ... even if if the actual text bounds is slightly narrower <emilio> iank_: you can have the situation where the span won't go all the way to the inline edge but there may be some text there <emilio> ... but it is different <emilio> ... I think tab's proposal seems fine <emilio> astearns: I don't like something about tab's proposal, which is the difference for the determination for the start and end edge <emilio> ... I think it'd make sense to also take the smallest start edge <emilio> iank_: I doubt that'd be compatible <emilio> ... that's interoperable now, it's used to do something like a caret at the start of an inline <emilio> TabAtkins: that's why <emilio> astearns: It's just a weird result where the orange box covers half of the paragraph in fantasai's <astearns> ack dbaron <emilio> ... test-case <astearns> ack astearns <emilio> TabAtkins: yeah, but it's very interoperable behavior, so I think we're stuck with that <iank_> there is :) <emilio> dbaron: Are there complications here when the inline is split across columns/pages? <emilio> iank_: there are, I can talk about what edge did here, but that's a long tangent <emilio> TabAtkins: so we do ??? <astearns> ack dbaron <TabAtkins> s/???/still anchor the top-left of the CB to the top-left of the first fragment there?/ <emilio> dbaron: I think the issue of splitting over columns / pages is one of the reasons this never got fixed in Gecko <astearns> ack fantasai <Zakim> fantasai, you wanted to discuss this right-edge criteria <emilio> ... but might also be more about the auto behavior <astearns> q+ <emilio> fantasai: Wanted to talk about about what we pin the right edge to <emilio> ... end of the first line's last fragment? <emilio> ... rightmost of all of the lineboxes? <TabAtkins> My instinct is that if there's a column/etc break, we put the bottom edge to the end of the last fragment in that fragmentainer, analogous to the right-edge behavior. <emilio> ... rightmost of all the fragments? <emilio> ... line boxes have different edges with floats <iank_> From my perspective right most of either the line-boxes or the fragments <emilio> ... do we want to consider all of the lines? Or just the first? <emilio> iank_: pretty strong bias towards all of the lines <emilio> ... covers the case where all of the lines might not line up <TabAtkins> Ah, I see what you mean by "probably don't want lineboxes" then, yeah <TabAtkins> right edge fo the IFC or whatever, instead, yeah <TabAtkins> +1 to rightmost/bottommost of all fragments <emilio> fantasai: my proposal would be to use the rightmost edge of all of the fragments of the inline box <emilio> astearns: hard time coming with a use case for doing much more than what FF is doing <emilio> ... the case of putting a caret at the beginning of the line is the thing we can't change <emilio> ... what use case is there for having an abspos thing going over some weird section of a fragmented inline? <emilio> TabAtkins: there's no use case for doing both of the horizontal/vertical bounds we're defining <emilio> ... but each individually make sense <emilio> iank_: someone willing to cover all of the lines <emilio> fantasai: that's only useful if the span is the first thing in the line <TabAtkins> 1) Putting something at the start of the text (requires top/left to be the top left of the first fragment). 2) Have something as tall as the text (background, or overlay, etc). <emilio> iank_: true <TabAtkins> I think those are the two use-cases we can reasoanbly address with a single-box solution. <emilio> astearns: I worry that we're coming up with this thing that isn't really motivated by use cases <emilio> ... we're defining some reasonable behavior for this edge case where a lot of cases we could get the abspos cb further up <emilio> ... firefox's behavior seems simpler to spec and doesn't run into fragmentation issues <TabAtkins> +1 <emilio> iank_: we have a solution for fragmentation <TabAtkins> (+1 to Ian, that is) <emilio> ... but somewhat hard <emilio> ... probably don't have time on this call to consider it <emilio> ... I think we should consider at least all of the lines' block edges <iank_> (i've got to run 👋) <emilio> fantasai: proposal is that that in LTR-tb the top-left corner is the top-left corner of the top-left-most fragment of the first line, and the bottom and right edges are bottommost and rightmost edges of all the fragments <dholbert> bottom right of all-of-the-fragments, or all-of-the-line-boxes-that-contain-fragments? (if there's a <br> that prevents the fragments from hitting the end of the line) <emilio> RESOLVED: Try out the proposal above, spec the fragmentation behavior <TabAtkins> (afaict, the use-cases I listed are already satisfied by Chrome/WebKit's behavior, since neither of them depend on the right side. But I do think a zero-width box should be avoided if we can.) <dbaron> (also need to be clear whether that LTR-tb is for the IFC or the inline) <fantasai> analogously for other writing modes, anchoring on the same writing mode as the painting of borders <emilio> fantasai: I think you want the writing-mode of the inline element, e.g. if you want a flag at the start of the span <emilio> emilio: iank_ was arguing for writing-mode of the IFC <dholbert> (my question relates to a distinction that Tab was making early on; we should be clear whether we're talking about line boxes vs. fragments for bottom-right corner. Sorry, my audio seems to be broken) <emilio> proposal for dholbert's question is using the fragments themselves <dholbert> thanks! <emeyer> I have an uneasy feeling about the proposed solution, but I’m not sure I understand it properly.. <fantasai> Using fragments, because if you have short lines of text you want the edges of those inlines, not the far right of the screen <emilio> RESOLVED: in LTR-tb the top-left corner is the top-left corner of the top-left-most fragment of the first line, and the bottom and right edges are bottommost and rightmost edges of all the fragments. Directionality comes from the inline <fantasai> see testcase on borders: https://www.software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Cp%3EThis%20%3Cspan%20dir%3Drtl%20style%3D%22border%3A%20solid%22%3Etest%3Cbr%3Eborder%3C%2Fspan%3E%3C%2Fp%3ERESOL <TabAtkins> emeyer, top/left/bottom edge all match Chrome's current behavior, right edge is the rightmost of *all* fragments (rather than just the first, like what FF currently does, or the last-but-clamped, like Chrome currently does) |
After thinking about this some more - the current resolution breaks a use-case. At the moment developers can use the previous behaviour to anchor something to the end fragment (if they can ensure the start of the inline always is at the start), e.g. A potential option is to alter the containing block depending on what inset properties are set instead. e.g. if both insets in an axis is set, use the bounding-rect, if one inset is set, use the first/last fragment edge. |
@bfgeek If you do that per-axis, then you can end up pinning things to where there isn't anything, though. E.g. if I try to position against the bottom left corner in LTR on a multiline box that doesn't start on the left edge, I'll end up somewhere at the bottom middle of the paragraph. You need to consider both axes simultaneously. Edits for the latest WG resolution are in b961c0b btw; I'm leaving the issue open for discussion, though, and marked it in the draft. |
This is similar to our second proposal:
The major difference is that we don't think there should be 3rd behavior for when both
Considering that there are no obvious bottom-left and top-right (start-end and end-start) corners that would be fine with us. However it does show that a property giving the author various options is probably the best solution. |
We could consider both axises, so only if you referenced the start/start or end/end corners do we use the first/last fragment. (Or start/end in one axis with double-auto in the other axis.) If you're inconsistent, you get a fallback behavior (bounding box?). |
CSS2.1 defines the containing block formed by an inline box like this:
In CSS Positioning Level 3, we tried to generalize the definition in a way that would handle multiple lines:
This basically takes (for LTR text) the top/left edges of the first fragment and the bottom/right edges of the last fragment and makes a rectangle of them. The “left” box edge might end up as the “right” containing block edge, but in any case there's a rectangle.
What browsers actually do is demonstrated in this testcase:
The question here is, what actually is the most useful thing to do?
The text was updated successfully, but these errors were encountered: