10 CSS Animation Techniques That Make Websites Look Professional in 2025

Master the top CSS animation techniques used by world-class websites. From scroll-triggered reveals to glassmorphism effects — with copy-paste code examples.

About 5 min read

10 CSS Animation Techniques That Make Websites Look Professional in 2025

The gap between an amateur website and a professional one usually comes down to one thing: motion. Not flashy, distracting animation — but purposeful, subtle movement that guides the eye, communicates hierarchy, and gives the interface a sense of life.

Here are the 10 CSS animation techniques that top-tier companies (Stripe, Linear, Vercel, Framer) use in 2025, complete with copy-paste code.


1. Scroll-Triggered Reveal Animations

The #1 most impactful animation on any content-heavy page. Elements fade and slide into view as the user scrolls — making the page feel dynamic without overwhelming.

Using the Intersection Observer API

'use client';
import { useEffect, useRef } from 'react';

export function RevealOnScroll({ children }: { children: React.ReactNode }) {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          entry.target.classList.add('revealed');
        }
      },
      { threshold: 0.15 }
    );

    if (ref.current) observer.observe(ref.current);
    return () => observer.disconnect();
  }, []);

  return (
    <div ref={ref} className="reveal-on-scroll">
      {children}
    </div>
  );
}
.reveal-on-scroll {
  opacity: 0;
  transform: translateY(32px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal-on-scroll.revealed {
  opacity: 1;
  transform: translateY(0);
}

Modern Alternative: CSS @scroll-timeline

Chrome 115+ supports pure CSS scroll animations with zero JavaScript:

@keyframes fade-in-up {
  from { opacity: 0; transform: translateY(40px); }
  to   { opacity: 1; transform: translateY(0); }
}

.card {
  animation: fade-in-up linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 30%;
}

2. Shimmer Loading Skeletons

Replace blank loading states with shimmer skeletons. Users perceive shimmer screens as 47% faster than blank spinners (Facebook research).

@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}

.skeleton {
  background: linear-gradient(
    90deg,
    #1f2937 25%,
    #374151 50%,
    #1f2937 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: 8px;
}
function CardSkeleton() {
  return (
    <div className="p-6 rounded-2xl border border-gray-800 space-y-4">
      <div className="skeleton h-6 w-3/4" />
      <div className="skeleton h-4 w-full" />
      <div className="skeleton h-4 w-5/6" />
      <div className="skeleton h-10 w-32 mt-4" />
    </div>
  );
}

3. Magnetic Button Effect

This effect makes buttons slightly pull toward the user's cursor — a subtle interaction that feels premium. Used by Linear, Arc Browser, and Framer.

'use client';
import { useRef } from 'react';

export function MagneticButton({ children }: { children: React.ReactNode }) {
  const btn = useRef<HTMLButtonElement>(null);

  function handleMouseMove(e: React.MouseEvent) {
    const { left, top, width, height } = btn.current!.getBoundingClientRect();
    const x = e.clientX - (left + width / 2);
    const y = e.clientY - (top + height / 2);
    btn.current!.style.transform = `translate(${x * 0.25}px, ${y * 0.25}px)`;
  }

  function handleMouseLeave() {
    btn.current!.style.transform = 'translate(0, 0)';
    btn.current!.style.transition = 'transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
  }

  return (
    <button
      ref={btn}
      onMouseMove={handleMouseMove}
      onMouseLeave={handleMouseLeave}
      style={{ transition: 'transform 0.1s ease' }}
      className="px-8 py-4 rounded-xl bg-white text-black font-semibold"
    >
      {children}
    </button>
  );
}

4. Glassmorphism Cards

The frosted-glass look remains one of 2025's most popular UI aesthetics. It pairs beautifully with animated gradient backgrounds.

.glass-card {
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 16px;
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.glass-card:hover {
  transform: translateY(-4px);
  box-shadow:
    0 20px 60px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.15);
}
function GlassCard({ title, description }: { title: string; description: string }) {
  return (
    <div className="glass-card p-6">
      <h3 className="text-white font-semibold text-xl mb-2">{title}</h3>
      <p className="text-white/60">{description}</p>
    </div>
  );
}

5. Gradient Text Animation

Animated gradient text is everywhere in 2025 — and for good reason. It draws the eye to key phrases without feeling gimmicky.

@keyframes gradient-flow {
  0%   { background-position: 0%   50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0%   50%; }
}

.gradient-text {
  background: linear-gradient(
    90deg,
    #a855f7,
    #ec4899,
    #06b6d4,
    #a855f7
  );
  background-size: 300% 300%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gradient-flow 4s ease infinite;
}
<h1>
  Build <span className="gradient-text">Beautiful Animations</span> Today
</h1>

With Tailwind CSS 3.4+, you can achieve the same with animate-[gradient_4s_ease_infinite] plus custom keyframes in your config.


6. Spotlight Cursor Effect

The spotlight effect — a radial glow that follows the mouse — gives pages a dramatic, editorial feel. Vercel and Resend use this on their marketing pages.

'use client';
import { useEffect, useRef } from 'react';

export function SpotlightSection({ children }: { children: React.ReactNode }) {
  const ref = useRef<HTMLDivElement>(null);
  const spotlight = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = ref.current!;
    const sp = spotlight.current!;

    el.addEventListener('mousemove', (e) => {
      const rect = el.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;
      sp.style.setProperty('--x', `${x}px`);
      sp.style.setProperty('--y', `${y}px`);
      sp.style.opacity = '1';
    });

    el.addEventListener('mouseleave', () => {
      sp.style.opacity = '0';
    });
  }, []);

  return (
    <div ref={ref} className="relative overflow-hidden">
      <div
        ref={spotlight}
        className="pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-300"
        style={{
          background: `radial-gradient(600px at var(--x) var(--y), rgba(120,80,255,0.15), transparent 80%)`,
        }}
      />
      {children}
    </div>
  );
}

