A simple btn hover animation

Posted on 2 December 2023

HTML CSS Tutorial

A straightforward guide on how to add a subtle arrow hover animation to your buttons.


I will walk you through in small manageable steps how to add a subtle spark of dynamic fun when a user on your site is about to click a button or submit a form.

This is what we’ll be building, hover the ‘Find out more’ button:

See the Pen Simple btn hover affect 🔥 by @darryncodes (@darryncodes) on CodePen.

Let’s start with the HTML

We don’t want to be styling a div here, we need to use the correct interactive element for the job. You’ll also notice I’ve added a btn class which is an abbreviation for button and will allow me to hook into it and style with the CSS.

<button class="btn">Find out more</button>


Firstly I have declared a few CSS custom properties in the :root pseudo-class. If we decide later to change any colours this will make life easier.

:root {
    --accent: #7f54b3;
    --white: #fff;

A very simple reset

Firstly selecting all elements and removing default margin & padding. I’ve also added box-sizing border-box so the browser calculates any border and padding in the values we specify, rather than stacking them on top. Andy Bell has written a great post about this.

*::after {
    margin: 0;
    padding: 0;
    box-sizing: inherit;

html {
    box-sizing: border-box;

For the benefit of the posts ever growing length I’ve omitted a few declarations to the <body> and the <h1> that you’ll find in the CodePen.

Styling the button

The font-size is set to inherit so it takes on the bodys font size, the sizing doesn’t happen automatically. Next we set the background to transparent, curve the edges slightly with border-radius and add a border.

Finally we set the font color property to white, add some padding and ensure the cursor is a pointer when hovered.

.btn {
    font-size: inherit;
    background: transparent;
    border-radius: 6px;
    border: 1px solid var(--white);
    color: var(--white);
    padding: 12.5px 25px;
    cursor: pointer;

Styling the arrow

We’ll create the arrow using the ::after pseudo-element, then we’ll use the content property to generate the arrow from it’s unicode.

Next we’ll position the arrow absolutely, relative to the .btn. Finally we’ll set the opacity to 0 so that it’s not visible until we hover over the button.

.btn::after {
    content: '\2192';
    position: absolute;
    top: 12px;
    left: 80px;
    opacity: 0;
.btn {
    position: relative;

Tweaking the buttons padding on hover

When the button is hovered we want to slightly decrease the padding to the left and increase it to the right. This helps the button text to move left and provides room for the arrow to move to the right.

.btn:hover {
    padding-left: 12px;
    padding-right: 48px;

Updating the arrow on hover

We now want to target the ::after pseudo-element on hover. We’ll change the opacity to 1 so it’s now visible and it’s final position to the right using the left property.

.btn:hover::after {
    opacity: 1;
    left: 128px;

Adding the transition effect

The pièce de résistance, the hover animation. It is all tied together using the transition property, this enables us to define the transition between two states of an element.

Firstly we need to smoothly transition the opacity of the arrow from not visible to visible at the same time as animating the movement to the right.

.btn::after {
    transition: 0.5s;

Secondly we want to apply the transition to all changed properties on the button.

.btn {
    transition: all 0.5s;


I really hope you enjoyed this guide and found it useful. You can view the completed working demo on CodePen.

Are you considering using SCSS in your next project? I’ve also re-created the same animation with that too.

Until next time, happy coding!