React-popper: Incorrect position on mount

Created on 15 Apr 2020  路  12Comments  路  Source: popperjs/react-popper

After updating to version 2.2 and above, popper is incorrectly positioned on first mount. Simple scroll or resize event will fix it.

Reproduction demo

https://codesandbox.io/s/gifted-ishizaka-3mxdv

Steps to reproduce the problem

  1. In provided codesandbox demo, open styles.css and remove min-height on line 4

What is the expected behavior?

Popper should be placed correctly

What went wrong?

Popper is misplaced, window resize will cause popper refresh and it will be corrected

Any other comments?

incorrect position after mount: (purple is arrow element, just to demonstrate position)
1

after resize, position is corrected
2

Packages versions

  • @popperjs/core: 2.3.2
  • react-popper: 2.2.2

Most helpful comment

the arrow needs to have same width and height, and its position needs to be absolute, otherwise before Popper has a chance to position it, the arrow will stretch the tooltip.

https://codesandbox.io/s/lingering-waterfall-qr9y2?file=/src/Popper.js

All 12 comments

I can't reproduce it in Chrome or FF. In Safari the layout shifts but updates aren't triggered by default when the DOM layout changes. Is that the issue?

I am using Chrome 81.0.4044.92 64bit on Win10. Also tried Firefox 75.0 and issue is present.
Here is screencast:
popper

I see, this is expected behavior. The popper doesn't update due to layout changes by default, only scroll/resize. It should've happened with any version in the past though.

But it is causing issues with arrow position in my other project. This is how it looked like on the first mount before using hooks version:
2 1 0
After implementing hooks, it looks like this:
2 2 2

You are probably passing an arrow with useRef, not using useState, right? You need to use callback refs not a ref object.

If not, try to create a CodeSandbox reproduction that matches the screenshot

I have updated the sandbox: https://codesandbox.io/s/gifted-ishizaka-3mxdv
The first load is showing displaced arrow:
firstload
Can you please check it out?

https://codesandbox.io/s/frosty-breeze-3525h?file=/src/styles.css

two problems:

  1. you arrow needs to have a width & height specified
  2. you need to use a ternary for the className, since it's doing arrowundefined currently

I have implemented it in my project, based on your example (added width, height, corrected classnames) but the problem persists. I was unable to reproduce it on codesandbox, but i found that if i scroll page at least 1px down, everything works correct. Problem is shown only on the first page load, when content is not scrolled.

I have created another demo, which reproduces the problem. First, i have bootstrapped simple react app from create-react-app, then i have added popper, react-popper and emotion for css-in-js. I have implemented popper example using hooks and the problem persists.
Repo URL: https://github.com/ejdzipi/cra-popper-arrow-issue
@atomiks can you please take another look on this? I have added width&height for arrow element, ref is managed with useState, code is taken from this library's readme. I have no clue how to fix it. Thanks.
image

the arrow needs to have same width and height, and its position needs to be absolute, otherwise before Popper has a chance to position it, the arrow will stretch the tooltip.

https://codesandbox.io/s/lingering-waterfall-qr9y2?file=/src/Popper.js

Thank you, finally i understand it 馃帀 Could this information be added to library documentation? I believe that it might be beneficial for others, if there is information that arrow element should have defined size and absolute position.

I agree with @ejdzipi that it would be beneficial to add this to the docs. I started out having position: absolute; on the arrow element but removed that because I noticed that the styles.arrow also contained this style. Later on I noticed there was some misplacement going on which must have been caused by the popper being stretched by the arrow in the initial render cycle.

Alternatively, you could consider omitting position: 'absolute' from styles.arrow because that would make it much more obvious what is going wrong.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rolandjitsu picture rolandjitsu  路  5Comments

souporserious picture souporserious  路  6Comments

linusthe3rd picture linusthe3rd  路  4Comments

craigsketchley picture craigsketchley  路  3Comments

RajaBellebon picture RajaBellebon  路  3Comments