Back

Animated Hover Button Component

Apr 28, 2025

3 min read


In today's post, we'll break down how to create a sleek, animated hover button component using React and Tailwind CSS. This component features a smooth text transition effect when users hover over it - a subtle but engaging interaction that can enhance your website's user experience.

Just like this.

Hover on MeHover on Me

Understanding the Component

The HoverButton component we'll build displays text that slides up and out of view when hovered, revealing identical text sliding up from below. This creates a satisfying transition effect that draws attention without being distracting.

Here's what we're aiming for:

The Code

export const HoverButton = ({ text }: { text: string }) => {
  return (
    <p
      className="group w-fit h-fit flex flex-col relative overflow-hidden cursor-pointer select-none"
      aria-label={text}
    >
      <span className="transition-all duration-500 translate-y-0 group-hover:-translate-y-10">
        {text}
      </span>
      <span className="transition-all duration-500 translate-y-10 absolute group-hover:-translate-y-0">
        {text}
      </span>
    </p>
  );
};

Breaking It Down

Let's analyze this component step by step:

Component Structure

The HoverButton is a functional React component that accepts a single prop:

The Container Element

<p
  className="group w-fit h-fit flex flex-col relative overflow-hidden cursor-pointer select-none"
  aria-label={text}
>

This paragraph element serves as our container with several important Tailwind classes:

The aria-label attribute improves accessibility by providing a text label for screen readers.

The Text Elements

The component contains two span elements with the same text content:

<span className="transition-all duration-500 translate-y-0 group-hover:-translate-y-10">
  {text}
</span>

This first span is initially visible and moves upward (out of view) when hovered:

<span className="transition-all duration-500 translate-y-10 absolute group-hover:-translate-y-0">
  {text}
</span>

This second span is initially positioned below the visible area and slides up into view on hover:

Implementation Tips

  1. Customize the Animation Speed: Adjust the duration-500 value to change how quickly the text slides. For a snappier effect, try duration-300 or for a more relaxed transition, use duration-700.

  2. Styling Variations: You can add background colors, padding, borders, and other styling to the parent element to make it look more like a traditional button.

  3. Event Handling: To make this a functional button, add an onClick handler:

    export const HoverButton = ({ text, onClick }: { text: string, onClick?: () => void }) => {
      return (
        <p
          onClick={onClick}
          className="group w-fit h-fit flex flex-col relative overflow-hidden cursor-pointer select-none"
          aria-label={text}
        >
          {/* spans remain the same */}
        </p>
      );
    };
  4. Accessibility: Consider changing the <p> element to a <button> for better semantic meaning if this component will trigger an action:

    <button
      className="group w-fit h-fit flex flex-col relative overflow-hidden cursor-pointer select-none"
      aria-label={text}
      onClick={onClick}
    >
      {/* spans remain the same */}
    </button>

Usage Example

Here's how you would use this component in your React application:

Hover on MeHover on Me

import { HoverButton } from './components/HoverButton';

function App() {
  return (
    <div className="flex justify-center items-center h-screen">
      <HoverButton text="Hover on Me" />
    </div>
  );
}

export default App;