# Smooth Scroll for Anchors

**SHOULD** · **ID:** `animations-smooth-scroll-anchors` · **Category:** animations
**Source:** [Rauno](https://interfaces.rauno.me/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/animations-smooth-scroll-anchors

> SHOULD: Use `scroll-behavior: smooth` for in-page anchors, with `scroll-margin-top` on targets so headings clear any sticky header.

Use scroll-behavior: smooth for navigating to in-page anchors with appropriate offset

Instant jumps to anchor links are disorienting — users lose context of where they are on the page. Smooth scrolling maintains spatial awareness and creates a more polished navigation experience.

## Rule snippet

```tsx
html { scroll-behavior: smooth; }
:target { scroll-margin-top: 5rem; }
```

## Bad — do not do this

`animations-smooth-scroll-anchors-bad`

```tsx
export function SmoothScrollAnchorsBad() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg overflow-hidden">
        <div className="p-3 border-b border-border flex gap-2">
          <a href="#bad-section-1" className="text-xs text-primary underline">Section 1</a>
          <a href="#bad-section-2" className="text-xs text-primary underline">Section 2</a>
          <a href="#bad-section-3" className="text-xs text-primary underline">Section 3</a>
        </div>
        <div className="h-32 overflow-y-auto p-3 space-y-24">
          <div id="bad-section-1"><h4 className="text-sm font-medium text-foreground">Section 1</h4><p className="text-xs text-muted-foreground">Content for section one.</p></div>
          <div id="bad-section-2"><h4 className="text-sm font-medium text-foreground">Section 2</h4><p className="text-xs text-muted-foreground">Content for section two.</p></div>
          <div id="bad-section-3"><h4 className="text-sm font-medium text-foreground">Section 3</h4><p className="text-xs text-muted-foreground">Content for section three.</p></div>
        </div>
      </div>
      <p className="text-xs text-error">Anchor links jump instantly — disorienting</p>
    </div>
  );
}
```

## Good — do this

`animations-smooth-scroll-anchors-good`

```tsx
export function SmoothScrollAnchorsGood() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg overflow-hidden">
        <div className="p-3 border-b border-border flex gap-2">
          <a href="#good-section-1" className="text-xs text-primary underline" onClick={(e) => { e.preventDefault(); document.getElementById('good-section-1')?.scrollIntoView({ behavior: 'smooth' }); }}>Section 1</a>
          <a href="#good-section-2" className="text-xs text-primary underline" onClick={(e) => { e.preventDefault(); document.getElementById('good-section-2')?.scrollIntoView({ behavior: 'smooth' }); }}>Section 2</a>
          <a href="#good-section-3" className="text-xs text-primary underline" onClick={(e) => { e.preventDefault(); document.getElementById('good-section-3')?.scrollIntoView({ behavior: 'smooth' }); }}>Section 3</a>
        </div>
        <div className="h-32 overflow-y-auto p-3 space-y-24" style={{ scrollBehavior: 'smooth' }}>
          <div id="good-section-1"><h4 className="text-sm font-medium text-foreground">Section 1</h4><p className="text-xs text-muted-foreground">Content for section one.</p></div>
          <div id="good-section-2"><h4 className="text-sm font-medium text-foreground">Section 2</h4><p className="text-xs text-muted-foreground">Content for section two.</p></div>
          <div id="good-section-3"><h4 className="text-sm font-medium text-foreground">Section 3</h4><p className="text-xs text-muted-foreground">Content for section three.</p></div>
        </div>
      </div>
      <p className="text-xs text-success">scroll-behavior: smooth — animated navigation to anchors</p>
    </div>
  );
}
```

## References

- [interfaces.rauno.me](https://interfaces.rauno.me/)
- [MDN scroll-behavior](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior)
