Repository navigation
[css-anchor-position][other] Handling popover default styles #10258
Description
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
Labels
Type
Projects
- StatusShow more project fieldsThursday Morning
- StatusShow more project fieldsAgenda+
Activity
tabatkins commentedon Apr 26, 2024
Maybe for that last one, the syntax would be just supplying a position-try block name to
position-visibility, likeposition-visibility: anchors-valid --ua-screen-centered;; if you don't supply a position-try name, it does the default "super-hide it" behavior.nt1m commentedon Apr 29, 2024
I'm surprised
inset-area: bottom span-right;doesn't work, I was expectinginset-areato reset insets for all 4 sides.tabatkins commentedon Apr 30, 2024
It was never defined to act like a shorthand for the other insets, no. (That would be a slightly strange design, tho not unworkable perhaps.) You usually want auto insets for
inset-area, but not necessarily always.Even if it did, tho, the alignment would still be wrong; inset-area wants
normalwhile the non-anchored popup wantscenter.fantasai commentedon May 12, 2024
Wait, explain this bit? Why would the
inset-areaone have this effect? The spec setsautoinsets to zero already wheneverinset-areaisn'tnoneso... if that' breaks things then it's very broken?o-t-w commentedon Jan 20, 2025
I don't find centering by default compelling. I'd usually use a dialog element for use-cases that require centering in the viewport. Most popover use-cases require positioning the popover in relation to the anchor.
inset: auto;is a better default.jakearchibald commentedon Jul 9, 2025
When I used
position-area: top, it appeared "not working" until I figured out I needed to also setmargin: 0.position-areais a kinda magic "we'll just do the right thing for you" feature, so it was kinda frustrating that it came with this confusing gotcha.I don't have any solutions to recommend though. Maybe using
position-areaoranchor()in any position value, activates a pseudo-class that can only be used in the UA stylesheet (to avoid loops in author code), which is in-turn used to setmargin: 0in the UA stylesheet. Ugh.jamesnw commentedon Jul 9, 2025
Because the UA styles for popover contain
margin: auto, would it be possible to say thatmargin: autoresolves to 0 when the popover element is using anchor positioning?We could re-use the conditions from Compensates for scroll. "If a popover has a default anchor box and an anchor reference to its default anchor box, the
autokeyword formarginresolves to 0."I was unable to find a specification for
margin: auto, so I'm not sure what other impacts there might be.yisibl commentedon Jul 9, 2025
This used to be in Chrome, where you didn't need
margin: 0, and then the behavior changed. Please refer to: https://issues.chromium.org/issues/374574260tabatkins commentedon Jul 21, 2025
Okay, @fantasai and I are giving this issue another shot, because it continues to be a constant souce of confusion for authors, even very experienced ones. See e.g. #12466
Recapping the issue:
[popover]defaults to styling the element in a “non-anchored” way - it's fixpos and centered on the screen. This is perfectly fine as a default.position-area: bottom span-leftor something, it doesn't work. This is because the “centered fixpos” styles don't play nicely with anchorpos styling and defaults. To get things to work, authors have to remember to unset margins back to0.Our goal is to square this circle, and make it so that authors doing the intuitive thing get the intuitive result, if possible. We think we've hit on a solution.
Proposal
Add a new
dialogvalue toalign/justify-self. (Better name potentially TBD, but we think this one could work as-is.) This value responds toposition-area: ifposition-areais set to a non-nonevalue, it resolves just likealign/justify-self:normal. But ifposition-areaisnone(initial value), then it triggers theposition-areaadditional behavior (resolving auto insets to0, etc), but acts likealign/justify-self: center. (Thenormalvalue already responds toposition-area, so this dependency has strong precedent.)The HTML UA stylesheet can then simplify, replacing all the sizing/aligning properties for popovers:
By default, this centers the element in the viewport and sizes it to its content, as today. If an author sets
position-area, tho, it'll automatically work as expected -position-area: bottom span-right;will “attach” it to the popover invoker.This also handles some other cases more elegantly, we think. For example, an author setting
place-self: stretchtoday would also not see any effect, because the default styles explicitly setwidthandheight; after this change, it'll actually stretch.An alternative we considered was a new value for
position-areawhich would behave just likespan-allexcept resolvingnormalalignment tocenterinstead ofanchor-center. Both options would get us similar behavior, but this felt more like an alignment problem than aposition-areaproblem.CC @kizu @jakearchibald
una commentedon Jul 23, 2025
YES please fix this, it is a major footgun! Though I think the real issue is for specifically anchor positioned elements, not just general
[popover]elements. When you anchor position an element, that's essentially by definition saying you want to position it relative to its anchor and not the viewport (current UA style behavior that gets in the way). Some[popover]elements won't be anchored and thus aren't affected by this as much. The anchored popovers are where this really comes into play and causes so much frustration.Additionally, for semantic purposes, a
dialogmight also be anchored. Is there a way to resolve on a solution for specifically anchored elements?tabatkins commentedon Jul 25, 2025
@una pointed out in private chat that this defaults issue extends to dialogs in general, not just popovers; I'd missed that, despite looking at the styles for dialogs in general at the same time.
It stems from the same basic issue: it's using margins to center in the inline axis, which mispositions it when you use anchor positioning. See this basic example:
The big black bar indicates the center of the page - the dialog is centered in the bottom-right position-area cell, which puts it far away from its anchor and looking oddly off-center as well. It also ends up positioned identically if you instead open it as a modal, and scrolls with its anchor (because that's how anchored fixpos is supposed to work!)
Luckily, the modal dialog behavior is essentially identical to the popover behavior - fixpos, centered in the screen. The non-modal dialog is a bit different - abspos, centered inline, auto-positioned block. This works out nicely! We can just add another behavior for
dialogwhen it's abspos rather than fixpos, so it does not resolve the block insets to 0 and sticks withnormalalignment in the block axis; by default, then it'll use the static position, as specified today. That would let us simplify the stylesheets further:leaving us with just:
And now, using
position-areaon a dialog will Just Work (once you also setposition-anchor, since it doesn't get an implicit anchor)nt1m commentedon Jul 25, 2025
Not a fan of a special "dialog" value. Is it something that could benefit non-dialog use cases? Is it top layer specific? Names should reflect that ideally.
80 remaining items
Bug 1994521 [wpt PR 55460] - [css-anchor-position-1] Ignore auto marg…
Bug 1998474 [wpt PR 55860] - [wpt] Remove the align-dialog-* tests., …
astearns commentedon Nov 10, 2025
RESOLVED: Auto margins are disabled if align-self is set to anchor-center
Bug 1994521 [wpt PR 55460] - [css-anchor-position-1] Ignore auto marg…
Bug 1998474 [wpt PR 55860] - [wpt] Remove the align-dialog-* tests., …
Bug 1994521 [wpt PR 55460] - [css-anchor-position-1] Ignore auto marg…
Bug 1998474 [wpt PR 55860] - [wpt] Remove the align-dialog-* tests., …
Bug 1994521 [wpt PR 55460] - [css-anchor-position-1] Ignore auto marg…
Bug 1998474 [wpt PR 55860] - [wpt] Remove the align-dialog-* tests., …
`position-area`: add behavioral subfeature for auto margins
`position-area`: add behavioral subfeature for auto margins (#29280)