Tips & Tricks

How to Implement Animations with Claude Code

Learn how to implement animations using Claude Code. Includes practical code examples and step-by-step guidance.

Streamlining Animation Implementation with Claude Code

Web animations can dramatically improve the user experience, but implementing them well requires specialized knowledge. With Claude Code, you can just say “I want a fade-in” or “Reveal elements on scroll” and it will generate the appropriate animation code.

CSS Animation Basics

Let’s start with animations you can build with CSS alone.

> Create a CSS animation that fades in when an element scrolls into view.
> Also include a variant that slides up from below.
/* Fade in + slide up */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInLeft {
  from {
    opacity: 0;
    transform: translateX(-20px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.animate-fade-in-up {
  animation: fadeInUp 0.6s ease-out forwards;
}

.animate-fade-in-left {
  animation: fadeInLeft 0.6s ease-out forwards;
}

/* Initially hidden */
.animate-on-scroll {
  opacity: 0;
}

.animate-on-scroll.is-visible {
  animation: fadeInUp 0.6s ease-out forwards;
}

/* Staggered (delayed) animation */
.stagger-1 { animation-delay: 0.1s; }
.stagger-2 { animation-delay: 0.2s; }
.stagger-3 { animation-delay: 0.3s; }
.stagger-4 { animation-delay: 0.4s; }

Combine this with an Intersection Observer.

function setupScrollAnimations() {
  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          entry.target.classList.add("is-visible");
          observer.unobserve(entry.target);
        }
      });
    },
    { threshold: 0.1, rootMargin: "0px 0px -50px 0px" }
  );

  document.querySelectorAll(".animate-on-scroll").forEach((el) => {
    observer.observe(el);
  });
}

document.addEventListener("DOMContentLoaded", setupScrollAnimations);

Animation with Framer Motion

In React projects, Framer Motion gives you a more declarative way to write animations.

import { motion, useInView, type Variants } from "framer-motion";
import { useRef } from "react";

const containerVariants: Variants = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1,
    },
  },
};

const itemVariants: Variants = {
  hidden: { opacity: 0, y: 20 },
  visible: {
    opacity: 1,
    y: 0,
    transition: { duration: 0.5, ease: "easeOut" },
  },
};

export function AnimatedList({ items }: { items: string[] }) {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: "-50px" });

  return (
    <motion.ul
      ref={ref}
      variants={containerVariants}
      initial="hidden"
      animate={isInView ? "visible" : "hidden"}
      className="space-y-4"
    >
      {items.map((item, i) => (
        <motion.li key={i} variants={itemVariants} className="p-4 bg-white rounded-lg shadow">
          {item}
        </motion.li>
      ))}
    </motion.ul>
  );
}

Page Transitions

Animations between page navigations.

import { motion, AnimatePresence } from "framer-motion";
import { useRouter } from "next/router";

const pageVariants: Variants = {
  initial: { opacity: 0, x: -20 },
  animate: { opacity: 1, x: 0 },
  exit: { opacity: 0, x: 20 },
};

export function PageTransition({ children }: { children: React.ReactNode }) {
  const router = useRouter();

  return (
    <AnimatePresence mode="wait">
      <motion.div
        key={router.pathname}
        variants={pageVariants}
        initial="initial"
        animate="animate"
        exit="exit"
        transition={{ duration: 0.3, ease: "easeInOut" }}
      >
        {children}
      </motion.div>
    </AnimatePresence>
  );
}

Loading Animations

export function SkeletonLoader({ lines = 3 }: { lines?: number }) {
  return (
    <div className="space-y-3 animate-pulse">
      {Array.from({ length: lines }).map((_, i) => (
        <div
          key={i}
          className="h-4 bg-gray-200 rounded"
          style={{ width: `${100 - i * 15}%` }}
        />
      ))}
    </div>
  );
}

export function SpinnerLoader({ size = "md" }: { size?: "sm" | "md" | "lg" }) {
  const sizeClasses = { sm: "h-4 w-4", md: "h-8 w-8", lg: "h-12 w-12" };

  return (
    <div className={`${sizeClasses[size]} animate-spin rounded-full border-2 border-gray-300 border-t-primary-600`} />
  );
}

For integration with a design system, see building a design system, and for responsive behavior, see responsive design.

Summary

With Claude Code, you can ship CSS animations, Framer Motion, page transitions, and loading indicators in a fraction of the usual time. Simply describe “the kind of motion I want” and Claude will pick the right technique and generate the code.

For more details, see the official Claude Code documentation.

#Claude Code #animation #CSS #Framer Motion #frontend

Level up your Claude Code workflow

50 battle-tested prompt templates you can copy-paste into Claude Code right now.

Free

Free PDF: Claude Code Cheatsheet in 5 Minutes

Key commands, shortcuts, and prompt examples on a single printable page.

Download PDF
M

About the Author

Masa

Engineer obsessed with Claude Code. Runs claudecode-lab.com, a 10-language tech media with 2,000+ pages.