Tab Links New

Links that look like Tabs. Use it to move between pages.

Standalone

<link rel="stylesheet" href="https://esm.sh/@erikt/ui/tab-links.css" />

Example

The overview page.

<nav class="tab-links" aria-label="Sections">
  <a href="/overview" aria-current="page">Overview</a>
  <a href="/activity">Activity</a>
  <a href="/settings">Settings</a>
</nav>

Usage

  • Put the links directly inside .tab-links. Use a <nav>.
  • Add aria-current="page" to the link for the current page. The highlight goes there.
  • Add an aria-label to the <nav> if the page has more than one <nav>.

View transitions

The highlight slides to the new link during a view transition.

On the same page

Move aria-current inside document.startViewTransition().

bar.addEventListener("click", (event) => {
  const link = event.target.closest("a[href]");
  if (!link || link.hasAttribute("aria-current")) return;

  event.preventDefault();

  document.startViewTransition(() => {
    for (const a of bar.querySelectorAll("a"))
      a.removeAttribute("aria-current");
    link.setAttribute("aria-current", "page");
  });
});

Between pages

Add this to the <head> of every page with the bar. It must be in the <head>, or the transition sometimes does not run.

<style>
  @view-transition {
    navigation: auto;
  }
</style>

Change the motion

/* the highlight */
::view-transition-group(.ui-tab-links) {
  animation-duration: 400ms;
  animation-timing-function: var(--ease-snap);
}

/* the labels */
::view-transition-group(.ui-tab-link),
::view-transition-old(.ui-tab-link),
::view-transition-new(.ui-tab-link) {
  animation-duration: 400ms;
}

Without view transitions

Add .morph if you update the bar without a view transition, for example with htmx morphing. The highlight still slides.

<nav class="tab-links morph">
  <a href="/overview" aria-current="page">Overview</a>
  <a href="/activity">Activity</a>
  <a href="/settings">Settings</a>
</nav>

With icons

Put an icon before the label.

<nav class="tab-links">
  <a href="/board" aria-current="page">
    <svg><!-- icon --></svg> Board</a
  >
  <a href="/table">
    <svg><!-- icon --></svg> Table</a
  >
  <a href="/chart">
    <svg><!-- icon --></svg> Chart</a
  >
</nav>

Disabled link

Add aria-disabled="true" and remove the href.

<nav class="tab-links">
  <a href="/overview" aria-current="page">Overview</a>
  <a href="/analytics">Analytics</a>
  <a aria-disabled="true">Reports</a>
</nav>

Several bars per page

Give each extra bar its own --ui-tab-links-name. Without it, only one bar animates. A .morph bar does not need a name.

<nav class="tab-links" aria-label="Folders">
  <a href="/inbox" aria-current="page">Inbox</a>
  <a href="/archive">Archive</a>
</nav>

<nav class="tab-links" aria-label="Sort" style="--ui-tab-links-name: ui-sort">
  <a href="/inbox?sort=new">Newest</a>
  <a href="/inbox?sort=old" aria-current="page">Oldest</a>
</nav>

Custom properties

Set these on the bar.

Property Default Description
--bg var(--ui-neutral-200) Background of the bar.
--bg-active var(--ui-neutral-50) Background of the highlight behind the current link.
--fg var(--ui-neutral-800) Text color of the links.
--fg-hover var(--ui-neutral-950) Text color of a link on hover.
--fg-active var(--ui-neutral-950) Text color of the current link.
--ui-tab-links-name ui-tab-links Name for the highlight. Unique per bar on a page.
.tab-links {
  --bg: var(--ui-neutral-100);
  --bg-active: var(--ui-neutral-0);
}

API reference

Type Classes / attributes What it does
State [aria-current="page"] Marks the active link and moves the highlight to it
Disabled [aria-disabled="true"] Fades the link and blocks clicks
Modifier .morph Slides the highlight with a CSS transition instead of a view transition, for DOM morphing
Transition name --ui-tab-links-name: ui-sort View transition name, unique per tab bar on a page
Track --bg: var(--ui-neutral-200) Background of the bar
Highlight --bg-active: var(--ui-neutral-50) Background of the highlight behind the active link
Text --fg: var(--ui-neutral-800) Text color of links
Hover text --fg-hover: var(--ui-neutral-950) Text color of a hovered link
Active text --fg-active: var(--ui-neutral-950) Text color of the active link

Search 5021 icons

Type a name to find icons from the Tabler icon set.

      Move Open Esc Close