Interaction
Overlays
Popovers and modals built on the browser, with a script only where CSS cannot reach.
An overlay in sitereal is the browser's, not ours. popover on the panel, popovertarget on the button, :popover-open and ::backdrop in your own rule — the top layer, light dismiss, Escape and focus handling all come from the platform.
Two kinds
| Kind | For | Ships |
|---|---|---|
| Fixed | modals, toasts, videos | no script at all |
| Relative | dropdowns, popovers | overlay.js, which measures and places it |
A Fixed overlay needs nothing beyond CSS. A Relative one hangs off the button that opened it, and that is the one thing CSS cannot do everywhere yet — anchor positioning is Chromium-only — so a small script measures and places it, and steps aside where anchor-name is supported.
The trigger is an element you pick
There is no hidden setting. Whatever carries popovertarget="<id>" is the trigger, which is exactly what the browser reads:
<button builder-data-element="button" popovertarget="menu-1">Account</button>
<div builder-data-element="div" id="menu-1" popover data-overlay="relative">
…
</div>Any element can be a trigger, and an overlay can have several.
The rule you get
Adding an overlay writes a starter rule into your own stylesheet — in your tokens, with a fallback on every one, so it still looks like a panel with the design system switched off:
#menu-1 {
position: fixed;
inline-size: max-content;
padding: var(--space-s, 1rem);
background: var(--base-ultra-light, #fff);
border: var(--border, 1px solid rgba(0, 0, 0, 0.12));
border-radius: var(--radius-m, 8px);
box-shadow: var(--shadow-l, 0 18px 40px rgba(0, 0, 0, 0.18));
opacity: 0;
translate: 0 -0.35rem;
transition: opacity 160ms ease, translate 160ms ease,
overlay 160ms allow-discrete, display 160ms allow-discrete;
&:popover-open { opacity: 1; translate: 0 0; }
&::backdrop { background: rgb(0 0 0 / 0.5); }
@starting-style {
&:popover-open { opacity: 0; translate: 0 -0.35rem; }
}
}Two details are worth knowing, because they are why overlays fade instead of blink:
- The closed state is
display: none— the browser's own — so a transition has to opt in withallow-discrete. @starting-styleis the frame before it opens, so it has somewhere to come from.
Both are in the rule, where you can edit them.
On the canvas
The canvas deliberately does not apply popover: an overlay you cannot see is an overlay you cannot edit. It marks it instead, and shows it in place.
When not to use one
If the thing is a menu, build a navigation — dropdowns, mobile panel, focus trap and aria-* wiring are already done there. Overlays are for the rest: a modal, a filter panel, a video lightbox, a share sheet.