7. Staggered List Animations

When rendering lists of cards or features, stagger the animations so each item appears slightly after the previous one. This creates an elegant cascade effect.

.stagger-item {
  opacity: 0;
  transform: translateY(20px);
  animation: stagger-in 0.5s ease forwards;
}

@keyframes stagger-in {
  to { opacity: 1; transform: translateY(0); }
}

/* Stagger delays */
.stagger-item:nth-child(1) { animation-delay: 0.05s; }
.stagger-item:nth-child(2) { animation-delay: 0.10s; }
.stagger-item:nth-child(3) { animation-delay: 0.15s; }
.stagger-item:nth-child(4) { animation-delay: 0.20s; }
.stagger-item:nth-child(5) { animation-delay: 0.25s; }
.stagger-item:nth-child(6) { animation-delay: 0.30s; }
function FeatureGrid({ features }: { features: Feature[] }) {
  return (
    <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
      {features.map((feature, i) => (
        <div key={feature.id} className="stagger-item">
          <FeatureCard {...feature} />
        </div>
      ))}
    </div>
  );
}

8. Morphing SVG Blobs

Organic, morphing blob shapes create a playful, modern feel for startup and creative portfolio sites.

@keyframes morph {
  0%   { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
  25%  { border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%; }
  50%  { border-radius: 50% 60% 30% 60% / 30% 40% 60% 70%; }
  75%  { border-radius: 60% 40% 50% 30% / 60% 70% 40% 50%; }
  100% { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
}

.blob {
  width: 400px;
  height: 400px;
  background: linear-gradient(135deg, #a855f7, #ec4899);
  animation: morph 8s ease-in-out infinite;
  filter: blur(1px);
}

This is purely CSS — no SVG library needed. For more complex morphs, consider using GSAP's MorphSVGPlugin.


9. Text Scramble Effect

The text scramble (or "glitch") effect rapidly cycles through random characters before settling on the final word. It's great for hero headings and navigation items.

'use client';
import { useEffect, useState } from 'react';

const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

export function ScrambleText({ text }: { text: string }) {
  const [display, setDisplay] = useState(text);

  useEffect(() => {
    let iteration = 0;
    const total = text.length * 3;

    const interval = setInterval(() => {
      setDisplay(
        text
          .split('')
          .map((char, i) => {
            if (i < iteration / 3) return char;
            return chars[Math.floor(Math.random() * chars.length)];
          })
          .join('')
      );

      if (iteration >= total) clearInterval(interval);
      iteration++;
    }, 30);

    return () => clearInterval(interval);
  }, [text]);

  return <span className="font-mono">{display}</span>;
}

10. Border Beam Animation

A glowing beam that travels around a card border. This is the signature effect of many premium SaaS landing pages in 2025.

@property --angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

@keyframes border-rotate {
  to { --angle: 360deg; }
}

.border-beam {
  position: relative;
  border-radius: 16px;
  padding: 1px; /* space for the gradient border */
  background: conic-gradient(
    from var(--angle),
    transparent 70%,
    #a855f7,
    #ec4899,
    transparent 30%
  );
  animation: border-rotate 3s linear infinite;
}

.border-beam-inner {
  background: #0f0f0f;
  border-radius: 15px;
  padding: 24px;
}
function PremiumCard({ children }: { children: React.ReactNode }) {
  return (
    <div className="border-beam">
      <div className="border-beam-inner">
        {children}
      </div>
    </div>
  );
}

Choosing the Right Animation

Not every technique is right for every site. Here's a quick guide:

GoalRecommended Technique
First impression / heroGradient background + staggered headline
Feature showcaseScroll-triggered reveal + staggered list
Premium feelBorder beam + glassmorphism
Content-heavy blogShimmer skeletons + reveal on scroll
Creative/portfolioMorphing blobs + scramble text
Interactive productMagnetic buttons + spotlight effect

Start with Ready-Made Templates

All 10 of these techniques are implemented in the Animation Web library. Instead of writing them from scratch, you can browse hundreds of pre-built animated backgrounds, hero sections, and UI components — all production-ready and copy-paste friendly.

Explore the Animation Web Section Library to find the perfect starting point for your next project.

logo

AnimationWeb

A collection of components for your startup business or side project.

© 2026 AnimationWeb. All rights reserved.