FIELD NOTE 020TypeScriptReviewed July 2026

Smooth Scroll to Element

Smoothly scrolls to a DOM element with configurable offset and behavior

Copy the complete example or adapt its typed interface to your project. Comments are kept inside the snippet so the intent travels with the code.

pattern.ts
/**
 * Smooth scroll to DOM element
 * @param element Target element or selector
 * @param offset Scroll offset in pixels
 * @param behavior Scroll behavior ('auto' or 'smooth')
 */
function scrollToElement(
  element: HTMLElement | string,
  offset = 0,
  behavior: ScrollBehavior = 'smooth'
): void {
  const target = typeof element === 'string' 
    ? document.querySelector(element) 
    : element;
  
  if (!target) return;
  
  const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - offset;
  window.scrollTo({
    top: targetPosition,
    behavior
  });
}

// Usage Example
scrollToElement('#section-about', 20); // Scroll to #section-about with 20px offset
scrollToElement(document.getElementById('contact'), 0, 'auto'); // Instant scroll

Perfect for navigation menus, back-to-top buttons, or smooth scrolling between page sections

Implementation note

Review the input assumptions and browser or runtime support before adopting a utility unchanged. Small helpers are easiest to maintain when their contract stays narrow.

How it works

The helper locates an element, calculates its document position plus an optional offset, and asks the browser to animate the viewport to that point. The offset leaves room for sticky navigation or contextual spacing.

What to watch for

The target may not exist, layout can change during animation, nested scroll containers need different handling, and motion can make some users uncomfortable. Browser focus is separate from visual scrolling and matters for accessibility.

Production use

Use native scrollIntoView when its alignment options are sufficient. Respect prefers-reduced-motion, update focus for navigation-like jumps, and test sticky headers plus mobile viewport changes before relying on a fixed offset.

Before you ship

  • Confirm the input contract with tests that cover empty, invalid, boundary, and representative real-world values before sharing the helper across a codebase.
  • Keep the function focused on one responsibility and name any project-specific policy explicitly instead of hiding it inside a generic-looking utility.
  • Measure behavior in the browsers or runtime versions your product supports, especially when timing, storage, DOM state, locale, or network access is involved.
  • Document the return type, mutation behavior, failure mode, and performance characteristics beside the call site so future maintainers can evaluate changes safely.
  • Compare the example with current official platform documentation when it relies on a browser API, language feature, or runtime behavior that may change over time.
  • If the helper crosses a trust boundary, validate again on the server and avoid treating browser-side checks, TypeScript annotations, or formatted output as a security guarantee.
  • Add a small regression test whenever a real edge case is discovered; concrete examples preserve the reason behind a guard more reliably than a general comment.