Skip to content

[BUG] Tooltip position and show status not synchronized. #1010

Closed

Description

@knubie

Describe the bug
When moving from one anchor to another, sometimes the tooltip's position is updated before its visibility. This results in some glitchy / flickering behavior.

Version of Package
v5.10.6

To Reproduce

  1. Set Tooltip delayShow to 300
  2. Set Tooltip delayHide to 0
  3. Move from one anchor to another (with no space between)
  4. Observe that the tooltip first changes position and content, then hides. Then after 300ms shows again.

Expected behavior
The tooltip should hide first, then update position and content.

Screenshots
https://user-images.githubusercontent.com/431251/230918927-995f1ccf-2449-40d8-8a4b-948c48605393.mp4

Desktop (please complete the following information if possible or delete this section):

  • OS: MacOS
  • Browser firefox
  • Version [e.g. 22]
  • Frameworks create-react-app

Additional context
Repro: https://github.com/knubie/react-tooltip-demo
Somewhat, but not really related: #1008

Activity

  1. gabrieljablonski commented on Apr 10, 2023

    @gabrieljablonski
    Member

    This one will be a lot trickier to solve. The root of this problem is that the tooltip content and the tooltip position are updated independently. Since the position calculation may take more than 1 render cycle to finish, and updating the content will pretty much always take exactly 1 cycle, sometimes you'll see the text updating before the position.

    We've tried to fix this by updating the content and the position on the same cycle 100% of the time, but it turned out to be not that easy.

    The tooltip closing when you move from one element to another is actually a bug, since the expected behavior when using delayShow is that the tooltip will stay open for as long as you're hovering an anchor element, not close and reopen after the delay.

    Here are some alternatives until we can tackle this on (it might take several days until we have the time):

    1. When using delayShow, also use delayHide with a small value (50 should be fine). This will mitigate the flickering, though sometimes you'll still see the text updating before the tooltip has moved.
    2. Use one tooltip for each anchor element. This is really not ideal, and we usually recommend against this, but it could work on your case if you don't have many elements (anything up to 20 tooltips on the page should be fine, maybe even more).

    If you have any other ideas, please let us know.

  2. knubie commented on Apr 10, 2023

    @knubie
    Author

    The tooltip closing when you move from one element to another is actually a bug, since the expected behavior when using delayShow is that the tooltip will stay open for as long as you're hovering an anchor element, not close and reopen after the delay.

    Ah okay. I was going to ask about this earlier. Solving that bug might be a good next step.

    1. When using delayShow, also use delayHide with a small value (50 should be fine). This will mitigate the flickering, though sometimes you'll still see the text updating before the tooltip has moved.

    This worked for me. However I noticed another issue that is kind of the opposite of the previous one: When hovering over an anchor, the tooltip's show state is updated to true first, then a frame or two later the position and content are updated. This has the effect of the tooltip showing up at it's previous position for a frame or two before moving to the correct position. However I was only able to replicate this in my own application and not the create-react-app demo.

    To resolve that I simply added the transition CSS property back in so that the tooltip is opacity: 0 for the first frame or two.

    Ideally all of the state change (show/position/content) should update synchronously. I don't have any concrete suggestions for you at the moment, though, as I'm not that familiar with the code base.

  3. github-actions commented on May 12, 2023

    @github-actions

    This issue is stale because it has not seen activity in 30 days. Remove the stale label or comment within 14 days, or it will be closed.

  4. removed
    StaleThis has not seen activity in quite some time
    on May 12, 2023
  5. dbidwell94 commented on Jun 30, 2023

    @dbidwell94

    I'm experiencing a similar issue.

    reactTooltipBug.mp4

    Looks like the position is not updated before the tooltip is shown

  6. knubie commented on Jul 1, 2023

    @knubie
    Author

    Also experiencing this on the latest version, even with the transition hack mentioned above. Haven't had time to dig into how or why it's happening, though.

  7. dbidwell94 commented on Jul 1, 2023

    @dbidwell94

    I've been digging, but I can't seem to find the problem yet.

  8. gabrieljablonski commented on Jul 1, 2023

    @gabrieljablonski
    Member

    @dbidwell94 the original issue has to do with transitioning between two adjancent anchor elements, yours seems to be a little different. I am unable to reproduce it. If you could provide a sample repo it would help a lot.

    @knubie are you experiencing the same thing? as in:

    • you hover on an element to show the tooltip
    • you hover out and the tooltip is hidden
    • you hover on another element and the tooltip is misplaced for a few frames

    Again, I haven't been able to reproduce this.

  9. knubie commented on Jul 1, 2023

    @knubie
    Author

    Just recorded a demo video from my production app. I noticed the following things:

    • On mouseout the tooltip is misplaced for a few frames.
    • On mouseenter the tooltip is misplaced for ~1 frame sometimes. This only happens once or twice in the video.

    Here are the settings for my tooltip:

    delay-show = 500
    delay-hide = 50
    transition: opacity 0.1s ease-out
    
    tooltip_bug4.mp4
  10. dbidwell94 commented on Jul 2, 2023

    @dbidwell94

    @gabrieljablonski Here are the items in question:

    React tooltip instance => https://github.com/Tekxchange/web_ui/blob/master/src/App.tsx#L26

    Go to current location data-id => https://github.com/Tekxchange/web_ui/blob/master/src/pages/app/map/index.tsx#L86
    Results bar id => https://github.com/Tekxchange/web_ui/blob/master/src/pages/app/resultsBar/index.tsx#L41

    I'm not sure it's too big of a deal. While testing I have noticed it:

    A) only seems to happen on Opera (might happen on Safari as well, I'm not sure)
    B) only happens on that browser if you are logged in
    C) Chrome and Firefox seem to be working as expected.

  11. gabrieljablonski commented on Jul 2, 2023

    @gabrieljablonski
    Member

    @dbidwell94 thanks for taking the time. We'll investigate and see what we can do.

  12. gabrieljablonski commented on Jul 2, 2023

    @gabrieljablonski
    Member

    @dbidwell94 please try the following setup:

    <ReactTooltip
      id="tooltip"
      delayShow={1000}
      positionStrategy="fixed"
      style={{ zIndex: 1000 }}
    />

    Setting opacity: 1 on the tooltip styling breaks funcionality. The correct way to set the opacity is by overriding the CSS variable like this:

    :root {
      --rt-opacity: 1;
    }

    (As a side-note, we should probably add a more straight-forward way of setting the opacity, such as an opacity prop.)

    I've also set positionStrategy="fixed" since the scrollbar was showing for a frame when the tooltip is inserted into the DOM. Please see if this works for you.


    @knubie Please confirm if you're setting opacity: 1 manually.

  13. 13 remaining items

  14. danielbarion commented on Jul 15, 2023

    @danielbarion
    Member

    @Uni2K I do have a Macbook, please create a reproducible example and I'll try to test and debug it from my side, I'll share my findings with @gabrieljablonski and we will try to fix it if possible.

  15. Uni2K commented on Jul 16, 2023

    @Uni2K

    Here is the repo: https://codesandbox.io/s/amazing-sanne-lnwmfg

    My coworker tested it with his Macbook. He could not reproduce the issue in Firefox, but he could reproduce it in Safari 16.3 on every 5-7 attempt. For now, this is the best I can provide.

  16. deleted a comment from Uni2K on Jul 17, 2023
  17. danielbarion commented on Jul 20, 2023

    @danielbarion
    Member

    I tried a lot of times but the issue only happened 1 time with me, this will be hard to debug and fix.

    I'll take a look if we can reset the Tooltip coordinates when we close it, or something like that.

  18. gabrieljablonski commented on Jul 20, 2023

    @gabrieljablonski
    Member

    @danielbarion we could try, but I'm guessing it won't work.

    my bet is on some weird CSS specification that safari doesn't follow exactly as it should. maybe something to so with how opacity transition is behaving

  19. Uni2K commented on Jul 31, 2023

    @Uni2K

    Maybe I can help with a new video, checkout the clicking:

    delayshow-bug.mov
  20. added
    V6It might get fixed/merged before, but most likely only on V6's release.
    on Aug 2, 2023
  21. lopo12123 commented on Nov 22, 2023

    @lopo12123

    Perhaps it is caused by the same reason.

    When their contents are the same, moving from an element that is set not to display tooltip to its neighbor element that displays tooltip, it will appear misaligned.

    image
    image

    When their contents are different, there will be the flickering phenomenon that others have mentioned.
    image

  22. StevenSawtelle commented on Mar 26, 2024

    @StevenSawtelle

    I was having this issue (or at least a very similar one, mine was always only flickering in the top left of the page), and this was the hacky solution I came up with to get at least something working using the afterShow/afterHide props to delay the showing until after the flickering was over, in case it helps anyone else:

    const [classNameSuffix, setClassNameSuffix] = useState('hidden');
    return <Tooltip
              id={uid}
              className={`tooltip ${classNameSuffix}`}
              delayHide={50}
              delayShow={400}
              clickable
              afterShow={() => setTimeout(() => setClassNameSuffix('visible'), 50)}
              afterHide={() => setClassNameSuffix('hidden')}
            >
              {....}
    </Tooltip>

    and then my scss is just:

    .tooltip {
      &.hidden{
        visibility: hidden;
      }
    
      &.visible{
        visibility: visible;
      }
    }
  23. VladimirGK8 commented on Jan 13, 2025

    @VladimirGK8

    I realized I had a flickering issue when I overrode the opacity with opacity: 1 !important for the .react-tooltip CSS class.
    The next suggestion helped me:
    :root { --rt-opacity: 1; }

  24. xfeeefeee commented on Jul 14, 2025

    @xfeeefeee

    After some frustrating debugging, I realized I was having this issue when the arrow was disabled, which then led me to this:

      return computePosition(elementReference as HTMLElement, tooltipReference as HTMLElement, {
        placement: 'bottom',
    

    not sure why it is always passing 'bottom' here, when if using an arrow it passes placement: place as expected. Changing this to use placement: place as well seems to have resolved it for me, at least in this situation. On other tooltips that do use the arrow, I still occasionally see the strange old position issue but much less so after increasing the --rt-transition-show-delay

  25. jaykobo commented on Aug 12, 2025

    @jaykobo

    Not topic related but belonging to

    I realized I had a flickering issue when I overrode the opacity with opacity: 1 !important for the .react-tooltip CSS class. The next suggestion helped me: :root { --rt-opacity: 1; }

    👀 See this: https://react-tooltip.com/docs/examples/styling#changing-the-opacity.

    I had some similar flickering behavior, which was caused by opacity changes from css.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugHelp WantedV6It might get fixed/merged before, but most likely only on V6's release.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions