Skip to content

offset

沿指定轴平移浮动元素。

¥Translates the floating element along the specified axes.

Placement Modifier
import {offset} from '@floating-ui/dom';

这使你可以添加参考元素和浮动元素之间的距离(边距或间距),稍微改变位置,甚至创建 自定义展示位置

¥This lets you add distance (margin or spacing) between the reference and floating element, slightly alter the placement, or even create custom placements.

0px

10px

用法

¥Usage

computePosition(referenceEl, floatingEl, {
  middleware: [offset(10)],
});

传递的值是 logical,这意味着它们对物理结果的影响取决于放置、写入方向(例如 RTL)或对齐。

¥The value(s) passed are logical, meaning their effect on the physical result is dependent on the placement, writing direction (e.g. RTL), or alignment.

排序

¥Order

offset() 通常应放置在中间件数组的开头。

¥offset() should generally be placed at the beginning of your middleware array.

选项

¥Options

这些是你可以传递给 offset() 的选项。

¥These are the options you can pass to offset().

type Options =
  | number
  | {
      mainAxis?: number;
      crossAxis?: number;
      alignmentAxis?: number | null;
    };

数字表示浮动元素和参考元素之间的距离(装订线或边距)。这是 mainAxis 的简写。

¥A number represents the distance (gutter or margin) between the floating element and the reference element. This is shorthand for mainAxis.

offset(10);

还可以传递一个对象,这使你能够单独配置每个轴。

¥An object can also be passed, which enables you to individually configure each axis.

mainAxis

默认:0

¥default: 0

沿着浮动元素侧面延伸的轴。表示浮动元素和参考元素之间的距离(装订线或边距)。

¥The axis that runs along the side of the floating element. Represents the distance (gutter or margin) between the floating element and the reference element.

offset({
  mainAxis: 10,
});

这是它的四个侧面的样子:

¥Here’s how it looks on the four sides:

top

bottom

left

right

crossAxis

默认:0

¥default: 0

沿着浮动元素的对齐方式延伸的轴。表示浮动元素和参考元素之间的滑动。

¥The axis that runs along the alignment of the floating element. Represents the skidding between the floating element and the reference element.

offset({
  crossAxis: 20,
});

这是它的四个侧面的样子:

¥Here’s how it looks on the four sides:

top

bottom

left

right

alignmentAxis

默认:null

¥default: null

crossAxis 相同的轴,但仅适用于对齐放置并反转 end 对齐。当设置为数字时,它将覆盖 crossAxis 值。

¥The same axis as crossAxis but applies only to aligned placements and inverts the end alignment. When set to a number, it overrides the crossAxis value.

正数会将浮动元素沿与对齐边缘相对的方向移动,而负数则相反。

¥A positive number will move the floating element in the direction of the opposite edge to the one that is aligned, while a negative number the reverse.

offset({
  alignmentAxis: 20,
});

以下是它与 crossAxis 的区别:

¥Here’s how it differentiates from crossAxis:

top-start
(crossAxis)

top-end
(crossAxis)

top-start
(alignmentAxis)

top-end
(alignmentAxis)

创建自定义展示位置

¥Creating custom placements

虽然你只能选择 12 个不同的展示位置作为核心库的一部分,但你可以使用 offset() 中间件来创建你想要的任何展示位置。

¥While you can only choose 12 different placements as part of the core library, you can use the offset() middleware to create any placement you want.

例如,虽然库没有提供在两个轴上居中的位置,但 offset 通过允许你读取矩形的函数选项来实现此目的:

¥For example, although the library doesn’t provide a placement for centering on both axes, offset enables this via the function option by allowing you to read the rects:

computePosition(referenceEl, floatingEl, {
  middleware: [
    // Assumes placement is 'bottom' (the default)
    offset(({rects}) => {
      return (
        -rects.reference.height / 2 - rects.floating.height / 2
      );
    }),
  ],
});

10px

在这种情况下,函数选项从默认的底部位置开始,然后使用该起点返回一个偏移量以使浮动元素在两个轴上居中。

¥In this case, the function option starts from the default bottom placement, then using that starting point, returns an offset to center the floating element on both axes.

对角线放置也是可能的:

¥A diagonal placement is also possible:

computePosition(referenceEl, floatingEl, {
  placement: 'top-start',
  middleware: [
    offset(({rects}) => ({
      alignmentAxis: -rects.floating.width,
    })),
  ],
});

这次以 'top-start' 为起点。

¥This time, 'top-start' was used as the starting point.

因此,允许这样做很简单:

¥So, it’s straightforward to allow this:

computePosition(referenceEl, floatingEl, {
  placement: 'center',
});

使用封装器,如下所示:

¥With a wrapper, like this:

import {computePosition as base, offset} from '@floating-ui/dom';
 
const centerOffset = offset(({rects}) => {
  return -rects.reference.height / 2 - rects.floating.height / 2;
});
 
export function computePosition(
  referenceEl,
  floatingEl,
  options,
) {
  const isCentered = options.placement === 'center';
  const placement = isCentered ? 'bottom' : options.placement;
  const middleware = [
    isCentered && centerOffset,
    ...(options.middleware || []),
  ];
 
  return base(referenceEl, floatingEl, {
    ...options,
    placement,
    middleware,
  });
}