Bottom Navigation

Mobile navigation at bottom of screen.

html

<nav class="bottomnav bottomnav--labeled" style="--accent:#A8E6C1;" aria-label="Mobile">
  <a class="bottomnav__item is-active" href="#" aria-current="page">
    <span class="bottomnav__icon bottomnav__icon--home" aria-hidden="true"></span>
    <span class="bottomnav__label">Home</span>
  </a>
  <a class="bottomnav__item" href="#">
    <span class="bottomnav__icon bottomnav__icon--search" aria-hidden="true"></span>
    <span class="bottomnav__label">Search</span>
  </a>
  <a class="bottomnav__item" href="#">
    <span class="bottomnav__icon bottomnav__icon--alerts" aria-hidden="true"><span class="bottomnav__badge"></span></span>
    <span class="bottomnav__label">Alerts</span>
  </a>
  <a class="bottomnav__item" href="#">
    <span class="bottomnav__icon bottomnav__icon--profile" aria-hidden="true"></span>
    <span class="bottomnav__label">Profile</span>
  </a>
</nav>
<style>
.bottomnav { display: flex; justify-content: space-around; align-items: center; background: #FAF7F2; padding: 8px 4px; border-radius: 16px; width: 320px; font: 500 11px system-ui, sans-serif; }
.bottomnav__item { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; color: #241430; opacity: .55; text-decoration: none; padding: 4px 10px; border-radius: 10px; }
.bottomnav__item.is-active { opacity: 1; color: var(--accent); }
.bottomnav__item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; opacity: 1; }
.bottomnav__icon { position: relative; width: 18px; height: 18px; border: 2px solid currentColor; border-radius: 5px; }
.bottomnav__icon--home { border-radius: 50% 50% 5px 5px; }
.bottomnav__icon--search { border-radius: 50%; }
.bottomnav__badge { position: absolute; top: -3px; right: -3px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); border: 2px solid #FAF7F2; }
.bottomnav--icon-only .bottomnav__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
</style>

tailwind

<nav aria-label="Mobile" class="bottomnav-tw bottomnav-tw--labeled flex justify-around items-center bg-[#FAF7F2] px-1 py-2 rounded-2xl w-80 font-medium text-[11px]" style="--accent:#A8E6C1;">
  <a class="flex flex-col items-center gap-1 px-2.5 py-1 rounded-lg no-underline" href="#" aria-current="page" style="color:#A8E6C1;">
    <span class="w-[18px] h-[18px] border-2 rounded-t-full rounded-b-md" aria-hidden="true"></span>
    <span class="bottomnav-tw__label">Home</span>
  </a>
  <a class="flex flex-col items-center gap-1 px-2.5 py-1 rounded-lg text-[#241430]/55 no-underline" href="#">
    <span class="w-[18px] h-[18px] border-2 rounded-full" aria-hidden="true"></span>
    <span class="bottomnav-tw__label">Search</span>
  </a>
  <a class="relative flex flex-col items-center gap-1 px-2.5 py-1 rounded-lg text-[#241430]/55 no-underline" href="#">
    <span class="relative w-[18px] h-[18px] border-2 rounded-md" aria-hidden="true"><span class="absolute -top-1 -right-1 w-1.5 h-1.5 rounded-full border-2 border-[#FAF7F2]" style="background:#A8E6C1;"></span></span>
    <span class="bottomnav-tw__label">Alerts</span>
  </a>
  <a class="flex flex-col items-center gap-1 px-2.5 py-1 rounded-lg text-[#241430]/55 no-underline" href="#">
    <span class="w-[18px] h-[18px] border-2 rounded-md" aria-hidden="true"></span>
    <span class="bottomnav-tw__label">Profile</span>
  </a>
</nav>
<style>
.bottomnav-tw a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bottomnav-tw--icon-only .bottomnav-tw__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
</style>

react

export function BottomNavigation({
  activeLabel = "Home",
  accent = "#A8E6C1",
  style = "labeled",
  badge = true,
}) {
  const iconOnly = style === "icon-only";
  const labelStyle = iconOnly
    ? { position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0,0,0,0)", whiteSpace: "nowrap" }
    : {};
  const items = [
    { label: activeLabel, active: true },
    { label: "Search" },
    { label: "Alerts", badge },
    { label: "Profile" },
  ];
  return (
    <nav aria-label="Mobile" style={{ display: "flex", justifyContent: "space-around", alignItems: "center", background: "#FAF7F2", padding: "8px 4px", borderRadius: 16, width: 320, fontFamily: "system-ui, sans-serif", fontSize: 11, fontWeight: 500 }}>
      {items.map((item) => (
        <a key={item.label} href="#" aria-current={item.active ? "page" : undefined} style={{ position: "relative", display: "flex", flexDirection: "column", alignItems: "center", gap: 4, padding: "4px 10px", borderRadius: 10, textDecoration: "none", color: item.active ? accent : "#241430", opacity: item.active ? 1 : .55 }}>
          <span style={{ position: "relative", width: 18, height: 18, border: "2px solid currentColor", borderRadius: 5 }}>
            {item.badge && <span style={{ position: "absolute", top: -3, right: -3, width: 7, height: 7, borderRadius: "50%", background: accent, border: "2px solid #FAF7F2" }} />}
          </span>
          <span style={labelStyle}>{item.label}</span>
        </a>
      ))}
    </nav>
  );
}