Skip to content

computePosition

计算坐标以将浮动元素定位到另一个元素旁边。

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

import {computePosition} from '@floating-ui/dom';

用法

¥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.

<button id="button">My reference element</button>
<div id="tooltip">My floating element</div>

首先,为浮动元素指定初始 CSS 样式,使其成为浮动在 UI 顶部的绝对定位元素,并准备好进行测量布局:

¥First, give the floating element initial CSS styles so that it becomes an absolutely-positioned element that floats on top of the UI with layout ready for being measured:

#tooltip {
  /* Float on top of the UI */
  position: absolute;
 
  /* Avoid layout interference */
  width: max-content;
  top: 0;
  left: 0;
}

然后,确保这两个元素渲染到文档上并且可以测量,以它们作为参数调用 computePosition()

¥Then, ensuring that these two elements are rendered onto the document and can be measured, call computePosition() with them as arguments.

第一个参数是要锚定的 reference element,第二个参数是要定位的 floating element

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

import {computePosition} from '@floating-ui/dom';
 
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
 
computePosition(button, tooltip).then(({x, y}) => {
  Object.assign(tooltip.style, {
    left: `${x}px`,
    top: `${y}px`,
  });
});

computePosition() 返回一个 Promise,该 Promise 解析为可用于将样式应用于浮动元素的坐标。

¥computePosition() returns a Promise that resolves with 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.

初始布局

¥Initial layout

为了保证定位顺利进行,浮动元素定位前后的尺寸不应发生变化。

¥To ensure positioning works smoothly, the dimensions of the floating element should not change before and after being positioned.

在调用 computePosition() 之前必须应用某些 CSS 样式:

¥Certain CSS styles must be applied before computePosition() is called:

#floating {
  position: absolute;
  width: max-content;
  top: 0;
  left: 0;
}
  • position: absolute

这使得元素漂浮在 UI 顶部,具有基于内容的内在尺寸,而不是充当块。topleft 坐标即可生效。

¥This makes the element float on top of the UI with intrinsic dimensions based on the content, instead of acting as a block. The top and left coordinates can then take effect.

  • width: max-content(或固定值)

    ¥width: max-content (or a fixed value)

  • top: 0

  • left: 0

这些属性可防止浮动元素在溢出容器时调整大小,从而消除可能导致错误测量的布局干扰。

¥These properties prevent the floating element from resizing when it overflows a container, removing layout interference that can cause incorrect measurements.

这使你可以将浮动元素放置在 DOM 树中的任何位置并使其正确定位,而不管任何祖级容器的 CSS 样式如何。

¥This lets you place the floating element anywhere in the DOM tree and have it be positioned correctly, regardless of the CSS styles of any ancestor containers.

锚定

¥Anchoring

由于 computePosition() 只是一个函数调用,因此它只定位浮动元素一次。

¥Since computePosition() is only a single function call, it only positions the floating element once.

为了确保它在各种情况下(例如调整大小或滚动时)保持锚定到参考元素,请将计算封装在 autoUpdate 中:

¥To ensure it remains anchored to the reference element in a variety of scenarios, such as when resizing or scrolling, wrap the calculation in autoUpdate:

import {computePosition, autoUpdate} from '@floating-ui/dom';
 
// When the floating element is mounted to the DOM:
const cleanup = autoUpdate(referenceEl, floatingEl, () => {
  computePosition(referenceEl, floatingEl).then(({x, y}) => {
    // ...
  });
});
 
// ...later, when it's removed from the DOM:
cleanup();

选项

¥Options

作为第三个参数传递,这是配置行为的对象。

¥Passed as a third argument, this is the object to configure the behavior.

computePosition(referenceEl, floatingEl, {
  // options
});

placement

浮动元素相对于其参考元素的放置位置。默认情况下,这是 'bottom'

¥Where to place the floating element relative to its reference element. By default, this is 'bottom'.

12 个字符串可用:

¥12 strings are available:

