Glass tab barPro

A floating Liquid Glass tab bar that refracts what scrolls beneath it, with a glass lens that glides, magnifies and can be dragged between tabs, and an optional search bubble; it compacts on scroll down.

Live · keyboard ready

Following

  • Mateo AlvarezLisbon
    A yellow tram on a street lined with historic buildings in Lisbon
  • Jordan ReyesMarrakesh
    Wavy terracotta walls rising toward a blue sky
  • Ava MitchellLos Angeles
    Curved stainless steel panels of the Walt Disney Concert Hall against a blue sky
  • Ryan SullivanAzores
    A long coastline with waves rolling onto a beach below green cliffs
  • Emma CollinsPorto
    Seared salmon with a bright herb salsa and a glass of red wine
  • Chloe NguyenEngadin
    A calm alpine lake reflecting a rocky peak at golden hour
  • Mobile web apps and PWAs with three to five top level sections and one global action such as search.
  • Content feeds where the bar should step aside while reading and come back on scroll up.
  • Desktop layouts with many sections; use a sidebar or morph-nav.
  • Switching views inside a card; use segmented-control or tabs.

Installation

Pro source and install commands unlock with a Pro plan.

example.tsx
import { GlassTabBar } from "@/registry/components/glass-tabbar/glass-tabbar";import { Bookmark, Compass, House, Search, UserRound } from "lucide-react"; export function AppShell() {  const [tab, setTab] = useState("home");  return (    <GlassTabBar      className="tabbar"      value={tab}      onValueChange={setTab}      items={[        { value: "home", label: "Home", icon: <House /> },        { value: "explore", label: "Explore", icon: <Compass /> },        { value: "saved", label: "Saved", icon: <Bookmark />, badge: 3 },        { value: "profile", label: "Profile", icon: <UserRound /> },      ]}      action={{ value: "search", label: "Search", icon: <Search /> }}    />  );}

API reference

2 parts. The first is the root.

GlassTabBar

A floating Liquid Glass tab bar. The bar refracts what scrolls under it, and the selected tab sits under a glass lens that glides, lifts, and magnifies as it moves and can be dragged across the tabs. An optional round action bubble sits beside it, and the bar shrinks to a compact pill of icons on scroll down.

PropTypeDefaultDescription
itemsRequiredGlassTabBarItem[]–Tabs with value, label, icon, and an optional badge.
valuestring–Controlled active tab. A value that matches no tab, or the action, hides the lens.
defaultValuestring–Initial active tab when uncontrolled. Defaults to the first item.
onValueChange(value: string) => void–Called when a tab or the action is chosen by tap, drag, or keyboard.
actionGlassTabBarItem–A separate round glass tab beside the bar, such as search. It takes part in selection and keyboard order like any tab.
compactboolean–Controlled compact state.
defaultCompactbooleanfalseInitial compact state when uncontrolled.
onCompactChange(compact: boolean) => void–Called when the bar shrinks or grows.
scrollRefRefObject<HTMLElement | null>–Scroll container to watch. Leave it out to watch the window.
collapseOnScrollbooleantrueShrink on scroll down and grow on scroll up.
labelstring"Tabs"Accessible name of the navigation and its tab list.
classNamestring–Extra class on the nav. Position the bar here, usually fixed or absolute at the bottom.
styleCSSProperties–Inline style on the nav.

GlassTabBarItem

One tab, or the action.

PropTypeDefaultDescription
valueRequiredstring–Unique value.
labelRequiredstring–Visible label and accessible name. The action shows only its icon and uses the label as its name.
iconRequiredReactNode–Icon at 22px; lucide icons are sized automatically.
badgenumber | string–Count shown as an accent badge on the icon. 0 or empty hides it.
Tab
Moves focus to the selected tab; the tab list is one stop.
Arrow leftorArrow right
Moves to and selects the previous or next tab, including the action, wrapping around.
HomeorEnd
Selects the first tab or the last one.
EnterorSpace
Selects the focused tab and grows the bar if it is compact.
  • Renders a nav landmark around a tablist; every tab, including the action, has role="tab" and aria-selected, with a roving tabindex.
  • Labels stay in the accessibility tree when the bar is compact, so each tab keeps its name.
  • Badges carry hidden text such as "3 new" for screen readers.
  • Selection is carried by the lens, the accent tint, and aria-selected, never by color alone.
  • Reduced transparency swaps the glass for a solid raised surface; increased contrast strengthens the tint, border, and ink.
  • No focus rings are drawn, in line with the library.
  • The lens glides on the smooth spring, which never overshoots. Its speed lifts it off the bar: it grows, stretches along the direction of travel, and turns into a clear lens that magnifies the icons under it, then settles back into a soft fill.
  • Each tab's tint and icon scale follow the lens position, so the accent glides with it instead of switching.
  • Press the selected tab and the lens lifts; drag past a few pixels and it follows the pointer across the bar; release snaps it to the nearest tab and selects it.
  • One spring drives the compact morph: slot width, bar height, icon lift, and label fade all read from it, so the lens stays on its tab mid morph.
  • Reduced motion moves the lens and the size instantly, with no lift, stretch, or magnification.
  • Tabs share the available width, from 78px down to 56px each, so five tabs and an action fit a 390px screen. Compact tabs are 50px.
  • The bar and lens take touch with pan-y, so vertical scrolling that starts on the bar still works.
  • Motion values drive every frame; React renders only on tab, compact, or size changes. Nothing animates at rest.
  • Chromium gets real refraction: an SVG displacement filter inside backdrop-filter bends the backdrop at the rim, with a slight per channel dispersion. Safari and Firefox are detected and keep a blur and saturation glass.
  • The lens refraction is a fixed layer clipped to the lens; while it moves, only the clip and the filter's map rectangle update.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use it as the primary navigation of a mobile web app. Keep it to three to five tabs with short labels, plus at most one action.
  • Pass the page's scroll container as scrollRef when the app scrolls inside an element instead of the window.
  • Place it with position fixed or absolute at the bottom; the component centers itself and only the glass takes pointer events.
  • Put photos or colorful content behind it; the material is designed to be seen over real content, not a flat page.
  • Leave content room at the bottom (about 110px) so the last item is not hidden behind the bar.

The full library index for assistants is at /llms.txt.