Frequently Asked Questions (FAQ)
Don't see your question here? Feel free to ask on Spectrum! We'll try to answer you within a day or two.
Why is my popper in the wrong location (or not visible at all)?
For the left
and top
placements, Popper relies on HTML Standards Mode for
the computeStyles
modifier's adaptive
option. A problem will occur in Quirks
Mode when the <body>
is the popper element's offsetParent, and it's taller
than the viewport.
To fix it, use the Standards Mode doctype:
<!DOCTYPE html>
<html>
<!-- ... -->
</html>
Additionally, make sure your popper element (tooltip, popover, etc...) CSS
doesn't include some positioning styles (such as top
, left
, right
,
bottom
, and transform
) because they could interfere with the Popper
positioning logic.
Why is my popper jittering while scrolling?
If your reference element is position: fixed
, use the "fixed"
strategy:
createPopper(reference, popper, {
strategy: 'fixed',
});
Due to the way browsers handle element updates, there will likely be some inevitable stutters if the strategy does not match the reference element's position.
How do I add CSS transitions without disabling adaptive
?
We recommend making the popper element a wrapper around an inner element that can have any CSS property transitioned:
<div class="popper">
<div class="box">
Content
</div>
</div>
In the above case, the .popper
element is the one that's positioned but has no
styles applied. The .box
element has all of the CSS styling and animations.
How do I set modifier defaults and allow them to be overridden?
Modifiers are merged by name, where later items in the array override earlier ones. This provides a way to configure some defaults for modifiers, but allow them to be overridden easily:
// A user passes this object in:
const popperOptions = {
strategy: 'fixed',
modifiers: [
{
name: 'preventOverflow',
options: {
padding: 0,
},
},
],
};
// Your library sets its own defaults:
createPopper(reference, popper, {
...popperOptions,
modifiers: [
{
name: 'preventOverflow',
options: {
rootBoundary: 'document',
padding: 10,
},
},
...(popperOptions.modifiers || []),
],
});
How do I change offset
based on the browser width (media queries)?
Popper doesn't accept margins, but you can still make offset dynamic based on media queries.
window.matchMedia()
is a useful API for this — since offset
can take a
function, it allows you to dynamically change the offset based on a condition:
const mediaQuery = window.matchMedia('(max-width: 500px)');
createPopper(reference, popper, {
modifiers: [
{
name: 'offset',
options: {
// 0px distance at <= 500px width, otherwise 10px distance
offset: () => [0, mediaQuery.matches ? 0 : 10],
},
},
],
});
My popper is bigger than the viewport, what do I do?
Here are some options:
- Prevent the popper's width from ever exceeding the browser's width with
max-width: 100vw;
CSS (along withbox-sizing: border-box
). - Set
preventOverflow
'srootBoundary
option todocument
if it must be larger than the viewport. - Create a custom
size
modifier that changes the size of the popper based on the available space remaining, and allow the popper box to be scrolled. ThedetectOverflow
utility enables this.