Skip to content

autoPlacement

A visibility optimizer that chooses the placement that has the most space available automatically.

Scroll the container

This is useful when you don’t know which placement will be best for the floating element, or don’t want to have to explicitly specify it.

Usage

import {computePosition, autoPlacement} from '@floating-ui/dom';
 
computePosition(referenceEl, floatingEl, {
  middleware: [autoPlacement()],
});
import {computePosition, autoPlacement} from '@floating-ui/dom';
 
computePosition(referenceEl, floatingEl, {
  middleware: [autoPlacement()],
});

Options

These are the options you can pass to autoPlacement()autoPlacement().

interface Options extends DetectOverflowOptions {
  crossAxis?: boolean;
  alignment?: Alignment | null;
  autoAlignment?: boolean;
  allowedPlacements?: Array<Placement>;
}
interface Options extends DetectOverflowOptions {
  crossAxis?: boolean;
  alignment?: Alignment | null;
  autoAlignment?: boolean;
  allowedPlacements?: Array<Placement>;
}

crossAxis

default: falsefalse

Determines whether a “most space” strategy is also used for the cross axis (which runs along the alignment of the floating element). May be desirable when the allowedPlacementsallowedPlacements are all on the same axis.

autoPlacement({
  crossAxis: true,
});
autoPlacement({
  crossAxis: true,
});

alignment

default: undefinedundefined

Without options, autoPlacement()autoPlacement() will choose any of the SideSide placements which fit best, i.e. 'top''top', 'right''right', 'bottom''bottom', or 'left''left'.

By specifying an alignment, it will choose those aligned placements.

autoPlacement({
  // top-start, right-start, bottom-start, left-start
  alignment: 'start',
});
autoPlacement({
  // top-start, right-start, bottom-start, left-start
  alignment: 'start',
});

autoAlignment

default: truetrue

When alignmentalignment is specified, this describes whether to automatically choose placements with the opposite alignment if they fit better.

autoPlacement({
  alignment: 'start',
  // Won't also choose 'end' alignments if those fit better
  autoAlignment: false,
});
autoPlacement({
  alignment: 'start',
  // Won't also choose 'end' alignments if those fit better
  autoAlignment: false,
});

allowedPlacements

default: computed subset of allPlacementsallPlacements

Describes the placements which are allowed to be chosen.

autoPlacement({
  // 'right' and 'left' won't be chosen
  allowedPlacements: ['top', 'bottom'],
});
autoPlacement({
  // 'right' and 'left' won't be chosen
  allowedPlacements: ['top', 'bottom'],
});
autoPlacement({
  // Only choose these placements
  allowedPlacements: ['top-start', 'bottom-end'],
});
autoPlacement({
  // Only choose these placements
  allowedPlacements: ['top-start', 'bottom-end'],
});

…detectOverflowOptions

All of detectOverflow’s options can be passed. For instance:

autoPlacement({
  padding: 5, // 0 by default
});
autoPlacement({
  padding: 5, // 0 by default
});

Deriving options from state

You can derive the options from the middleware lifecycle state:

autoPlacement((state) => ({
  padding: state.rects.reference.width,
}));
autoPlacement((state) => ({
  padding: state.rects.reference.width,
}));

Final placement

The placement returned from the function will let you know which placement was chosen.

computePosition(referenceEl, floatingEl, {
  middleware: [autoPlacement()],
}).then(({placement}) => {
  console.log(placement); // 'top', 'bottom', 'left' or 'right'
});
computePosition(referenceEl, floatingEl, {
  middleware: [autoPlacement()],
}).then(({placement}) => {
  console.log(placement); // 'top', 'bottom', 'left' or 'right'
});

Conflict with flip

flip()flip() and autoPlacement()autoPlacement() cannot be used together inside the same middleware array, make sure you choose only one of them to use.

The reason is they both try to perform work on the placement but with opposing strategies. Therefore, they will continually try to change the result or work of the other one, leading to a reset loop.

  • flip()flip() — Uses a fallback “no space” strategy. Ensures the preferred placement is kept unless there is no space left.
  • autoPlacement()autoPlacement() — Uses a primary “most space” strategy. Always chooses the placement with the most space available.