Appearance
usePosition
usePosition adds JavaScript geometry to an existing floating context. It owns placement, strategy, middleware configuration, generated styles, auto-update wiring, and manual updates.
Type
ts
function usePosition(context: FloatingContext, options?: UsePositionOptions): FloatingPosition;ts
interface UsePositionOptions {
placement?: MaybeRefOrGetter<Placement | undefined>;
strategy?: MaybeRefOrGetter<Strategy | undefined>;
transform?: MaybeRefOrGetter<boolean | undefined>;
middleware?: MaybeRefOrGetter<UsePositionMiddlewareOptions | undefined>;
middlewares?: MaybeRefOrGetter<Middleware[]>;
autoUpdate?: MaybeRefOrGetter<boolean | AutoUpdateOptions | undefined>;
enabled?: MaybeRefOrGetter<boolean>;
}
interface UsePositionMiddlewareOptions {
offset?: true | false | OffsetOptions;
flip?: true | false | FlipOptions;
shift?: true | false | ShiftOptions;
matchWidth?: boolean;
custom?: MaybeRefOrGetter<Middleware[] | undefined>;
}
interface FloatingPosition {
x: Readonly<Ref<number>>;
y: Readonly<Ref<number>>;
strategy: Readonly<Ref<Strategy>>;
placement: Readonly<Ref<Placement>>;
middlewareData: Readonly<Ref<MiddlewareData>>;
isPositioned: Readonly<Ref<boolean>>;
styles: Readonly<Ref<FloatingStyles>>;
update: () => Promise<void>;
}
type FloatingStyles = {
position: Strategy;
top: string;
left: string;
transform?: string;
"will-change"?: string;
} & {
[key: `--${string}`]: any;
};Details
usePosition reads context.refs.anchorEl and context.refs.floatingEl. It never creates or mutates open state.
placementdefaults to"bottom".strategydefaults to"absolute".transformis enabled by default and writes coordinates as a CSS transform.middlewareconfigures common positioning behavior without manually composing Floating UI middleware.middleware.customappends raw middleware after the declarative middleware options.middlewaresstill accepts a raw middleware pipeline for existing code, but new code should prefermiddlewareandmiddleware.custom.autoUpdateis enabled by default. Passfalseto disable it, or pass anAutoUpdateOptionsobject.enabledgates computation and auto-update listeners without tying positioning to open state.x,y,placement,strategy,middlewareData, andisPositionedexpose the last computed positioning result.stylesis the style ref you usually bind to the floating element.- Other composables, such as
useArrow, can register middleware through the internal registry attached to the returned position object.
Example
This tooltip opts into positioning after creating the shared context.
vue
<script setup lang="ts">
import { ref } from "vue";
import { useFloatingContext, useHover, usePosition, useRole } from "v-float";
const anchorEl = ref<HTMLElement | null>(null);
const floatingEl = ref<HTMLElement | null>(null);
const context = useFloatingContext({
refs: { anchorEl, floatingEl },
});
const { styles } = usePosition(context, {
placement: "top",
middleware: {
offset: 8,
},
enabled: () => context.state.open.value,
});
useHover(context);
useRole(context, { role: "tooltip" });
</script>
<template>
<button ref="anchorEl">Hover me</button>
<div v-if="context.state.open.value" ref="floatingEl" :style="styles">Helpful detail</div>
</template>Use middleware.custom when you need a middleware that VFloat does not expose as a semantic option.
ts
usePosition(context, {
placement: "bottom-start",
middleware: {
offset: 8,
flip: true,
shift: { padding: 8 },
custom: [myCustomMiddleware()],
},
});See Also
- useFloatingContext - Shared refs and open state
- offset - Add space between anchor and floating element
- Placement and Positioning - Positioning mental model