Skip to main content
Design System

Heartbeat Animation

A CSS-based pulsing glow effect that creates a subtle, rhythmic animation reminiscent of a heartbeat. Uses radial gradients with blur effects and CSS keyframe animations.

Preview

Watch the heartbeat animation pulse with a rhythmic glow effect. The animation adapts to your design system theme.

Features

  • Pure CSS animation using keyframes and transforms
  • GPU-accelerated properties for smooth performance
  • Radial gradient with blur filter for soft glow effect
  • Automatic dark mode support with adjusted opacity
  • Rhythmic pulsing animation (2 second cycle)
  • Non-intrusive with pointer-events-none

Usage

Import and use the HeartbeatAnimation component:

import HeartbeatAnimation from "@/components/pulse/HeartbeatAnimation";

export default function MyComponent() {
  return (
    <div className="relative min-h-screen">
      <HeartbeatAnimation />
      {/* Your content here */}
    </div>
  );
}

Animation Properties

Duration & Timing

  • Duration: 2 seconds per cycle
  • Timing Function: ease-in-out (smooth acceleration and deceleration)
  • Iteration: infinite (loops continuously)

Scale & Opacity

  • Scale Range: 1.0 → 1.1 → 1.2 → 1.1 → 1.0
  • Opacity Range: 0.6 → 0.8 → 0.9 → 0.8 → 0.6

Color & Gradient

  • Color: Uses design system primary color (hsl(var(--primary)))
  • Gradient: Radial gradient with 5 stops (0%, 30%, 60%, 80%, 100%)
  • Blur: 20px filter blur for soft glow effect

Implementation Details

CSS Keyframes

The animation uses CSS keyframes to create a rhythmic pulsing effect. The keyframe percentages (0%, 25%, 50%, 75%, 100%) create a smooth heartbeat-like rhythm with two beats per cycle.

Radial Gradient

The radial gradient creates a smooth fade from center to edge, using the design system primary color with opacity decreasing from 0.4 (light mode) or 0.5 (dark mode) at the center to transparent at the edges. This creates the glowing orb effect.

Blur Filter

The 20px blur filter is essential for creating the soft, glowing appearance. Without it, the animation would appear as a sharp circle. The blur creates the diffused light effect that makes it look like a glowing orb.

Positioning

The component uses absolute positioning with flexbox centering. The parent container should have position: relative. The animation element uses pointer-events-none to prevent it from blocking interactions with content underneath.

Dark Mode

Dark mode automatically adjusts the gradient opacity values to be slightly more visible (0.5, 0.3, 0.15, 0.08 vs 0.4, 0.2, 0.1, 0.05) to maintain visibility against darker backgrounds.

Customization

The heartbeat animation can be customized by modifying the CSS variables and keyframe values:

Animation Speed

Change the duration to make it faster or slower:

/* Faster (1.5s) */
animation: heartbeat 1.5s ease-in-out infinite;

/* Slower (3s) */
animation: heartbeat 3s ease-in-out infinite;

Size

Adjust the width and height for larger or smaller glow:

/* Larger */
width: 400px;
height: 400px;

/* Smaller */
width: 200px;
height: 200px;

Color

The animation uses the design system primary color by default. To use a different color, replace hsl(var(--primary)) with your desired color:

/* Use secondary color */
hsl(var(--secondary) / 0.4) 0%,
hsl(var(--secondary) / 0.2) 30%,

/* Use custom color */
hsl(200 80% 50% / 0.4) 0%,
hsl(200 80% 50% / 0.2) 30%,

Blur Intensity

Adjust the blur filter for sharper or softer glow:

/* Sharper */
filter: blur(10px);

/* Softer */
filter: blur(30px);

Browser Compatibility

This animation uses standard CSS features supported in all modern browsers:

  • ✅ CSS Animations - Supported in all modern browsers
  • ✅ CSS Gradients - Supported in all modern browsers
  • ✅ CSS Filters - Supported in all modern browsers (IE 10+)
  • ✅ Transform - Supported in all modern browsers

Performance

  • The animation uses CSS transforms and opacity, which are GPU-accelerated properties, ensuring smooth performance
  • The blur filter can be performance-intensive on some devices; consider reducing blur amount if you notice performance issues
  • The animation runs continuously; consider pausing it when the element is not visible using animation-play-state: paused with JavaScript