Skip to content
llms.txt
llms.txt

Placement

Open the live placement demo

Live demo

Placement

Source for this preview

PlacementExample.astro
---
import {DEFAULT_PLACEMENT, PLACEMENT_OPTIONS} from '../../example-data';
---
<div id="placement-demo" class="placement-stage" aria-label="Interactive placement selector">
{
PLACEMENT_OPTIONS.map((placement) => (
<button
type="button"
class:list={[
'placement-control',
{'is-selected': placement === DEFAULT_PLACEMENT},
]}
value={placement}
aria-pressed={placement === DEFAULT_PLACEMENT}
aria-label={`Place floating element at ${placement}`}
>
<span aria-hidden="true"></span>
</button>
))
}
<floating-root id="placement-root" open placement={DEFAULT_PLACEMENT}>
<div slot="reference" class="placement-reference">Reference</div>
<template slot="content">
<div class="placement-floating" role="status">{DEFAULT_PLACEMENT}</div>
</template>
</floating-root>
</div>
<script>
import {
FloatingRootElement,
offset,
type Placement,
} from '@floating-ui-plus/web-components';
import {initializeExample} from './initialize-example';
initializeExample('placement', (scope) => {
const floating = FloatingRootElement.query(scope, '#placement-root');
floating.middleware = [offset(18)];
const panel = scope.querySelector<HTMLElement>('.placement-floating');
const controls = [
...scope.querySelectorAll<HTMLButtonElement>(
'.placement-control',
),
];
controls.forEach((button) => {
button.addEventListener('click', () => {
const placement = button.value as Placement;
floating.placement = placement;
controls.forEach((control) => {
const selected = control === button;
control.classList.toggle('is-selected', selected);
control.setAttribute('aria-pressed', String(selected));
});
if (panel) panel.textContent = placement;
void floating.updatePosition();
});
});
});
</script>

Open the full demo ↗

The placement card exposes all 12 values (top, top-start, top-end, and the corresponding bottom/right/left variants). Clicking a control updates the root and calls updatePosition():

const placement = button.dataset.placementControl as Placement;
floating.placement = placement;
await floating.updatePosition();

offset(18) makes the gap visible. Use the generated PLACEMENT and PLACEMENTS exports for typed constants, or pass ordinary placement strings. The Vue version binds placement through FloatingRoot options or the composable state.