The future of Popper is here! Floating UI is now available. Get it now!
Popper Logo
Popper Logo

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 with box-sizing: border-box).
  • Set preventOverflow's rootBoundary option to document 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. The detectOverflow utility enables this.
Edit this page
Performance
© 2024 MIT License