# React Bottom Navigation Bar: Safe Areas und Badges

> React Bottom Navigation Bar in Next.js: 3 bis 5 Tabs, Safe Areas, Badges, die Screenreader vorlesen, Ausblenden beim Scrollen und wann die Sidebar besser passt.

- Autor: [Serban Rusu](https://wingo-ui.com/blog/authors/serban), Founder of Wingo UI
- Veröffentlicht: 9. Okt. 2026
- Kategorie: [Mobile UI mit React](https://wingo-ui.com/de/blog/category/mobile-ui)
- Lesezeit: 9 Min.
- Kanonische URL: https://wingo-ui.com/de/blog/react-bottom-navigation-bar
- Englische Fassung: https://wingo-ui.com/blog/react-bottom-navigation-bar

## Kurz gesagt

Eine React Bottom Navigation Bar ist eine fixierte Navigation mit 3 bis 5 Links am unteren Bildschirmrand: aria-current="page" am aktiven Link, Padding für env(safe-area-inset-bottom) unter viewport-fit=cover und unten auf der Seite ein Padding in der Höhe der Leiste, damit die letzte Zeile sichtbar bleibt. Lass die Labels sichtbar, pack Badge-Zahlen in den zugänglichen Namen jedes Links und blende die Leiste beim Scrollen nur aus, wenn sie dem Finger folgt und beim Hochscrollen zurückkommt. Nutz sie unter 768px, darüber eine Sidebar, und bei mehr als fünf Zielen kommen die vier meistgenutzten in die Leiste und der Rest in einen Drawer.

Eine React Bottom Navigation Bar ist die Tab-Leiste, an die uns native Apps gewöhnt haben: drei bis fünf Ziele am unteren Rand, genau dort, wo der Daumen ohnehin ist. Im Web reicht dafür kein fixiertes `<div>` mit Icons. Die Leiste muss Abstand zum Home-Indikator des iPhones halten, die letzte Zeile der Seite sichtbar lassen, einem Screenreader sagen, dass im Posteingang 4 ungelesene Nachrichten liegen, dem Router folgen und klären, was ein großer Button in der Mitte und ein langer Scroll tun sollen. Dieser Guide geht jeden Punkt mit der [Bottom Tab Bar](https://wingo-ui.com/components/bottom-tab-bar) von Wingo UI durch und zeigt dann, wann eine [Sidebar](https://wingo-ui.com/components/sidebar) die bessere Wahl ist.

## Wann braucht eine Web-App eine Bottom Navigation Bar?

Wenn Leute sie auf dem Smartphone nutzen und pro Sitzung oft zwischen drei und fünf Hauptbereichen wechseln. Die [Android-Richtlinien zur Navigation Bar](https://developer.android.com/develop/ui/compose/components/navigation-bar) nennen die Bedingungen: drei bis fünf gleich wichtige Ziele, kompakte Fenstergrößen und dieselben Ziele auf allen Screens der App. Ein CRM mit Start, Kunden, Posteingang und Profil passt. Eine Marketing-Website, eine Doku-Seite oder ein Checkout passt nicht, weil dort niemand zwischen den Bereichen hin und her springt.

Der untere Rand ist der Grund für den Aufwand. In Steven Hoobers [Feldstudie von 2013](https://www.uxmatters.com/mt/archives/2013/02/how-do-users-really-hold-mobile-devices.php) (1.333 Beobachtungen von Menschen an mobilen Geräten) hielten 49 % derjenigen, die den Bildschirm berührten, das Smartphone in einer Hand. Ein Hamburger-Menü oben in der Ecke liegt weit weg von diesem Daumen und versteckt jedes Ziel hinter einem zusätzlichen Tipp. In einer Web-App mit Bottom Tab Bar bleibt jedes Ziel sichtbar und einen Tipp entfernt, und der aktive Tab zeigt, wo man gerade ist.

## Was braucht eine Bottom Tab Bar im Browser?

Fünf Aufgaben, die eine native Tab Bar von der Plattform geschenkt bekommt und die eine Webseite selbst erledigen muss:

| Thema | Was zu tun ist | In der Bottom Tab Bar |
| --- | --- | --- |
| Semantik | Ein `<nav>` aus Links, `aria-current="page"` am aktiven Link | `aria-label="Primary"`; Tabs ohne `href` werden als Buttons gerendert |
| Routing | Der aktive Tab folgt der URL, verschachtelte Routen eingeschlossen | `currentPath` wählt das längste passende `href`; `linkComponent` nimmt `next/link` |
| Home-Indikator | `viewport-fit=cover`, dann innen mit `env(safe-area-inset-bottom)` auffüllen | `safeArea`, standardmäßig an |
| Verdeckter Inhalt | Die Seite um die echte Höhe der Leiste auffüllen | Schreibt `--bottom-bar-offset` auf `<html>` |
| Touch | Tippflächen ab 44px | Jeder Tab füllt seinen Platz, 56 oder 64px hoch |

Bau die Tabs aus Links. Das [ARIA-Tabs-Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/) beschreibt übereinanderliegende Inhaltsbereiche, die Tab-Panels, von denen immer nur einer sichtbar ist. Eine Tab-Leiste lädt dagegen eine andere Seite, also würde `role="tablist"` ein Widget ankündigen, das es gar nicht gibt.

Hier ist eine React Mobile Bottom Navigation für den Next.js App Router, verteilt auf zwei Dateien:

```tsx
// app/(app)/mobile-nav.tsx
"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";
import { House, Inbox, Plus, UserRound, Users } from "lucide-react";
import { BottomTabBar, type BottomTabBarItem } from "@/components/ui/bottom-tab-bar";

const tabs: BottomTabBarItem[] = [
  { label: "Start", href: "/", icon: <House />, activeIcon: <House className="fill-current/20" /> },
  { label: "Kunden", href: "/clients", icon: <Users />, activeIcon: <Users className="fill-current/20" /> },
  { label: "Posteingang", href: "/inbox", icon: <Inbox />, badge: 4 },
  { label: "Profil", href: "/profile", icon: <UserRound />, dot: true },
];

export function MobileNav() {
  return (
    <BottomTabBar
      className="md:hidden"
      items={tabs}
      currentPath={usePathname()}
      linkComponent={Link}
      action={{ label: "Neuer Kunde", icon: <Plus />, href: "/clients/new" }}
    />
  );
}
```

```tsx
// app/(app)/layout.tsx
import type { ReactNode } from "react";
import type { Viewport } from "next";
import { MobileNav } from "./mobile-nav";

// ohne cover hält iOS die Seite in der Safe Area, und env() liefert 0
export const viewport: Viewport = { width: "device-width", initialScale: 1, viewportFit: "cover" };

export default function AppLayout({ children }: { children: ReactNode }) {
  return (
    <>
      <main className="pb-(--bottom-bar-offset)">{children}</main>
      <MobileNav />
    </>
  );
}
```

Die Leiste ist am Viewport fixiert und misst sich selbst, Safe Area eingeschlossen. Das Padding auf `<main>` stimmt also immer. Auf dem Desktop, wo `md:hidden` sie ausblendet, misst sie 0. Ein geschätztes `pb-16` ist falsch, sobald sich das Inset oder die Größe ändert. Der [Guide zu Safe Areas](https://wingo-ui.com/de/blog/tailwind-safe-area-insets) erklärt das CSS dahinter. Render die Leiste im Server-HTML und blende sie per CSS aus. Entscheidest du das mit einem `useIsMobile()`-Hook, rendert der Server nichts, und die Leiste springt erst nach der Hydration ins Bild, wie der [Guide zum useMobile-Hook](https://wingo-ui.com/de/blog/react-use-mobile-hook-ssr) zeigt.

> Live-Demo (Bottom Tab Bar): Tippe auf Clients, öffne einen Kunden und tippe dann noch einmal auf Clients: Der Tab springt zurück zu seiner Liste, ein weiterer Tipp scrollt nach oben. Der erhöhte Add-Button öffnet ein Sheet, statt den Tab zu wechseln. Probier sie unter [Bottom Tab Bar](https://wingo-ui.com/components/bottom-tab-bar) aus und installier sie mit `npx wingo-ui@latest add bottom-tab-bar`.

## Wie sollten Badges und Labels in der Tab-Leiste funktionieren?

Eine Zahl für Dinge, die eine Aktion verlangen, ein Punkt für etwas Neues, und beides wird als Teil des Tab-Namens vorgelesen. `badge: 4` rendert eine Zahl (über 99 steht 99+), `dot: true` einen 8px großen Punkt, standardmäßig rot (`badgeTone="danger"`), weil man eine rote Zahl als ungelesen versteht. Das sichtbare Badge ist `aria-hidden`, und der Link heißt dann „Posteingang, 4 ungelesen“ (`badgeLabel`) oder „Profil, neu“ (`dotLabel`). So liest ein Screenreader nie eine zusammenhanglose Zahl vor. Apples [Richtlinien zu Tab Bars](https://developer.apple.com/design/human-interface-guidelines/tab-bars) (aktualisiert im Juni 2026) raten, Badges für wirklich wichtige Informationen aufzuheben, damit sie ihre Wirkung und Bedeutung nicht verlieren: ungelesene Nachrichten und offene Freigaben, kein neues Feature.

Bleib bei `showLabels="always"`. Dieselben Richtlinien empfehlen Labels an den Tabs, weil sie die Navigation erleichtern, und nach Möglichkeit einzelne Wörter. `"active"` und `"never"` gibt es für Consumer-Apps mit vielen Icons. Mit `"never"` bleiben die Labels für Screenreader im DOM und werden zu `title`-Tooltips. `activeIcon` tauscht das Icon aus, solange der Tab aktiv ist, etwa gegen eine gefüllte Version des Outline-Icons. Apple geht noch weiter und empfiehlt auf jedem Tab gefüllte Symbole oder Icons, passend zur Plattform.

## Sollte der Button in der Mitte ein Tab, eine Aktion oder ein FAB sein?

Eine Aktion, nie ein Tab, und nur dann, wenn eine einzige Aktion zum Anlegen die App dominiert. Apple ist hier streng: Eine Tab Bar soll der Navigation dienen und keine Aktionen anbieten. Wir liefern den erhöhten Button in der Mitte trotzdem, denn in einer App, die um ein einziges Verb herum gebaut ist (Posten, Verkaufen, Scannen), hat sich dieses Verb den am besten erreichbaren Platz verdient. Die Prop `action` rendert ihn in der Mitte (bei vier Tabs: zwei, die Aktion, zwei), gefüllt mit dem `tone` und benannt über sein `label`. Er bekommt nie die Markierung des aktiven Tabs, damit ihn niemand mit der aktuellen Position verwechselt.

Lässt sich in der App mehreres anlegen, oder folgst du Apples Regel, dann überlass die Leiste der Navigation und nimm einen [FAB](https://wingo-ui.com/components/fab). Er liest `--bottom-bar-offset` und schwebt damit 16px über der Tab-Leiste und dem Home-Indikator, ohne das Inset doppelt zu zählen:

```tsx
import { FileText, UserPlus } from "lucide-react";
import { Fab, type FabAction } from "@/components/ui/fab";

const actions: FabAction[] = [
  { id: "client", label: "Neuer Kunde", icon: <UserPlus />, href: "/clients/new" },
  { id: "invoice", label: "Neue Rechnung", icon: <FileText />, href: "/invoices/new" },
];

export function CreateFab() {
  return <Fab className="md:hidden" label="Hinzufügen" actions={actions} />;
}
```

> Live-Demo (FAB): Tippe auf Add: Die Seite wird abgedunkelt, und die Aktionen zum Anlegen steigen aus dem Button auf. Scroll die Liste, und das Label klappt zum Plus ein. Probier sie unter [FAB](https://wingo-ui.com/components/fab) aus und installier sie mit `npx wingo-ui@latest add fab`.

## Sollte sich eine Bottom Navigation Bar beim Scrollen ausblenden?

Nur in langen Feeds und auf Lese-Screens, und nur, wenn sie genau dann zurückkommt, wenn man sie brauchen könnte. Apple warnt, dass Leute bei ausgeblendeter Tab Bar vergessen können, in welchem Bereich der App sie sind. Die iOS-Richtlinien beschreiben, wie eine Tab Bar mit Zubehör, etwa dem MiniPlayer in der Musik-App, beim Runterscrollen schrumpft. Ein Tipp auf einen Tab oder Scrollen nach oben holt sie zurück.

Wenn du sie ausblendest, zeigt `hideOnScroll` das Verhalten, das du übernehmen solltest:

- **Sie folgt dem Finger.** Die Leiste bewegt sich Pixel für Pixel mit dem Scroll, bis sie ihre eigene Höhe plus Safe Area zurückgelegt hat, und rastet auf sichtbar oder ausgeblendet ein, sobald das Scrollen aufhört. Ein Boolean, der je nach Richtung umschaltet, lässt die Leiste schon bei 2px Scroll springen.
- **Sie kommt zurück** beim Hochscrollen, ganz oben, am Ende des Inhalts und immer dann, wenn der Tastaturfokus in ihr liegt.
- **Sie bewegt sich nur per Transform.** Der Fortschritt liegt in einem Motion Value, also rendert Scrollen weder die Leiste noch die Seite neu. Eine Version, die im Scroll-Handler `setState` aufruft, rendert bei jedem Scroll-Event.
- **Mit Reduced Motion** gleitet die Leiste nicht, sondern wechselt direkt, nachdem eine volle Leistenhöhe gescrollt wurde.

> Live-Demo (Bottom Tab Bar): Scroll die Seite: Die schwebende Leiste folgt deinem Finger aus dem Bild und kommt zurück, sobald du nach oben scrollst. Probier sie unter [Bottom Tab Bar](https://wingo-ui.com/components/bottom-tab-bar) aus und installier sie mit `npx wingo-ui@latest add bottom-tab-bar`.

## Wann ist eine Sidebar die bessere Wahl?

Wenn es mehr als fünf Hauptziele gibt, wenn sie verschachtelt sind oder wenn die meisten Sitzungen am Laptop stattfinden. Apple schlägt für Apps mit komplexer Informationsstruktur eine Sidebar vor, oder eine Tab Bar, die sich in eine Sidebar verwandelt, und rät von Overflow-Tabs ab. Android empfiehlt die Leiste für kompakte Fenster.

| Deine App | Auf dem Smartphone | Ab 768px |
| --- | --- | --- |
| 3 bis 5 Bereiche, täglich auf dem Smartphone genutzt | Bottom Tab Bar | Sidebar oder Navigation oben |
| 6 oder mehr Bereiche oder verschachtelte Bereiche | Die 4 meistgenutzten in der Leiste, alles im Drawer | Sidebar |
| Admin-Tool, meist am Schreibtisch genutzt | Drawer, Tab-Leiste optional | Sidebar mit Icon-Rail |
| Content- oder Doku-Seite | Leiste oben und ein Menü | Navigation oben |

Die meisten Apps brauchen beides. Darum rendert die [App Shell](https://wingo-ui.com/components/app-shell) ab 768px die Sidebar neben der Seite und darunter dieselbe Sidebar in einem Drawer plus eine Tab-Leiste für die täglichen Ziele:

```tsx
// app/(app)/layout.tsx mit der App Shell
import type { ReactNode } from "react";
import { AppShell } from "@/components/ui/app-shell";
import { Sidebar } from "@/components/ui/sidebar";
import { Topbar } from "@/components/ui/topbar";
import { nav, tabs } from "./nav";

export default function AppLayout({ children }: { children: ReactNode }) {
  return (
    <AppShell sidebar={<Sidebar groups={nav} filter />} topbar={<Topbar title="Summit CRM" />} tabs={tabs}>
      {children}
    </AppShell>
  );
}
```

`nav` enthält jedes Ziel in Gruppen, `tabs` die vier, die Leute jeden Tag öffnen. Die Shell rendert die Tab-Leiste selbst und liest die Route aus einem `LinkProvider` (`component={Link}`, `currentPath={usePathname()}`), den du einmal in einem Client-Provider setzt. Das [Next.js Admin-Dashboard-Tutorial](https://wingo-ui.com/de/blog/nextjs-admin-dashboard-tutorial) baut diesen Provider und das ganze Layout. Die [Admin Shell](https://wingo-ui.com/components/admin-shell) ergänzt einen Mehr-Tab, der den Drawer öffnet.

Falls du eine shadcn Bottom Navigation gesucht hast: Stand Oktober 2026 enthält die [Komponentenliste](https://ui.shadcn.com/docs/components) von shadcn/ui keine, und die [Sidebar](https://github.com/shadcn-ui/ui/blob/main/apps/v4/registry/new-york-v4/ui/sidebar.tsx) wird unter 768px zu einem 18rem breiten Sheet, zwei Tipps von jedem Ziel entfernt. Die [Bottom Navigation](https://mui.com/material-ui/react-bottom-navigation/) von Material UI ist eine solide React-Komponente für die untere Navigation und die bessere Wahl, wenn deine App schon auf Material UI läuft. Stand Oktober 2026 deckt ihre Doku Labels, feste Positionierung und Router-Links ab und überlässt dir Badges, Safe Areas und das Ausblenden beim Scrollen.

## Was macht eine Bottom Navigation Bar in Produktion kaputt?

- **Start ist auf jeder Seite aktiv.** Ein selbst geschriebenes `pathname.startsWith(href)` trifft `/` überall. Die Leiste prüft `/` nur exakt und nimmt das längste passende `href`, so bleibt bei `/clients/northwind-tech` der Tab Kunden aktiv.
- **Ein Tipp auf den aktiven Tab tut nichts.** Leute erwarten, dass er nach oben scrollt oder zum ersten Screen des Tabs zurückgeht. `scrollToTopOnReselect` macht beides, und `onReselect` kann einen Feed neu laden.
- **Ein sechster Tab.** Bei mehr als fünf Einträgen warnt die Leiste im Development-Modus. Verschieb den Rest in einen Mehr-Tab oder den Drawer.
- **Safaris schwebende Toolbar.** Seit iOS 26 schwebt Safaris Toolbar im Tab-Layout Compact über dem unteren Teil der Seite, und laut einem [Forenbeitrag vom September 2025](https://developer.apple.com/forums/thread/800798) rendert Safari fixierte Inhalte nicht unterhalb dieser Bedienelemente. Teste auf einem echten iPhone in den Tab-Layouts Compact, Bottom und Top.
- **Zwei Leisten, zwei Insets.** Eine Kaufleiste über der Tab-Leiste darf den Home-Indikator nicht noch einmal auffüllen. Der Guide zu [Mobile-first React-Komponenten](https://wingo-ui.com/de/blog/mobile-first-react-components) zeigt, wie man die Leisten stapelt.

## Was solltest du installieren?

`npx wingo-ui@latest add bottom-tab-bar` kopiert die Komponente nach `components/ui/`, zusammen mit dem Badge, den Helfern für Navigation und Motion und den Scroll-Hooks, die sie importiert. Bottom Tab Bar, FAB, Sidebar und App Shell gehören zu [Wingo UI Pro](https://wingo-ui.com/de/pricing), das Badge ist kostenlos. Der [Guide zum React Floating Action Button](https://wingo-ui.com/de/blog/react-floating-action-button) behandelt den FAB, der über der Tab-Leiste sitzt. Weitere Guides wie diesen findest du unter [Mobile UI in React](https://wingo-ui.com/de/blog/category/mobile-ui).

## Komponenten in diesem Artikel

- [Bottom Tab Bar](https://wingo-ui.com/components/bottom-tab-bar) (Pro): A React bottom tab bar for phones: 3 to 5 tabs at the thumb with an animated pill, badges, a raised center action and hide on scroll. Installation: `npx wingo-ui@latest add bottom-tab-bar`
- [FAB](https://wingo-ui.com/components/fab) (Pro): A React floating action button (FAB) for a phone screen's main action, with a labeled or radial speed dial and a label that folds on scroll. Installation: `npx wingo-ui@latest add fab`
- [Sidebar](https://wingo-ui.com/components/sidebar) (Pro): A React sidebar for admin apps: grouped links with icons, nested sections, badges, a sliding active pill, an icon rail and a filter. Installation: `npx wingo-ui@latest add sidebar`
- [App Shell](https://wingo-ui.com/components/app-shell) (Pro): A React app shell for admin layouts: a collapsible, resizable sidebar, a top bar and the page, with a drawer and a tab bar on phones. Installation: `npx wingo-ui@latest add app-shell`

## Häufige Fragen

### Wie viele Einträge sollte eine Bottom Navigation Bar haben?

Drei bis fünf. Die Android-Richtlinien nennen drei bis fünf gleich wichtige Ziele, und Apples Richtlinien zur Tab Bar raten von Overflow-Tabs ab. Gibt es mehr Bereiche, kommen die vier meistgenutzten in die Leiste und alle zusammen in einen Drawer oder eine Sidebar.

### Hat shadcn/ui eine Bottom Navigation?

Stand Oktober 2026 nicht: Die Komponentenliste enthält weder eine Bottom Navigation noch eine Tab Bar, und die Sidebar wird unter 768px zu einem 18rem breiten Sheet. Die Bottom Tab Bar von Wingo UI, eine Pro-Komponente, installierst du genauso als Quellcode in dein Projekt, mit npx wingo-ui@latest add bottom-tab-bar.

### Sollte eine Bottom Navigation Bar role="tablist" verwenden?

Nein. Das ARIA-Tabs-Pattern ist für Panels gedacht, die innerhalb einer Seite wechseln. Eine Leiste, die die Seite wechselt, ist Navigation: ein nav-Element mit Links und aria-current="page" am aktiven Link.

### Sollte sich eine Bottom Navigation Bar beim Scrollen ausblenden?

Nur in langen Feeds und auf Lese-Screens, denn eine ausgeblendete Leiste verbirgt auch, wo man sich in der App befindet. Wenn sie sich ausblendet, sollte sie dem Finger folgen, sich nur per Transform bewegen und zurückkommen: beim Hochscrollen, ganz oben, am Ende der Seite und solange der Tastaturfokus in ihr liegt.

### Ist die Bottom Tab Bar von Wingo UI kostenlos?

Nein. Die Bottom Tab Bar von Wingo UI ist eine Pro-Komponente, genau wie FAB, Sidebar und App Shell. Das Badge, das sie für Zahlen nutzt, ist kostenlos.

---

Quelle: https://wingo-ui.com/de/blog/react-bottom-navigation-bar
