[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;
🎨 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>
- 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);
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"
/>
🚀 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.