Works natively with Cursor. Add npx -y bare-ui-mcp to your MCP settings.

Floating Nav

A sleek, auto-hiding navigation bar that floats above your content and uses backdrop-filter.

Scroll up or down on this page to see the nav bar appear and disappear!

(Make sure your window is scrollable)

Installation

1. Add the CSS to your global stylesheet:

css
/* Floating Nav */
.floating-nav { position: fixed; top: 1.5rem; left: 50%; transform: translateX(-50%); z-index: 50; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease; padding: 0.5rem; border-radius: 9999px; background: var(--glass-bg); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid var(--glass-border); box-shadow: 0 10px 30px -10px rgba(0,0,0,0.1); width: fit-content; max-width: 90vw; }
.floating-nav-visible { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.floating-nav-hidden { transform: translate(-50%, -150%); opacity: 0; pointer-events: none; }
.floating-nav-list { display: flex; gap: 0.25rem; list-style: none; margin: 0; padding: 0; align-items: center; }
.floating-nav-item { margin: 0; }
.floating-nav-link { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; border-radius: 9999px; color: var(--text-primary); text-decoration: none; font-size: 0.875rem; font-weight: 600; transition: all 0.2s ease; position: relative; }
.floating-nav-link:hover { background: var(--bg-secondary); color: var(--accent); }
.floating-nav-icon { display: flex; align-items: center; justify-content: center; width: 1.25rem; height: 1.25rem; }

2. Copy the React component into your project:

tsx
"use client";

import { ReactNode, useEffect, useState, useRef } from "react";
import { isSafeHref } from "./is-safe-href";

export interface NavItem {
  name: string;
  link: string;
  icon?: ReactNode;
}

export interface FloatingNavProps {
  navItems: NavItem[];
  className?: string;
}

/**
 * A zero-dependency, ultra-lightweight floating navigation component.
 * Hides on scroll down, shows on scroll up.
 */
export const FloatingNav = ({ navItems, className = "" }: FloatingNavProps) => {
  const [isVisible, setIsVisible] = useState(true);
  const lastScrollY = useRef(0);

  useEffect(() => {
    if (typeof window === "undefined") return;

    const handleScroll = () => {
      const currentScrollY = window.scrollY;

      // If scroll is near top, always show
      if (currentScrollY < 50) {
        setIsVisible(true);
      } else {
        // Scrolling UP
        if (currentScrollY < lastScrollY.current) {
          setIsVisible(true);
        }
        // Scrolling DOWN
        else if (currentScrollY > lastScrollY.current) {
          setIsVisible(false);
        }
      }

      lastScrollY.current = currentScrollY;
    };

    window.addEventListener("scroll", handleScroll, { passive: true });
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  return (
    <nav
      className={`floating-nav ${isVisible ? "floating-nav-visible" : "floating-nav-hidden"} ${className}`}
    >
      <ul className="floating-nav-list">
        {navItems.map((item, idx) => (
          <li key={idx} className="floating-nav-item">
            <a
              href={isSafeHref(item.link) ? item.link : "#"}
              className="floating-nav-link"
            >
              {item.icon && (
                <span className="floating-nav-icon">{item.icon}</span>
              )}
              <span className="floating-nav-text">{item.name}</span>
            </a>
          </li>
        ))}
      </ul>
    </nav>
  );
};

Usage

tsx
import { FloatingNav } from '@/components/ui/floating-nav';
import { Home, Info, Mail } from 'lucide-react';

export default function MyComponent() {
  const navItems = [
    { label: 'Home', href: '/', icon: <Home size={16} /> },
    { label: 'About', href: '/about', icon: <Info size={16} /> },
    { label: 'Contact', href: '/contact', icon: <Mail size={16} /> }
  ];

  return (
    <>
      <FloatingNav items={navItems} />
      <main>
        {/* Your content here */}
      </main>
    </>
  );
}