Quick Tip: Fixing Initial Position and Transitions with Floating UI

Published October 4th, 2023
3 minute read

When positioning dropdowns, tooltips, or context menus with Floating UI (formerly Popper.js), transitions sometimes don't behave like you'd expect. The first time the element is positioned the transition won't originate from the right spot, or it transitions from the prior position. Turns out there's an easy fix!

What is Floating UI?

Floating UI is a JavaScript library which eases the pain of positioning floating elements. Positioning these types of components can be a deceptively hard problem! For example, what if you open a dropdown menu, then window size changes? Your menu might be overflowing the viewport and cut off as a result -- Floating UI solves these kinds of nasty problems.

The Problem with Transitions

Following the guide works great -- all until you start adding transitions. When you open a dropdown menu, it shouldn't fly in from the top left of the screen the first it gets opened. The problem becomes even more noticeable when you use Floating UI for something like a context (right click) menu. Transitions for a floating element which is positioned based on a MouseEvent will always appear to originate from where the prior event happened.

The Easy Fix

Simply use a wrapper element for positioning (only), and style the inner element for looks and transitions.

1<!-- Don't do this -->
2<div class="absolute top-0 left-0 transition dropdown-style-classes">
3 Dropdown content
4</div>
5 
6<!-- Do this instead! -->
7<div class="absolute top-0 left-0">
8 <div class="transition dropdown-style-classes">Dropdown content</div>
9</div>
1<!-- Don't do this -->
2<div class="absolute top-0 left-0 transition dropdown-style-classes">
3 Dropdown content
4</div>
5 
6<!-- Do this instead! -->
7<div class="absolute top-0 left-0">
8 <div class="transition dropdown-style-classes">Dropdown content</div>
9</div>

The outer element is the element to position with Floating UI, and the inner element should be the actual styled element. This works because the inner element is position: static by default. The position: absolute (outer) element can be repositioned by Floating UI without conflicting with other transforms or transitions.

I've ran into this before in the past and fixed it with hacks or setTimeout calls, but came across this GitHub comment tonight and it worked great for me, so I wanted to share.

Happy Coding! ✌️

Enjoy this article? Follow me on Twitter for more tips, articles and links.
😢 Awww, nobody has liked or mentioned this on Twitter yet.

Want Updates?

Sign up here if you want to stay in the loop about new articles or products I'm making.
I'll never spam you. Unsubscribe at any time.
Copyright ©2024 Austen Cameron