Positioning
Place a popover, menu or tooltip next to its trigger, keep it there on scroll and resize, and flip it when there is no room.
Anchored elements
anchored() places the element on a side of its anchor, aligned along it, with a small
gap. Start and end follow the writing direction, so the same code works in right-to-left layouts.
Open the popover, then change its side and alignment. Near an edge of the window it flips to the other side.
<script>
import { anchored, dismissable } from 'sveltier';
let open = $state(false);
let trigger = $state();
</script>
<button bind:this={trigger} aria-expanded={open} onclick={() => (open = !open)}>Account</button>
{#if open}
<!-- A manual popover sits in the top layer; anchored() places it, dismissable() closes it. -->
<div
popover="manual"
{@attach (element) => element.showPopover()}
{@attach anchored({ anchor: trigger, side: 'bottom', align: 'end' })}
{@attach dismissable({ onDismiss: () => (open = false), inside: [trigger] })}
>
…
</div>
{/if}| Name | Type | Default | Description |
|---|---|---|---|
anchor | Element | null | undefined | – | The element to place against. Nothing happens until it exists. |
side | 'top' | 'bottom' | 'start' | 'end' | 'bottom' | Side of the anchor. Start and end follow the writing direction. |
align | 'start' | 'center' | 'end' | 'start' | Alignment along that side, following the writing direction. |
offset | number | 5 | Gap between the anchor and the element, in px. |
flip | boolean | true | Move to the opposite side when there is not enough room. |
How it works
Where the browser has CSS anchor positioning, the browser does all the work: the element moves with its anchor and flips without a line of script running. Elsewhere a small script loads on demand and places the element the same way, so browsers with native support never download it.
Put the element in the top layer with popover, or position it with position: fixed: it is placed against the viewport, so no ancestor can clip it.