Rreact.wiki
Open-Source Projects

Floating UI — A battle-tested, accessible positioning engine for tooltips, popovers, dropdowns, and other floating elements

React Library6/21/2026dropdownhacktoberfestpopoverpopoverspositionpositioningpositioning-enginetooltip
floating-ui

floating-ui/floating-ui

33kTypeScriptMIT
dropdownhacktoberfestpopoverpopoverspositionpositioningpositioning-enginetooltiptooltip-position

Floating UI is a lightweight, TypeScript-first library that solves the notoriously hard problem of correctly positioning and interacting with floating UI elements—while guaranteeing visibility, accessibility, and cross-platform flexibility.

Floating UI (formerly Popper.js) is the de facto standard positioning engine for modern front-end applications—and for good reason. With 32,625 GitHub stars, an MIT license, and deep roots in production-grade UI libraries (including Material UI, Chakra UI, Radix UI, and Mantine), it’s not just popular—it’s trusted. For React developers building anything that floats—a tooltip on hover, a context menu on right-click, a combobox dropdown, or a mobile-friendly bottom sheet—Floating UI removes the guesswork, edge-case fatigue, and accessibility debt that usually comes with position: absolute.

The Pain It Solves

Positioning floating elements seems simple until you confront reality:

  • A tooltip anchored to a button disappears when scrolled into a clipped container.
  • A popover renders off-screen near the viewport edge and isn’t repositioned automatically.
  • Keyboard navigation (e.g., Tab, Esc, ArrowDown) isn’t wired up consistently across devices or screen readers.
  • You end up writing fragile getBoundingClientRect() logic, manual collision detection, or brittle useEffect-based repositioning—and still fail WCAG 2.1 success criteria like “Focus Visible” or “Keyboard Trap”.

Floating UI abstracts all of this into a composable, platform-agnostic core—and then layers on React-specific primitives that handle both geometry and interaction out of the box.

Key Features That Matter to React Developers

Smart, adaptive positioning: Uses a pluggable algorithm (computePosition) that auto-flips, shifts, resizes, and repositions based on available space—no manual if (x > window.innerWidth) checks.
Built-in accessibility hooks: useClick, useHover, useDismiss, useRole, useFocus, and useInteractions collectively handle keyboard navigation, focus management, click-outside dismissal, and ARIA attributes (e.g., aria-expanded, role="tooltip").
Zero-runtime bundle size optimization: Choose @floating-ui/react-dom (~2.4 KB gzipped) for positioning-only needs—or @floating-ui/react (~4.8 KB) for full interactivity. Both are tree-shakable and ESM-first.
Cross-platform extensibility: Core logic lives in @floating-ui/core, enabling custom platforms (e.g., Canvas, React Native, or even SSR-rendered static tooltips).
Visual, snapshot-based testing: Every positioning behavior—including nested scrolling, RTL layouts, zoom levels, and dynamic resizing—is verified via Playwright screenshots in their dev playground—giving you confidence before shipping.

Typical Usage: A Fully Accessible Tooltip in <20 Lines

Here’s how you’d build a production-ready tooltip using @floating-ui/react:

TSX
import { useState, useRef, useMemo } from 'react';
import {
  useFloating,
  useClick,
  useHover,
  useDismiss,
  useRole,
  useInteractions,
  FloatingPortal,
  arrow,
  offset,
  flip,
  shift,
} from '@floating-ui/react';
 
function Tooltip({ children, label }: { children: React.ReactNode; label: string }) {
  const [isOpen, setIsOpen] = useState(false);
  const arrowRef = useRef<SVGSVGElement>(null);
 
  const { x, y, strategy, refs, context, middlewareData } = useFloating({
    open: isOpen,
    onOpenChange: setIsOpen,
    middleware: [
      offset(4),
      flip(),
      shift(),
      arrow({ element: arrowRef }),
    ],
  });
 
  const click = useClick(context);
  const hover = useHover(context, { move: false, delay: { open: 500 } });
  const dismiss = useDismiss(context);
  const role = useRole(context, { role: 'tooltip' });
 
  const { getReferenceProps, getFloatingProps, getArrowProps } = useInteractions([
    click,
    hover,
    dismiss,
    role,
  ]);
 
  return (
    <>
      <div ref={refs.setReference} {...getReferenceProps()}>
        {children}
      </div>
      <FloatingPortal>
        {isOpen && (
          <div
            ref={refs.setFloating}
            style={{
              position: strategy,
              top: y ?? 0,
              left: x ?? 0,
              zIndex: 9999,
            }}
            {...getFloatingProps()}
          >
            <div className="bg-gray-900 text-white text-sm rounded px-2 py-1">
              {label}
              <div
                ref={arrowRef}
                style={{
                  position: 'absolute',
                  left: middlewareData.arrow?.x ?? 0,
                  top: middlewareData.arrow?.y ?? 0,
                }}
                {...getArrowProps()}
              >
                <svg width="8" height="4" viewBox="0 0 8 4">
                  <path d="M0 0L4 4L8 0" fill="currentColor" />
                </svg>
              </div>
            </div>
          </div>
        )}
      </FloatingPortal>
    </>
  );
}
 
// Usage
function App() {
  return (
    <Tooltip label="This is an accessible, keyboard-navigable tooltip">
      <button>Hover or focus me</button>
    </Tooltip>
  );
}

This example handles hover and focus-triggered display, automatic repositioning on scroll/resize, arrow alignment, dismiss-on-escape/click-outside, and proper ARIA semantics—all without external dependencies or custom event listeners.

Who It’s For

  • React library authors who need a reliable, tested foundation for floating components (dropdowns, menus, selects).
  • Product teams shipping design systems, where consistency, accessibility compliance, and visual reliability are non-negotiable.
  • Senior front-end engineers tired of maintaining homegrown positioning logic—and ready to adopt a mature, community-vetted solution.

Floating UI doesn’t ship pre-styled components. It ships primitives—so you retain full control over styling, animation, and behavior while delegating the hardest parts: geometry, accessibility, and ergonomics. And with its monorepo architecture, TypeScript-first APIs, and active maintenance (last push: 2026-06-10), it’s built not just to work—but to scale alongside your application’s complexity.