w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.5k stars 668 forks source link

[css-anchor] Detecting active @position-fallback #8171

Open jh3y opened 1 year ago

jh3y commented 1 year ago

Currently, we don't have a proposed way to detect which fallback is currently active.

A huge use case for this is if we want to display arrows on elements such as tooltips. If I have a position-fallback that goes from top to bottom:

@position-fallback --vertical {
  @try {
    top: anchor(bottom);
  }
  @try {
    bottom: anchor(top);
  }
}

If my arrow is styled on the top of my element. But then my element is moved to be on top of the anchor. My arrow now points to space potentially.

Although not possible with the spec as is, being able to use non-inset properties would be interesting inside the fallback.

@position-fallback --vertical {
  @try {
    --on-the-bottom: 1;
    top: anchor(bottom);
  }
  @try {
    --on-the-top: 1;
    bottom: anchor(top);
  }
}

You could use that custom property like a boolean flip for the arrow position. But, I imagine there's a more elegant solution to this potentially.

xiaochengh commented 1 year ago

There's a fundamental issue: position-fallback is applied at used value time. If we expose the active fallback to CSS, then we allow computed values to depend on used values, which violates the "specified -> computed -> used values" pipeline.

Unless we introduce one more snapshotting: we can snapshot the active fallback at the beginning of a frame and expose it to other properties, like how we currently deal with scrolling.

tabatkins commented 1 year ago

The plan is that we'll introduce a new CQ type for this; CQs violate that pipeline in the exact same way, but in a controlled manner. We'll need to be careful that you can't trigger the parent to flip into a different fallback set, tho.

bfgeek commented 1 year ago

The plan is that we'll introduce a new CQ type for this; CQs violate that pipeline in the exact same way, but in a controlled manner. We'll need to be careful that you can't trigger the parent to flip into a different fallback set, tho.

We'll need size containment in both axes for this to work

fantasai commented 9 months ago

This isn't fundamentally cyclic, as long as you have a clear and unambiguous way to tie the conditional styles to the position option.

kizu commented 9 months ago

I think using something like CQ here is the way, though the tricky thing is the size containment.

The way I think could be the most powerful while avoiding any circularity: an ability to query any container's closest used fallback. Critically, not the fallback used on the container itself, as allowing the containment on the children of the positioned element can make things more flexible.

<div popover>
  <div class="decorations"></div>
  Some content
</div>

With this HTML, for example, we will have a popover which uses some list of fallbacks, and then what we could do is position the .decorations with inset: 0 over the popover, make it a container, and then any pseudo-element (or element) inside this container could query the fallback.

Of course, if the popover itself could be made a container, any children could query the fallback directly, but that will come with more limitations, so an ability to separate the containers from the fallbacks they query could be the most flexible way to go.

wesbos commented 1 week ago

I spent some time playing with anchors today and could not find a single example using a tooltip with a "tail" that changes based on it's position-try

For example putting something a tooltip above with position-area: top center;

Screenshot 2024-11-08 at 4 56 38 PM

But then changing the tooltip tail / arrow when it's been flipped with with position-try-fallbacks: flip-block; or another @position-try

Screenshot 2024-11-08 at 4 59 04 PM

I was looking for either some sort of keyword for the anchored inline-block side, a style query, or the ability to target more css inside a @position-try past the allowed values.

All I understand why they don't work, but is this design not possible with CSS anchors?

tabatkins commented 1 week ago

At the moment, there is indeed no way to do that. It will have to wait for a container query that can ask what fallback style the abspos is using (and then style a child making the "tail" properly).

wesbos commented 1 week ago

OK - thank you for the quick reply!