Skip to content

[css-anchor-position][other] Handling popover default styles #10258

Open
@tabatkins

Description

@tabatkins

HTML defines some UA styles for popover elements https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3:

[popover] {
  position: fixed;
  inset: 0;
  width: fit-content;
  height: fit-content;
  margin: auto;
  border: solid;
  padding: 0.25em;
  overflow: auto;
  color: CanvasText;
  background-color: Canvas;
}

These styles center the element in the page, which is a useful default display for a popover.

However, popover was always designed with the intention that it would also be able to interop with Anchor Positioning, and position itself relative to its invoker (this is the whole reason the implicit anchor name exists).

Unfortunately, if you then do the simplest, most obvious styling, like:

[popover] {
  top: anchor(bottom);
  left: anchor(left);
}

or even

[popover] {
  inset-area: bottom span-right;
}

neither of these work correctly! Both of them end up interacting with the default inset: 0; from the UA styles, and behaving wrong as a result (stretching oddly, and/or not responding to scrolling correctly). Authors have to learn to manually set inset: auto; in these cases to reset things, and it's very easy to forget. Worse, it's very hard to realize what's happening, as the IMCB isn't visible in the page and not well-indicated in DevTools, either.

(Also, it uses margin-based centering, which has to be reset too, but we're finally at the point where we can depend on place-self: center working for abspos.)

In summary, we have two distinct styles we need:

  • when not anchoring, inset: 0; place-self: center;
  • when anchoring, inset: auto; place-self: normal; (aka the initial values)

I don't have a great solution for this! It would be nice if we could somehow only apply those "center in the screen" styles when the element isn't using anchoring, but the only way to detect that is by examining the styles themselves. Maybe we need to indicate that the popover will be anchored in the HTML syntax? Other solutions appreciated.

Or perhaps we could have a value, maybe in align/justify-self, which conditionally applies the "right" behaviors when something is anchored vs not? If it can just resolve to center vs normal, and trigger the "auto insets go to 0" behavior that anchor-center does, it would Just Work. I think this is defensible as a reasonable fallback for a lack of anchors? The UA stylesheet would then look like:

[popover] {
  position: fixed;
  place-self: bikeshed-center-when-unanchored;
  /* border, etc.
}

Or maybe this is a condition that can trigger position fallback, somehow - if your anchors don't exist, fallback to the next style? I imagine associating the position-visiblity keywords with individual try-options, indicating that they'll be used under those conditions. Then the UA stylesheet would look like:

[popover] {
  position: fixed;
  position-try-options: anchors-valid --ua-screen-centered;
}
@position-try --ua-screen-centered {
  inset: 0;
  place-self: center;
}

I kinda like this last one a lot? It seems worthwhile for authors in other cases, and is the most flexible. It's also the least intrusive when you don't think about it - if you're just applying some anchor styles, it'll do nothing, which is what you want, and if you do end up specifying some position-try stuff it'll get silently overridden without causing lingering issues.

/cc @mfreed7

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions