Skip to content

Components

Bottom Tab Bars for Web Apps — Thumbs Don't Reach the Top Left

Safe-Area Insets, 3–5 Destinations, and the Active State That Isn't Just Colour
Written by Aiden Wood Founder and Lead Design Engineer
📱 👍 🧭

Native apps settled this a decade ago: primary navigation lives at the bottom, under the thumb. Web apps somehow still bury theirs in a hamburger at the top left — the exact spot a one-handed phone grip cannot reach. If your product is used on phones like an app, navigate like an app.

Velocity X's standard-mobile-bottom-tab-bar is the web version of the pattern with the platform details already handled.

The Money Pattern

<nav aria-label="Primary"
     class="fixed inset-x-0 bottom-0 z-40 border-t border-neutral-200
            bg-white/90 backdrop-blur
            pb-[env(safe-area-inset-bottom)] md:hidden">
  <ul class="grid grid-cols-4">
    {tabs.map(t => (
      <li>
        <a href={t.href} aria-current={t.active ? 'page' : undefined}
           class="flex flex-col items-center gap-0.5 py-2 text-[11px]">
          <t.Icon class={t.active ? 'fill-current' : ''} />
          {t.label}
        </a>
      </li>
    ))}
  </ul>
</nav>

env(safe-area-inset-bottom) is the line that separates web tab bars from native-feeling ones — without it, the home indicator on modern phones overlaps your tabs. And the bar is part of the app shell: it mounts once and persists across route changes, never remounting per page (the outer shell rule).

The Catch

Three to five destinations, full stop. A sixth tab means the labels shrink past readability and the targets past tappability — that's when the fifth slot becomes "More". And every tab needs a text label; icon-only bars test terribly because your icons are not as self-evident as the design review thought.

Active state needs two signals, not one: a colour change plus a filled icon variant (or weight change), because colour alone fails colour-blind users and bright sunlight equally. aria-current="page" carries the same information to assistive tech.

Last trap: content padding. The page needs pb-20 (bar height + safe area) on its scroll container or the last list item hides behind the bar forever.

The Verdict

Bottom tabs on mobile web aren't a trend to evaluate — they're a settled answer to thumb reach. Safe-area inset, 3–5 labelled tabs, double-signal active state, persistent shell. The finished bar is in Velocity X's Standard Navigation category, source you own.

Let us make some quick suggestions?

Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.