autoPlacement
A visibility optimizer that chooses the placement that has the most space available automatically.
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: false
false
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
allowedPlacements
allowedPlacements
are all on the same axis.
autoPlacement({
crossAxis: true,
});
autoPlacement({
crossAxis: true,
});
alignment
default: undefined
undefined
Without options, autoPlacement()
autoPlacement()
will choose any of the
Side
Side
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: true
true
When alignment
alignment
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 allPlacements
allPlacements
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
});
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.