Re: [css-houdini-drafts] [css-layout-api] Missing fragments and absolute children

The Working Group just discussed `Missing fragments and absolute children`, and agreed to the following:

* `RESOLUTION: Abspos parented to custom layout elements have static pos computed similar to flex and grid children`
* `RESOLUTION: The rules for abspos containing blocks is not changed with the presence of custom layout.`
* `RESOLVED: custom layout must return all fragments, otherwise return an error and fall back to block layout`

<details><summary>The full IRC log of that discussion</summary>
&lt;heycam> Topic: Missing fragments and absolute children<br>
&lt;heycam> github: https://github.com/w3c/css-houdini-drafts/issues/775<br>
&lt;heycam> iank_: in the Layout API, it's possible to have multiple children<br>
&lt;heycam> ... in the example in the issue, the second child has an abspos child in it<br>
&lt;heycam> ... its containing block is higher up in the tree<br>
&lt;heycam> ... inside of layout, we only lay out the first child, and return it<br>
&lt;heycam> ... what should the behaviour of the abspos be?<br>
&lt;heycam> Rossen: is there an expectation for anything to happen to the child box?<br>
&lt;heycam> iank_: in the current API, you can just leave out children<br>
&lt;heycam> ... and they don't lay out<br>
&lt;heycam> eae: effectively it's display:none<br>
&lt;heycam> ... so wouldn't it make sense for their children not to show up?<br>
&lt;heycam> Rossen: there are two things<br>
&lt;heycam> ... either the abspos child will be lifted outside the scope of the display:layout function grandparent, or not<br>
&lt;heycam> ... if it's lifted outside of it, I'm assuming layout will happen in the normal way<br>
&lt;heycam> iank_: your assumption is that it will display the abspos child somewhere else<br>
&lt;heycam> Rossen: if it's positions outside the scope of the display:layout<br>
&lt;heycam> ... would all abspos elements reach their containing block, during custom layout?<br>
&lt;heycam> ... you can have a bunch of inner levels of custom and normal layout<br>
&lt;heycam> ... will there be a discontinuity in that process?<br>
&lt;heycam> ... my assertion is that it shouldn't<br>
&lt;heycam> ... one potential problem is that if you rely on something as part of the custom layout, in that interleaving, and that's not calculated, you might get wonky results<br>
&lt;heycam> ... e.g. if you don't lay out child 2, and the abspos position depends on child 2's position, you'll have to syntehsize something for the static pos<br>
&lt;heycam> ... btu that's about it, or you might ahve something that is switching writing modes or whatnot<br>
&lt;heycam> ... but again my assertion here is that this shouldn't have an effect apart from residual things like static pos<br>
&lt;heycam> iank_: I'm fine with that<br>
&lt;heycam> ... what should happen with the static pos?<br>
&lt;heycam> Rossen: (a) we don't want to have a loss of content, regardless of what happens to the custom layout parent<br>
&lt;heycam> ... i.e. the abspos box should not just disappear, unless you explicitly say so<br>
&lt;heycam> dbaron: so you're saying is it should have its normal abspos containing block, and the custom layout is never an abspos containing block><br>
&lt;heycam> Rossen: no<br>
&lt;heycam> ... my assertion is the box with abspos element will always generate a box, and it will be parented to the appropriate containing block, which may or may not be custom layout<br>
&lt;heycam> ... distinction is propagating through custom layout layers, second is ending up at a non-custom layout containing block<br>
&lt;heycam> ... so besides calculating some invalid or default static pos<br>
&lt;heycam> iank_: somethign along the lines of pretend that it did generate a (0, 0, 0, 0) fragment<br>
&lt;heycam> fantasai: for custom layout, unless we might want to let it control the static pos, but certainly you could just use the rules in flexbox<br>
&lt;heycam> ... which is you pretend that the static pos rectangle is the whole flexbox<br>
&lt;heycam> Rossen: what happens if a flex item is the whole area<br>
&lt;heycam> fantasai: if display:layout and child2 are both doing custmo layout<br>
&lt;heycam> Rossen: the outer one is the containing block<br>
&lt;heycam> fantasai: the parent gets used as the static pos relative<br>
&lt;heycam> ... if you didn't lay it out<br>
&lt;heycam> Rossen: then its parent<br>
&lt;heycam> fantasai: but that box still needs a position<br>
&lt;heycam> ... why isn't there a box?<br>
&lt;heycam> dino: on child2 if you put display:none, what happens to abspos?<br>
&lt;heycam> Rossen: same as always, it wouldn't display<br>
&lt;heycam> dino: why is different from not laying it out?<br>
&lt;heycam> Rossen: we shouldn't itnroduce things that are like display:none just because didn't lay out a box<br>
&lt;heycam> fantasai: it should just be (0, 0, 0, 0)<br>
&lt;heycam> dino: sure<br>
&lt;heycam> fantasai: the box should still existing, and you just happen to not position it<br>
&lt;heycam> Rossen: just becomes a position and an empty rect<br>
&lt;heycam> dino: if it had a position, you'd use that<br>
&lt;heycam> Rossen: hwihc is what I would epect<br>
&lt;heycam> iank_: yes<br>
&lt;heycam> Rossen: if my containing block some span e.g., didn't have anything else than the abspos, it still has a position calculated for it<br>
&lt;heycam> eae: makes a lot of sense<br>
&lt;heycam> Rossen: the static position of an abspos elemenet, with a custom layout parent, is based on that parent's fragment's box<br>
&lt;heycam> fantasai: similar to how static pos of a box that is parented to a flex container uses the rectangle of the flex container to calculate it static pos, rather than any hypotehetical "would have been" layout like block layout<br>
&lt;heycam> Rossen: the summary here is taht the static pos of abspos elements parented to custom layout is the same as in CSS, based on the rectangle of that parent<br>
&lt;heycam> fantasai: similar to flex/grid, not block<br>
&lt;heycam> ... in block and layout they use the hypothetical position if they weren't positioned<br>
&lt;heycam> ... for flex and grid, we don't try to calculate where it would have been, pretend you would have coincided with your entire parent<br>
&lt;heycam> RESOLUTION: Abspos parented to custom layout elements have static pos computed similar to flex and grid children<br>
&lt;fantasai> s/RESOLUTION/RESOLVED/<br>
&lt;heycam> Rossen: next problem, you've computed static pos, that's great. you end up with a custom element that has position:relative<br>
&lt;heycam> dbaron: there's an easier piece we should resolve first<br>
&lt;heycam> fantasai: proposal is that custom layout does not interrupt propagation of abspos<br>
&lt;heycam> dbaron: it doesn't change the rules for when something is an abspos containing block<br>
&lt;heycam> Rossen: the abspos is never exposed to the custom layout in any form<br>
&lt;heycam> iank_: other potential thing is about the behavior of the second child, in this case<br>
&lt;heycam> ... you are thinking that child2 should get laid out with available size zero, and would still show up?<br>
&lt;heycam> ... it's specced as not showing up<br>
&lt;heycam> ... that might be somethign easier to resolve on<br>
&lt;heycam> RESOLUTION: The rules for abspos containing blocks is not changed with the presence of custom layout.<br>
&lt;heycam> s/RESOLUTION/RESOLVED/<br>
&lt;heycam> Rossen: next is, if the containing block is custom layout<br>
&lt;heycam> fantasai: if you don't explicitly lay out a child the layout engine resolves its size and position to zero<br>
&lt;heycam> frremy: I'm fine with that, but it will not show up<br>
&lt;heycam> ... I think that's ok, but if I don't put return it, I don't want it in the layout<br>
&lt;heycam> frremy: similar to display:contents or something<br>
&lt;heycam> ... if I don't want to include a particular element, implementing something like -webkit-line-clamp, I don't want them generating<br>
&lt;heycam> dbaron: if I were to try to think about how I wanted custom layout to deal with being an abspos containing block, I feel like I would want to two different options probably<br>
&lt;heycam> ... don't necessarily need both options in v1<br>
&lt;heycam> ... one of them would be: I want a custom layout, might be an abspos conatining block, I want it to handle things I'm the abspos containing block for using the default rules<br>
&lt;heycam> ... I don't want to handle those with custom layout, just handle the in flow contents<br>
&lt;heycam> ... other option: I also want to take over layout for the descendants I'm the abspos containing block for<br>
&lt;heycam> ... and in that case, in many cases I'd want to get those sets of children separately<br>
&lt;heycam> ... i.e. process the in flow ones first, then the abspos ones<br>
&lt;heycam> iank_: I could imagine an API that is two additional callback functions, one where your'e routinign children, yes pass this to parent, no keep this one to myself<br>
&lt;heycam> ... and an out of flow layout pass, which gives you the children you're a containing block for<br>
&lt;heycam> ...and go ahead ans apply whatever abspos rules you want<br>
&lt;heycam> frremy: that;s useful for the grid polyfill<br>
&lt;heycam> ... if you set grid-column on them you still need to be able to place them in columsn, even if they're abspos<br>
&lt;heycam> ... doesn't have to be in the layout step, could be a separate step<br>
&lt;heycam> Rossen: only problem I have with this, is if you select which children you want to handle, that goes against the resolution we just had before<br>
&lt;heycam> frremy: what does grid do?<br>
&lt;heycam> Rossen: the API proposed, here are the children going through, I want to keep certain ones ... unless we specify we're not even going to expose abspos to your children<br>
&lt;heycam> ... because you really don't need to<br>
&lt;heycam> iank_: I think it's a niche use case, a callback for routing<br>
&lt;heycam> Rossen: but that's a more advanced feature<br>
&lt;heycam> Rossen: so, current issue is, element with custom layout, it's also an containing block for abspos, there's a descendant abspos, and the custom layout does no layout. what happens to the rest of the children?<br>
&lt;heycam> ... one of the assertions we should have here is that that child, at that level, is just a normal first level child, it has to be laid out<br>
&lt;heycam> ... it shouldn't be any different from other ones<br>
&lt;heycam> ... so if I have two children that are inside of this custom layout, one is an immediate child, one is a descendant, regardless how deep the descenadnt is, it's something I need to handle at the first level<br>
&lt;heycam> ... if I can decline layout for a first level child, I should be able to do that for the abspos descendant too<br>
&lt;heycam> ... might be different for layout logic, that's your business<br>
&lt;heycam> ... but the point is that I have a collection of children fragments that came up to me, if I decide to drop them all, I can<br>
&lt;heycam> ... from that point of view I don't think we need anything specific to abspos, but we still need to be clear as to what the rules are<br>
&lt;heycam> iank_: yes, we can discuss that<br>
&lt;heycam> fantasai: the original issue, we've got an element whose static pos we need to find, static pos is not the custom layout in this particular case, because it's a child of a child of the custom layout<br>
&lt;heycam> ... custom layout is responsible for laying out the child, when it does, that box will determine the static pos of the grandchild<br>
&lt;heycam> ... if the custom layout doesn't lay out that child, we still need to know where the static pos<br>
&lt;heycam> Rossen: we resolved that<br>
&lt;heycam> fantasai: we resolved that for a child of the custom layout, this is for a grandchild of the custom layout<br>
&lt;heycam> fantasai: it's different because if we don't run layout on the child of the custom layout, we don't know where it is<br>
&lt;heycam> ... it's a regular inflow child of the custom layout, inside that it the abspos<br>
&lt;heycam> ... the abspos's position is dependent on the size/pos of child2<br>
&lt;heycam> ... we don't have answer for the size/pos of child2<br>
&lt;heycam> Rossen: my point in the beginning is that the static pos of the abspos, is the origin<br>
&lt;heycam> ... this is relative to its parent<br>
&lt;heycam> ... if the parent doesn't compute to anything, it will be to the origin of its parent<br>
&lt;heycam> ... at some point there is some ancestor where that origin is defined<br>
&lt;heycam> fantasai: we didn't resolve on that<br>
&lt;heycam> Rossen: this is how custom layout is defined to work, relative to parent<br>
&lt;heycam> fantasai: I know it's relative to parent<br>
&lt;heycam> dbaron: I think we need a definition of what happens if custom layout decides not to lay out something<br>
&lt;heycam> ... in our engine, layout code can't not lay out something<br>
&lt;heycam> ... I suspect other engines are probably similar<br>
&lt;heycam> ... if you get laid out at (0, 0, 0, 0), whatever it is, it should be defined somewhere<br>
&lt;heycam> ... once we have that definition, it resolves this<br>
&lt;heycam> [-- break 20 mins --]<br>
&lt;fantasai> ScribeNick: fantasai<br>
&lt;fantasai> fantasai: key question is what dbaron said, what do we do to fragments which are not laid out?<br>
&lt;fantasai> frremy: A common use case for not laying out a child is when you want, e.g. lay out items until you run out of space and then have a continuation marker (like ...)<br>
&lt;fantasai> frremy: you want to just stop laying out at that point<br>
&lt;fantasai> frremy: Should try to address this in custom layout<br>
&lt;fantasai> frremy: makes sense to not generate a box for items that aren't laid out<br>
&lt;fantasai> frremy: rather than defaulting to  (0,0,0,0)<br>
&lt;fantasai> frremy: So prefer to define same as 'display: none' or define something else similar<br>
&lt;fantasai> frremy: or throw an exception for now and figure it out later<br>
&lt;fantasai> frremy: Don't think it's useful to create a box that's zero-sized, this isn't useful<br>
&lt;fantasai> frremy: and not generating the box is sometimes useful<br>
&lt;fantasai> Rossen: I think not showing things is useful<br>
&lt;fantasai> myles: max-lines is simlar<br>
&lt;fantasai> similar<br>
&lt;fantasai> Rossen: Should be able to not lay out. If we don't lay out anything, the question is would we absoluely generate no fragment/box, or would we end up with an empty size and origin position?<br>
&lt;fantasai> s/or w/W/<br>
&lt;fantasai> Rossen: We still have to answer questions like from the OM, what's the size/position<br>
&lt;fantasai> Rossen: So what would make the most sense?<br>
&lt;fantasai> frremy: Compromise would be to have a box at zero/zero, but it just doesn't paint<br>
&lt;fantasai> iank_: Agree that we should say it doesn't paint.<br>
&lt;fantasai> iank_: but what about the rest of the subtree?<br>
&lt;fantasai> iank_: do we return zero for everything all the way down the subtree, or do we contineu with layout?<br>
&lt;heycam> fantasai: for max-lines specifically, frmo an implementation perspective, I think it does make sense to lay everything out<br>
&lt;heycam> ... that's a use case where you want to hide and show things dynamically, not having to relayout would be useful<br>
&lt;heycam> ... more generally I'm not sure<br>
&lt;heycam> ... if you're not going to display the stuff<br>
&lt;heycam> ... but you could display:none things you don't want to display<br>
&lt;heycam> Rossen: but this is a layout time decision<br>
&lt;heycam> eae: for max-lines it would be nice to not reflow things that aren't going to be displayed, unnecessary work<br>
&lt;heycam> koji: this could create next fragments, it's more about fragmentation, when the next fragment containiner is missing<br>
&lt;heycam> fantasai: you could make the same argument here<br>
&lt;heycam> ... we will support fragmentation<br>
&lt;heycam> iank_: it might be reasonable to say layout doesn't happen, and all CSSOM APIs return zero, getClientRects doesn't anything<br>
&lt;fantasai> iank_: Saying all this without imple experience, might change opinion based on experienc<br>
&lt;fantasai> iank_: everything returns zero, empty array for line boxes<br>
&lt;fantasai> dbaron: I think this is a magical semi-displayed case<br>
&lt;fantasai> dbaron: I'd rather have a lyout and have the APIs return a consistent state<br>
&lt;fantasai> iank_: we could also define a consistent state<br>
&lt;fantasai> dbaron: Sounds messy<br>
&lt;fantasai> iank_: I'm a little bit torn, agree with fremy that use cases for this are very valuable<br>
&lt;fantasai> Rossen: Another lense to use for reasoning, how would you serialize your collection of children in the case that fremy gave?<br>
&lt;fantasai> Rossen: e.g. for accessibility purposes<br>
&lt;fantasai> Rossen: Would want accessibilty tool to walk the same tree as what's visible<br>
&lt;fantasai> Rossen: Would you synthesize things in the AT or what?<br>
&lt;fantasai> iank_: Not accessible to normal users, so shouldn't be accessible to AT<br>
&lt;fantasai> iank_: The way to make this decision would be, what should happen in the max-lines case?<br>
&lt;fantasai> iank_: Could also punt this for now, get impl experience<br>
&lt;fantasai> iank_: Our current behavior is that you need to return all the fragments. Otherwise we'll fall back to block layout<br>
&lt;fantasai> Rossen: That's nice. Very predictable and verifiable<br>
&lt;fantasai> iank_: We should investigate, then reopen this issue.<br>
&lt;fantasai> Rossen: In which case, this is an error<br>
&lt;fantasai> iank_: Yep<br>
&lt;fantasai> Rossen: Fix your code. Make it work.<br>
&lt;fantasai> heycam: I think it might be easy to accidentally lose your custom layout<br>
&lt;fantasai> Rossen: Exactly<br>
&lt;fantasai> heycam: Might be that you change your ordering in certain window sizes, and then it breaks<br>
&lt;fantasai> fantasai: I think if you can't loop correctly over all the items in this list ...<br>
&lt;fantasai> Rossen: You shouldn't be doing custom layout.<br>
&lt;fantasai> iank_: Grid iterates in a particular order<br>
&lt;fantasai> frremy: But here you need to iterate in the right order<br>
&lt;fantasai> Rossen: Sounds like for this level of where we are, this is areasonable error case handling<br>
&lt;fantasai> Rossen: It is simple, it's easy to describe, and should be easy to fix on the script size<br>
&lt;fantasai> s/size/side<br>
&lt;fantasai> Rossen: With that, plus previous two resolutions, then we have a clear answer to what happens with abspos children<br>
&lt;fantasai> Rossen: If we need to get more sophisticated later, we can<br>
&lt;fantasai> Rossen: implementtion experience may suggest a beter pattern<br>
&lt;fantasai> frremy: Would need to feature detect somehow, whether the browser supports laying out all the boxes or not<br>
&lt;fantasai> iank_: Need to resolve on this, then: if you don't return all the fragments, we return an error and fall back to block layout<br>
&lt;fantasai> iank_: Falling back to block layout is what happens if the layout function throws an error<br>
&lt;fantasai> iank_: You can check by ...<br>
&lt;fantasai> heycam: What about existing content, that falls back to block currently and throws an error, and then later it starts to drop content<br>
&lt;heycam> fantasai: could fall back to content disappears?<br>
&lt;heycam> ... but we don't like dropping content<br>
&lt;fantasai> Rossen: We could fall back to 100em bright red...<br>
&lt;fantasai> iank_: Two ways to deal with that.<br>
&lt;fantasai> iank_: One is to use-count<br>
&lt;fantasai> iank_: Other, if that number is sufficiently hight, we can add a layout option<br>
&lt;fantasai> iank_: It's a bit heavy handed<br>
&lt;fantasai> iank_: but we can use-count it to check<br>
&lt;fantasai> ...<br>
&lt;fantasai> philipwalton: Could put a note in the spec explaining what we're planning to do<br>
&lt;fantasai> Rossen: This is simple, easy to spec, easy to explain, easy to see if you messed up. Can revisit later. It's a good solution.<br>
&lt;fantasai> RESOLVED: custom layout must return all fragments, otherwise return an error and fall back to block layout<br>
</details>


-- 
GitHub Notification of comment by css-meeting-bot
Please view or discuss this issue at https://github.com/w3c/css-houdini-drafts/issues/775#issuecomment-401649441 using your GitHub account

Received on Monday, 2 July 2018 01:36:34 UTC