type Placement =
  | 'top'
  | 'top-start'
  | 'top-end'
  | 'right'
  | 'right-start'
  | 'right-end'
  | 'bottom'
  | 'bottom-start'
  | 'bottom-end'
  | 'left'
  | 'left-start'
  | 'left-end';
computePosition(referenceEl, floatingEl, {
  placement: 'bottom-start', // 'bottom' by default
});

-start-end 对齐方式是 logical,并将按预期适应写入方向(例如 RTL)。

¥The -start and -end alignments are logical and will adapt to the writing direction (e.g. RTL) as expected.

strategy

这是要使用的 CSS 位置属性的类型。有两个字符串可用:

¥This is the type of CSS position property to use. Two strings are available:

type Strategy = 'absolute' | 'fixed';
computePosition(referenceEl, floatingEl, {
  strategy: 'fixed', // 'absolute' by default
});

确保你的初始布局符合策略:

¥Ensure your initial layout matches the strategy:

#tooltip {
  position: fixed;
}

这些策略的区别如下:

¥These strategies are differentiated as follows:

  • 'absolute' — 浮动元素相对于其最近的定位祖级进行定位。对于大多数布局,这通常要求浏览器在更新位置时执行最少的工作。

    ¥'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.

  • 'fixed' — 浮动元素相对于其最近的包含块(通常是视口)定位。当参考元素也被固定以减少滚动时定位的跳跃时,这非常有用。在很多情况下它也会 “break” 裁剪祖级中的浮动元素

    ¥'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

当你想要精确控制浮动元素的定位方式时,可以使用中间件。它们读取当前坐标,可以选择更改它们,和/或提供用于渲染的数据。它们组合并共同产生最终坐标,你将收到该坐标作为 xy 参数。

¥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 修改放置以添加参考元素和浮动元素之间的距离或边距。

    ¥offset modifies the placement to add distance or margin between the reference and floating elements.

  • inline 相对于各个客户端矩形而不是边界框定位浮动元素,以获得更好的精度。

    ¥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 通过移动浮动元素使其保持在视野中,防止浮动元素溢出剪切容器。

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

  • flip 通过将浮动元素翻转到相反的位置以保持在视图中,防止浮动元素溢出剪切容器。

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

  • autoPlacement 使用 “大部分空间” 策略自动为你选择展示位置。

    ¥autoPlacement automatically chooses a placement for you using a “most space” strategy.

  • size 调整浮动元素的大小,例如使其不会溢出剪切容器,或匹配参考元素的宽度。

    ¥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 提供数据来定位浮动元素的内部元素,使其以其参考元素为中心。

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

  • 当由于不同的剪切上下文而不再显示附加到其参考元素时,hide 提供了在适用情况下隐藏浮动元素的数据。

    ¥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 inside the array inline for ergonomics:

// The array can accept `false`, `null`, or `undefined`
// inside of it. They get filtered out.
type MiddlewareOption = Array<
  Middleware | false | null | undefined
>;

通常这对于更高级别的封装器函数很有用,以避免需要消费者自己导入中间件:

¥Often this is useful for higher-level wrapper functions to avoid needing the consumer to import middleware themselves:

function wrapper(referenceEl, floatingEl, options) {
  return computePosition(referenceEl, floatingEl, {
    ...options,
    middleware: [
      options.enableFlip && flip(),
      options.arrowEl && arrow({element: options.arrowEl}),
    ],
  });
}

返回值

¥Return value

computePosition() 返回以下类型:

¥computePosition() returns the following type:

interface ComputePositionReturn {
  x: number;
  y: number;
  placement: Placement;
  strategy: Strategy;
  middlewareData: MiddlewareData;
}

x

浮动元素的 x 坐标。

¥The x-coordinate of the floating element.

y

浮动元素的 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

要使用的 CSS 位置属性。

¥The CSS position property to use.

middlewareData

使用的任何中间件返回的数据。

¥The data returned by any middleware used.