DEV Community

Cover image for How to Create an Animated Button with Hover Sound in React
Dinh Hoang Duy
Dinh Hoang Duy

Posted on

How to Create an Animated Button with Hover Sound in React

[TL;DR] Demo

Buttons are essential UI elements in any web application, but making them interactive and delightful can truly elevate the user experience. In this post, we’ll build a stylish React button component with a hover animation and sound effect when the user hovers over it.

By the end, you'll have a reusable button component with:

  • Smooth hover text animation
  • Optional icons (left and right)
  • A tick sound when hovered

🔧 Technologies Used

  • React
  • Tailwind CSS (for styling and animation)
  • HTML5 Audio API

📦 The Button Component

Below is the complete Button component you can copy into your React project.

import clsx from "clsx";
import { useEffect, useRef } from "react";

const Button = ({
  id,
  title,
  rightIcon,
  leftIcon,
  containerClass,
  hoverSound = "/audio/ui.mp3", // Sound file path
  hoverSoundAt = 0,
  children,
}) => {
  const audioRef = useRef(null);

  // Preload the hover sound
  useEffect(() => {
    if (hoverSound) {
      audioRef.current = new Audio(hoverSound);
      audioRef.current.currentTime = hoverSoundAt;
      audioRef.current.preload = "auto";
    }
  }, [hoverSound, hoverSoundAt]);

  // Play sound on hover
  const handleMouseEnter = () => {
    if (audioRef.current) {
      audioRef.current.currentTime = 0;
      audioRef.current.play();
    }
  };

  // Reset sound on mouse leave
  const handleMouseLeave = () => {
    if (audioRef.current) {
      audioRef.current.pause();
      audioRef.current.currentTime = 0;
    }
  };

  return children ? (
    <span
      id={id}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      {children}
    </span>
  ) : (
    <button
      id={id}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      className={clsx(
        "group relative z-10 w-fit cursor-pointer overflow-hidden rounded-full bg-violet-50 px-7 py-3 text-black",
        containerClass
      )}
    >
      {leftIcon}

      <span className="relative inline-flex overflow-hidden font-general text-xs uppercase">
        <div className="translate-y-0 skew-y-0 transition duration-500 group-hover:translate-y-[-160%] group-hover:skew-y-12">
          {title}
        </div>
        <div className="absolute translate-y-[164%] skew-y-12 transition duration-500 group-hover:translate-y-0 group-hover:skew-y-0">
          {title}
        </div>
      </span>

      {rightIcon}
    </button>
  );
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

🎨 Styling Explained

We use Tailwind utility classes to achieve a sleek sliding animation for the button text:

<span className="relative inline-flex overflow-hidden font-general text-xs uppercase">
  <div className="translate-y-0 skew-y-0 transition duration-500 group-hover:translate-y-[-160%] group-hover:skew-y-12">
    {title}
  </div>
  <div className="absolute translate-y-[164%] skew-y-12 transition duration-500 group-hover:translate-y-0 group-hover:skew-y-0">
    {title}
  </div>
</span>
Enter fullscreen mode Exit fullscreen mode
  • The first div moves up and skews on hover.
  • The second div takes its place from below, giving a smooth slide-in effect.

🔊 Adding Hover Sound

We preload and play the sound using the native Audio API:

const audioRef = useRef(null);
audioRef.current = new Audio(hoverSound);
Enter fullscreen mode Exit fullscreen mode

This ensures the tick sound plays instantly on hover.

💡 Tip:

Make sure your audio file (ui.mp3) is placed correctly in the public/audio/ directory (or adjust the path).


✅ Usage Example

<Button
  title="Click Me"
  hoverSound="/audio/ui.mp3"
  leftIcon={<MyLeftIcon />}
  rightIcon={<MyRightIcon />}
  containerClass="bg-blue-200 hover:bg-blue-300"
/>
Enter fullscreen mode Exit fullscreen mode

🚀 Final

This button is great for game UIs, modern websites, or any interface where tactile feedback enhances the experience. You can customize it further by changing:

  • The animation style
  • The sound file
  • The icon positions

📁 Resources

Happy coding! _duythenights 🔊💻✨

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.