Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Bottom Tab Bar Navbar Block for React

A bottom tab bar for a running-diary app: five cells on shared hairlines, four links with a filled current tab and an unread dot, and a raised Shine Button that opens a drawer from the bottom with three ways to create.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

A bottom tab bar for React with Base UI, the navigation of an app you hold in one hand. It's a nav on the page's rails with five cells on shared hairlines, each meeting the top rule with a plus mark: Feed, Routes, Alerts and Profile are links with an icon over a label, the current one filled and marked by a short stroke on the rule so it isn't colour alone, and Alerts carries a dot and a spoken count until you open it. The centre cell holds a raised round Shine Button that opens a drawer from the bottom edge with a grabber and three ways to create (a post, a story or a live run) and a Cancel button. The bar is 64 pixels tall plus the home indicator's safe area, and it sits in flow here: pinning it to the bottom of a phone is one class change, described below. Its rails and top rule come from the Guides spine, so it lines up with every block above it. It's built from Drawer, Shine Button, Button and Guides, with your theme's tokens for every colour. For mobile web apps, social and tracking products, and any site whose few main destinations belong under the thumb.

FAQ

How do I pin it to the bottom of a phone?

Add fixed inset-x-0 bottom-0 z-40 md:hidden to the nav (it already paints bg-background, so the page doesn't show through), give the page pb-16 so its last content isn't hidden under the bar, and put viewport-fit=cover in your viewport meta tag so env(safe-area-inset-bottom) has a value: the bar already pads by it. In this preview it stays in flow at every width so you can see it. If your page also has a top navbar, give one of the two navs another name than Main, such as Tabs.

How do I change the tabs?

Edit FEED, ROUTES, ALERTS and PROFILE at the top of the file (an icon, an id and a label each) and UNREAD, the count Alerts starts with. The four are plain links with href="#": point them at your routes and derive the current one from your router instead of the block's current state, which only marks a tab when it's chosen. Four tabs and a centre action are as many as a 320-pixel phone holds with touch targets that big; a fifth link would need the Create cell to go.

How are the current tab and the unread dot shown?

The link for the page you're on has aria-current="page": its icon fills, its label turns foreground and medium weight, and a short foreground stroke lies on the bar's top rule. The unread dot is a small foreground circle, never a red one, and a visually hidden ", 2 unread" follows the label so a screen reader hears "Alerts, 2 unread". Opening Alerts reads them: the dot and the count go. Replace the count with your own data.

How does the Create button work?

It's a Shine Button named Create that opens a drawer from the bottom edge. The drawer has a title, a one-line description, three links (each an icon, a name and a line) and a Cancel button; Escape, Cancel, a swipe down or choosing a way closes it, and focus goes back to Create. The drawer's open state is held in the block (creating), so every way closes it. The drawer is Base UI's, with showSwipeHandle for the grabber; on React Aria it's the same Base UI drawer. The drawer's trigger renders your button with render.

Why is it a nav and not a header?

A bottom tab bar isn't the page's header, so it doesn't use the header element the other navbars do. It's a nav landmark named Main with a list of links, and the Create button sits in the list as an item of its own, outside any link.

What moves, and what about reduced motion?

Colours ease between tabs and the drawer slides up from the bottom; nothing moves on load. With reduced motion the colours change at once and the drawer appears without sliding. In right-to-left layouts the cells run from the right and the hairlines and marks follow.

  • Pro

    Icon-Only Navbar

    Cells and splits

    An icon-only navbar for a messaging app: six destinations in square cells on shared hairlines, each named by a tooltip, with unread dots and a Show labels toggle that widens the cells to reveal the words.

  • Pro

    Drill-Down Drawer Navbar

    Mobile and drawers

    A drawer navbar for a travel planner: a Menu button at every width opens a sheet from the end where Plan and Explore slide a second panel in with a Back button, with Pricing and Help centre as plain links and a Shine Button at the foot.

  • Pro

    Animated Hamburger Navbar

    Mobile and drawers

    A menu-first navbar for a ceramics studio: a wordmark, a Shine Button and a hamburger whose three lines turn into a cross, opening a full-width card of six links that ease in one after the other.

  • Pro

    Fullscreen Overlay Navbar

    Mobile and drawers

    A full-screen menu navbar for an architecture studio: a two-line menu button at every width opens a sheet that fills the screen with five large numbered links on hairline rows that fade up one after the other.

  • Pro

    Priority Plus Navbar

    Cells and splits

    A priority-plus navbar for a media-planning suite in a resizable frame: the links that fit stay on the bar and the rest drop into a More menu as you drag the frame narrower, decided by container queries.

  • Pro

    A dock pill for a workspace app: a toolbar of four icon buttons (New page, Search, Share, Notifications), each with a tooltip showing its name and its key.