css

Smooth Scroll CSS & JS

Implement smooth scrolling with CSS and JavaScript, including scroll-to-top and anchor navigation.

#scroll #animation #navigation

Smooth scrolling implementations for modern websites.

CSS-Only Smooth Scroll

/* Global smooth scroll */
html {
  scroll-behavior: smooth;
}

/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

Scroll Padding (Fixed Header)

html {
  scroll-behavior: smooth;
  scroll-padding-top: 80px; /* Height of fixed header */
}

JavaScript Scroll Functions

// Scroll to element
function scrollToElement(selector: string, offset: number = 0) {
  const element = document.querySelector(selector);
  if (!element) return;
  
  const top = element.getBoundingClientRect().top + window.scrollY - offset;
  window.scrollTo({ top, behavior: 'smooth' });
}

// Scroll to top
function scrollToTop() {
  window.scrollTo({ top: 0, behavior: 'smooth' });
}

// Scroll to bottom
function scrollToBottom() {
  window.scrollTo({ 
    top: document.documentElement.scrollHeight, 
    behavior: 'smooth' 
  });
}

React Scroll-to-Top Button

import { useState, useEffect } from 'react';

function ScrollToTop() {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const toggleVisible = () => {
      setVisible(window.scrollY > 300);
    };
    
    window.addEventListener('scroll', toggleVisible);
    return () => window.removeEventListener('scroll', toggleVisible);
  }, []);

  const scrollToTop = () => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  if (!visible) return null;

  return (
    <button
      onClick={scrollToTop}
      className="fixed bottom-6 right-6 p-3 bg-blue-500 text-white 
                 rounded-full shadow-lg hover:bg-blue-600 
                 transition-all duration-300"
      aria-label="Scroll to top"
    >

    </button>
  );
}

Anchor Navigation Hook

function useScrollToHash() {
  useEffect(() => {
    const hash = window.location.hash;
    if (hash) {
      const element = document.querySelector(hash);
      if (element) {
        setTimeout(() => {
          element.scrollIntoView({ behavior: 'smooth' });
        }, 100);
      }
    }
  }, []);
}

Intersection Observer for Active Section

function useActiveSection(sectionIds: string[]) {
  const [activeId, setActiveId] = useState('');

  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            setActiveId(entry.target.id);
          }
        });
      },
      { rootMargin: '-50% 0px -50% 0px' }
    );

    sectionIds.forEach((id) => {
      const el = document.getElementById(id);
      if (el) observer.observe(el);
    });

    return () => observer.disconnect();
  }, [sectionIds]);

  return activeId;
}