Anchor Navigation

In-page anchor links with smooth scroll and active highlight.

Inline Jump Links

A row of links to sections further down the same scroll container. Works with zero JavaScript.

Overview

Scroll target — jumping here lands right below the jump bar.

Pricing

Another scroll target.

FAQ

Last target in this scroll container.

<nav class="flex flex-wrap gap-4">
  <a href="#overview">Overview</a>
  <a href="#pricing">Pricing</a>
  <a href="#faq">FAQ</a>
</nav>

<section id="overview">...</section>
<section id="pricing">...</section>
<section id="faq">...</section>

Fixed Side Dot Nav

A dot per section, filled in when that section is active. Click a dot to jump; scroll to see it update on its own.

Section A

Scroll down — the active dot updates as each section passes the top of the frame.

Section B

Middle section.

Section C

Last section.

<nav class="fixed right-6 top-1/2 -translate-y-1/2 flex flex-col gap-3">
  <a href="#a" class="dot" :class="active === 'a' && 'dot--active'"></a>
  <a href="#b" class="dot" :class="active === 'b' && 'dot--active'"></a>
</nav>
<!-- active is set by a scroll listener comparing scrollTop to each
     section's offsetTop, same logic as the Scroll Spy example below -->

Sticky Top Anchor Bar

sticky top-0 keeps the link row pinned while its section content scrolls underneath.

Specs

Notice the bar above stays fixed while this content scrolls past it.

Reviews

Still pinned.

Shipping

Still pinned.

<nav class="sticky top-0 flex gap-4 px-4 py-3 bg-white border-b">
  <a href="#specs">Specs</a>
  <a href="#reviews">Reviews</a>
  <a href="#shipping">Shipping</a>
</nav>

Scroll Spy

The link matching the section currently in view is highlighted automatically as you scroll.

Intro

Scroll and watch "Intro" lose its highlight to "Details".

Details

Now this link is active.

Summary

Last section.

<div x-data="{ active: 'x' }" @scroll="
       const boxes = $el.querySelectorAll('[data-spy]');
       let current = active;
       boxes.forEach(b => { if ($el.scrollTop + 40 >= b.offsetTop) current = b.dataset.spy; });
       active = current;
     ">
  <a href="#x" :class="active === 'x' && 'is-active'">Intro</a>
  <div id="x" data-spy="x">...</div>
</div>

Smooth Scroll

scroll-smooth on the scroll container eases the jump instead of snapping instantly.

Top

Click "Bottom" above to see the eased scroll.

Filler so there's distance to scroll through.

Bottom

Arrived smoothly.

<div class="overflow-y-auto scroll-smooth">
  <a href="#bottom">Bottom</a>
  ...
  <div id="bottom">...</div>
</div>

Edge Cases

An empty section list and a long label both need to degrade gracefully rather than breaking the bar's layout.

Zero sections — nav renders nothing, no empty bar artifact

Long label — wraps instead of overflowing the row