Compute Position

Computes coordinates to position a floating element next to another element.

use floating_ui_core::compute_position;

Usage

At its most basic, the function accepts two elements:

  • Reference element - also known as the anchor element, this is the element that is being referred to for positioning. Often this is a button that triggers a floating popover like a tooltip or menu.
  • Floating element - this is the element that floats next to the reference element, remaining anchored to it. This is the popover or tooltip itself.
use floating_ui_utils::Rect;

let reference_el = Rect {width: 100, height: 100, x 50, y: 50};
let floating_el = Rect {width: 200, height: 200, x 0, y: 0};

Then, call compute_position() with them as arguments, ensuring you pass the required platform methods.

The first argument is the reference element to anchor to, and the second argument is the floating element to be positioned.

use floating_ui_core::{compute_position, ComputePositionConfig, ComputePositionReturn};
use floating_ui_utils::Rect;

let reference_el = Rect {width: 100, height: 100, x 50, y: 50};
let floating_el = Rect {width: 200, height: 200, x 0, y: 0};

let ComputePositionReturn {x, y} = compute_position(reference_el, floating_el, ComputePositionConfig::new(
    // See https://floating-ui.rustforweb.org/platform.html
    platform
));

// Paint the screen.

compute_position() returns the coordinates that can be used to apply styles to the floating element.

By default, the floating element will be placed at the bottom center of the reference element

Options

Passed as a third argument, this is the struct instance to configure the behavior.

compute_position(
    reference_el,
    floating_el,
    ComputePositionConfig::default(),
);
pub struct ComputePositionConfig<Element, Window> {
    pub placement: Option<Placement>,
    pub strategy: Option<Strategy>,
    pub middleware: Option<Vec<Box<dyn Middleware<Element, Window>>>>,
}

placement

Where to place the floating element relative to its reference element. By default, this is Placement::Bottom.

12 placements are available:

pub enum Placement {
    Top,
    TopStart,
    TopEnd,
    Right,
    RightStart,
    RightEnd,
    Bottom,
    BottomStart,
    BottomEnd,
    Left,
    LeftStart,
    LeftEnd,
}
compute_position(
    reference_el,
    floating_el,
    ComputePositionConfig::default().placement(Placement::BottomStart),
);

The Start and End alignments are logical and will adapt to the writing direction (e.g. RTL) as expected.

Note

You aren't limited to just these 12 placements though. Offset allows you to create any placement.

strategy

This is the type of CSS position property to use. By default, this is Strategy::Absolute.

Two strategies are available:

pub enum Strategy {
    Absolute,
    Fixed,
}
compute_position(
    reference_el,
    floating_el,
    ComputePositionConfig::default().strategy(Strategy::Fixed),
);

Ensure your initial layout matches the strategy:

#tooltip {
    position: fixed;
}

These strategies are differentiated as follows:

  • Strategy::Absolute - the floating element is positioned relative to its nearest positioned ancestor. With most layouts, this usually requires the browser to do the least work when updating the position.
  • Strategy::Fixed - the floating element is positioned relative to its nearest containing block (usually the viewport). This is useful when the reference element is also fixed to reduce jumpiness with positioning while scrolling. It will in many cases also “break” the floating element out of a clipping ancestor.

middleware

When you want granular control over how the floating element is positioned, middleware are used. They read the current coordinates, optionally alter them, and/or provide data for rendering. They compose and work together to produce the final coordinates which you receive as x and y parameters.

The following are included in the package:

Placement Modifiers

These middleware alter the base placement coordinates.

  • Offset modifies the placement to add distance or margin between the reference and floating elements.

  • Inline positions the floating element relative to individual client rects rather than the bounding box for better precision.

Visibility Optimizers

These middleware alter the coordinates to ensure the floating element stays on screen optimally.

  • Shift prevents the floating element from overflowing a clipping container by shifting it to stay in view.

  • Flip prevents the floating element from overflowing a clipping container by flipping it to the opposite placement to stay in view.

  • AutoPlacement automatically chooses a placement for you using a “most space” strategy.

  • Size resizes the floating element, for example so it will not overflow a clipping container, or to match the width of the reference element.

Data Providers

These middleware only provide data and do not alter the coordinates.

  • Arrow provides data to position an inner element of the floating element such that it is centered to its reference element.

  • Hide provides data to hide the floating element in applicable situations when it no longer appears attached to its reference element due to different clipping contexts.

Custom

You can also craft your own custom middleware to extend the behavior of the library. Read middleware to learn how to create your own.

Conditional

Middleware can be called conditionally. Often this is useful for higher-level wrapper functions to avoid needing the consumer to import middleware themselves:

struct Options {
    enable_flip: bool,
    arrow_el: Option<Element>,
}

fn wrapper(reference_el: Element, floating_el: Element, options: Options) -> ComputePositionReturn {
    let mut middleware = vec![];

    if options.enable_flip {
        middleware.push(Box::new(Flip::new(FlipOptions::default())));
    }
    if let Some(arrow_el) = options.arrow_el {
        middleware.push(Box::new(Arrow::new(ArrowOptions::new(options.arrow_el))));
    }

    compute_position(reference_el, floating_el, ComputePositionConfig::default().middleware(middleware))
}

Return Value

compute_position() returns the following struct:

pub struct ComputePositionReturn {
    pub x: f64,
    pub y: f64,
    pub placement: Placement,
    pub strategy: Strategy,
    pub middleware_data: MiddlewareData,
}

x

The x-coordinate of the floating element.

y

The y-coordinate of the floating element.

placement

The final placement of the floating element, which may be different from the initial or preferred one passed in due to middleware modifications. This allows you to know which side the floating element is placed at.

strategy

The CSS position property to use.

middleware_data

The data returned by any middleware used.

See Also