Floatit API Reference
API At a Glance
| Symbol | Purpose | Common gotcha |
|---|---|---|
float() | Position + auto-update in one call | Call the returned cleanup when the floating UI unmounts |
positionFloat() | Compute and apply position styles directly | Use float() or autoUpdate in dynamic contexts |
computePosition() | Compute coordinates without DOM writes | Apply returned coordinates every reposition cycle |
autoUpdate() | Re-run a callback on viewport/layout changes | Dispose the updater when the floating UI unmounts |
Core Functions
float(reference, floating, options?)
The primary API. Positions the floating element immediately and keeps it in sync as the viewport or elements change. Returns a cleanup function.
Parameters:
reference: Element— The anchor element the floating element is positioned relative tofloating: HTMLElement— The element to be positionedoptions?: FloatOptions— Optional configuration
Returns: () => void — Cleanup function; call it when the floating element is hidden
Example:
const cleanup = float(trigger, tooltip, {
placement: 'top',
middleware: [offset(8), flip(), shift({ padding: 6 })],
});
// When done:
cleanup();positionFloat(reference, floating, options?)
Computes the floating position and immediately applies left / top inline styles to the floating element. Use float() when you also need auto-update.
Parameters:
reference: Element— The anchor element the floating element is positioned relative tofloating: HTMLElement— The element to be positionedoptions?: FloatOptions— Optional configuration
Returns: Placement — The resolved placement (which may differ from the requested one after flip)
Example:
const placement = positionFloat(trigger, dropdown, {
placement: 'bottom-start',
middleware: [flip(), shift({ padding: 6 })],
});computePosition(reference, floating, config?)
Low-level positioning engine. Computes { x, y, placement } without touching the DOM.
Parameters:
reference: Element— The anchor elementfloating: HTMLElement— The floating elementconfig?: ComputePositionConfig— Optional configuration
Returns: ComputePositionResult
Example:
const { x, y, placement } = computePosition(trigger, panel, {
placement: 'top',
middleware: [offset(8), flip()],
});
panel.style.transform = `translate(${x}px, ${y}px)`;autoUpdate(reference, floating, update, options?)
Calls update once immediately, then re-calls it whenever the floating element's position may have changed.
Listens to:
scrollonwindow(capturing — covers all scroll ancestors)resizeonwindowResizeObserveronreferenceand (by default) onfloatingwindow.visualViewportresize/scroll (by default)
Parameters:
reference: Element— The anchor elementfloating: HTMLElement— The floating elementupdate: () => void— Callback to re-run positioningoptions?: AutoUpdateOptionsobserveFloating?: boolean— Whether to observe size changes on the floating element itself (default:true)observeVisualViewport?: boolean— Whether to observevisualViewportchanges for pinch-zoom / virtual keyboard (default:true)
Returns: () => void — Cleanup function; call it when the floating element is hidden
Example:
const cleanup = autoUpdate(trigger, tooltip, () => {
positionFloat(trigger, tooltip, { placement: 'top', middleware: [flip()] });
});
// Later, when tooltip is hidden:
cleanup();Middlewares
offset(value)
Adds a pixel gap between the reference element and the floating element along the main axis.
Parameters:
value: number— Gap in pixels
Returns: Middleware
offset(8); // 8px gapflip(options?)
Flips to the opposite side when the preferred side would overflow the viewport.
Parameters:
options?: FlipOptionspadding?: number— Minimum distance from viewport edges before flipping (default:0)
Returns: Middleware
flip(); // flip when overflow
flip({ padding: 8 }); // flip when within 8px of viewport edgePipeline restart
When flip changes the placement, computePosition automatically restarts the middleware pipeline so that all subsequent middlewares (e.g. shift) receive the correct base coordinates for the new side.
shift(options?)
Slides the floating element along its cross axis to keep it inside the viewport.
Parameters:
options?: ShiftOptionspadding?: number— Minimum distance to maintain from viewport edges (default:0)
Returns: Middleware
shift(); // clamp to viewport
shift({ padding: 6 }); // maintain 6px from edgessize(options?)
Calls an apply callback with available dimensions so the floating element can be resized or constrained.
Parameters:
options?: SizeOptionspadding?: number— Reduce reported available space by this amount on each side (default:0)apply?: (args: SizeApplyArgs) => void— Called synchronously with{ availableWidth, availableHeight, elements }
Returns: Middleware
size({
padding: 8,
apply({ availableHeight, elements }) {
elements.floating.style.maxHeight = `${availableHeight}px`;
},
});Types
Placement
type Side = 'top' | 'bottom' | 'left' | 'right';
type Alignment = 'start' | 'end';
type Placement = Side | `${Side}-${Alignment}`;
// e.g. 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | ...AutoUpdateOptions
interface AutoUpdateOptions {
observeFloating?: boolean;
observeVisualViewport?: boolean;
}FloatOptions
interface FloatOptions {
placement?: Placement;
middleware?: Array<Middleware | null | undefined | false>;
}ComputePositionConfig
interface ComputePositionConfig {
placement?: Placement;
middleware?: Array<Middleware | null | undefined | false>;
}ComputePositionResult
interface ComputePositionResult {
x: number;
y: number;
placement: Placement;
}Middleware
interface Middleware {
name: string;
fn: (state: MiddlewareState) => MiddlewareState;
}MiddlewareState
interface MiddlewareState {
x: number;
y: number;
placement: Placement;
rects: {
reference: { x: number; y: number; width: number; height: number };
floating: { x: number; y: number; width: number; height: number };
};
elements: {
reference: Element;
floating: HTMLElement;
};
}FlipOptions
interface FlipOptions {
/** Minimum distance from the viewport edge before flipping (px). Default: 0 */
padding?: number;
}ShiftOptions
interface ShiftOptions {
/** Minimum distance to maintain from viewport edges (px). Default: 0 */
padding?: number;
}SizeOptions
interface SizeOptions {
/** Reduce available space by this amount on each side (px). Default: 0 */
padding?: number;
/** Called synchronously with available dimensions. */
apply?: (args: SizeApplyArgs) => void;
}SizeApplyArgs
interface SizeApplyArgs {
availableWidth: number;
availableHeight: number;
elements: {
reference: Element;
floating: HTMLElement;
};
}