[csswg-drafts] [css-anchor-position-1] Better handle an inset-area edge case when the default anchor element is partially or completely outside the containing block (#9663)

kizu has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-anchor-position-1] Better handle an inset-area edge case when the default anchor element is partially or completely outside the containing block ==
I have a created a demo CodePen (viewable in the latest Chrome Canary with the experimental flags on): https://codepen.io/kizu/pen/zYemwKM?editors=1100

Here is a video of how things work right now:

https://github.com/w3c/csswg-drafts/assets/177485/6d50ab66-d624-4c96-986e-43ce2bece160

In it, we can see how `inset-area` behaves when the default anchor element is placed partially or completely outside its containing block.

I imagine, some quirks of how it is currently displayed might be implementation bugs/grey areas, but then I think maybe the spec could be adjusted to be more flexible to cover these cases?

To quote the current spec (https://drafts.csswg.org/css-anchor-position-1/#resolving-spans) (I did replace the `ul` with `ol` to number the lines):

> The inset-area grid is conceptually a 3x3 grid, composed of four grid lines in each axis. In order:
>    - the start edge of the element’s [containing block](https://drafts.csswg.org/css-display-4/#containing-block) (aka the position referred to by [top: 0px;](https://drafts.csswg.org/css-position-3/#propdef-top) or whatever [inset property](https://drafts.csswg.org/css-logical-1/#inset-properties) corresponds to the start side of the containing block)
>    - the anchor(start) edge of the [default anchor element](https://drafts.csswg.org/css-anchor-position-1/#default-anchor-element)
>    - the anchor(end) edge of the [default anchor element](https://drafts.csswg.org/css-anchor-position-1/#default-anchor-element)
>    - the end edge of the element’s [containing block](https://drafts.csswg.org/css-display-4/#containing-block) (aka the position referred to by [bottom: 0px](https://drafts.csswg.org/css-position-3/#propdef-bottom), or whatever [inset property](https://drafts.csswg.org/css-logical-1/#inset-properties) is opposite the first one)

The issue I see is the “in order” part, and how things work in the current Canary implementation when the lines are not, in fact, in order. When the default anchor partially intersects or entirely leaves its containing block (in all these examples I imagine it leaves into the “right”, or “end” direction), its lines' order messes up.

- When the element partially leaves the containing block, the lines are ordered 1 2 4 3
- When the element fully leaves the containing block, the lines are ordered 1 4 2 3

The current implementation seems to use the lines rather than areas, so the “center” would span the 2–3 lines, so it could go outside the containing block, and the `all` spans 1–4, so it would never leave the containing block.

I think this might be not what the authors could expect, and this behavior is not very useful for the cases when the elements leave the containing block.

My proposal would be: to make sure the lines always stay in the same order, and do this by stretching the containing block's lines to always fit the default anchor. To take the examples from the previous list:

- When the element partially leaves the containing block, the lines are still 1 2 3 4, with the 3 & 4 lines being “merged” and being located at the `anchor(end)`.
- When the element fully leaves the containing block, the lines are, again, ordered 1 2 3 4, in the same way as above with 3 & 4 merged, and the 2 going outside the original containing block's bounds.

Now, there is a chance the “staying inside the containing block” behavior could be desirable (like keeping the tooltips in the viewport instead of them following the popover?), for this the best could be to introduce a separate property that would control this.

1. By default, _I think_ (but not strongly) when the element leaves its containing block, it stretches it, the first example in the CodePen above that only uses start/end/center currently behaves like this:
    
    <img width="745" alt="A screenshot of a 3×3 grid where the element did leave the containing element on the left, with the grid stretching over the element itself." src="https://github.com/w3c/csswg-drafts/assets/177485/88d44f88-bb9b-4b3c-8e5e-b37d847be81a">

2. As an option, we could make the anchor's element's line never “leave” the containing block. In this case:
    - When the element partially leaves the containing block, the lines are still 1 2 3 4, with the 3 & 4 lines being “merged”, but located at the edge of the containing block.
    - When the element fully leaves the containing block, the lines are, again, ordered 1 2 3 4, but now the 2, 3 & 4 are merged.

    The second example in the CodePen above that has the “all” behaves this way:

    <img width="664" alt="A screenshot of a 1×3 grid where the element did leave the containing element on the left, with the grid being contained inside the containing block only." src="https://github.com/w3c/csswg-drafts/assets/177485/3f1bec3b-e323-4287-b5c4-8475bc3d5e5c">

We can see that _right now_ we get either one behavior or another based on if we're using `all` keyword, or not, or maybe even some mixed weirdness like in the third example.

Making this edge case follow one of the ways with the lines always in order would be already an improvement, but I really think it would be the best to allow specifying this behavior: we'd want the grid to be always contained, or stretch over the combined area of an element and its containing block. Especially if we will decide to allow https://github.com/w3c/csswg-drafts/issues/9662 — in which case we will almost always want the “stretching” behavior.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/9663 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 30 November 2023 22:58:22 UTC