How To Create Arrow CSS Animation

Arrows can be used for paging, carousels, call to action buttons. This post will go over how to animate these arrows for your web design.

Dec 8, 2022 | Read time 12 minutes

πŸ”” Table of contents

In this post we will go over several methods to create arrow animations in CSS for your web design.

Arrow animations are usually used for paging buttons (next/previous), scroll to top/bottom buttons or even play video or call to action buttons.

Steps to create arrow animation in CSS

  1. Create the arrow with HTML and CSS using the border property.
  2. Define CSS animation @keyframes or transition property
  3. Trigger the animation on :hover state (eg when the user hovers over the arrow button)

We will be creating a arrow next button (can be used for paging or carousel slider components) that will look like the following:

Step 1: Create the arrow with HTML and CSS using the border property

Firstly, we need to setup the HTML for this arrow button:

<div class="arrow-button">
  <div class="arrow-container">
    <i class="arrow"></i>
  <div class="arrow-bg"></div>

Essentially, we want a big arrow-button class as the outer container. The arrow-bg will be used as the pulsing/ water drop animation that will expand when the user hovers over the arrow.

The arrow class will be the inner arrow icon that is inside the button.

To style the β€œarrow” icon, we can do this with CSS. The basic idea is to create a square box with borders for the top and right (3px) and the bottom and left borders to be zero (0px).

We then will rotate this box 45 degrees (transform:rotate(45deg)) to give it the appearance of a arrow facing to the right.

  color: #006064;
  height: 15px; 
  width: 15px;
  border: 1px solid #aaa;
  border-width: 3px 3px 0 0;
  transform: rotate(45deg);

Tip: Rotate the box to change the direction of the arrow

  • Rotate -135deg will give you a arrow facing left (<)
  • Rotate 135deg will give you a arrow facing down (\/)
  • Rotate -45deg will give you a arrow facing up (/\)

Step 2. Define CSS animation @keyframes or transition property

The next step to create the pulsing background effect. In this case, we will use the transition property, since this is a fairly simple animation. If you want more finer control over each frame of the animation, then @keyframe would be the way to go.

The background is the arrow-bg div. We start the div with 100% of its dimentions and not visible. This is done with the transform:scale3d(1,1,1) and opacity:0 respectively:

  width: 80px;
  height: 80px;
  background: white;
  opacity: 0.5;
  border-radius: 50%;
  position: absolute;
  opacity: 0;
  transform: scale3d(1, 1, 1);
  transition: all 1s; /* Transition definition with 1 second duration and animate on all properties */

Step 3 - Trigger the animation on :hover state

The final step is to scale up and increase the opacity the arrow-bg to have the β€œpulse” animation effect. We can do this updating the transform and opacity properties on the :hover pseudo-class.

  transform: scale3d(1.2, 1.2, 1.2);
  opacity: .4;

Example 1: Bouncing Arrow Animation with CSS

One use of arrows in web design is to create a scrolling button. When you click on this button, it will scroll to the top or bottom.

In our next example, we will create the following effect:

Similar to our previous code, the HTML for this arrow button will be simple. In this example, instead of creating the arrow with pure CSS, I will use icons from FontAwesome ( We just need to link it externally like so:

<head> <!-- External Font Awesome CSS -->
  <link rel="stylesheet" href="//">

<div class="arrow bounce">
  <a class="fa fa-arrow-down fa-2x" href="#"></a>

In the above, the classes fa fa-arrow-down fa-2x are font awesome icon classes. We just wanted the arrow down icon that is 2 times the size.

Then the key animation is defined in the following @keyframe:

@keyframes bounce {
  0%, 20%, 50%, 80%, 100% {
    transform: translateY(0);
  40% {
    transform: translateY(-30px);
  60% {
    transform: translateY(-15px);

The general idea is to move the .arrow along the Y-axis using the translateY() function. To get the bounce effect, we move it to the max value of -30px and slowly decrease it (-15px) to zero pixels. You can play around with Y values to get a more β€œreal world” effect!

Example 2: More advanced bouncing arrow animation

Now we can combine the techniques we have used in the previous examples (bounce) and pulse animation to create a more eye catching effect like the following:

The example is quite simple when we break it down.

Note: We will also use FontAwesome in this example as well.

Our HTML will look very close the the first example:

<div class="container">
  <span class="circle"> <!-- πŸ‘ˆ The circular button -->
    <i class="arrow fa fa-arrow-down"></i>  <!-- πŸ‘ˆ FontAwesome arrow icon -->
  <span class="pulse"></span> <!-- πŸ‘ˆ The pulse background effect -->

As seen above HTML structure, theres three main components to this animation:

  • We need a circle that will change in height (expand and collapse).
  • The circle will have a arrow inside of it that will move up and down
  • The pulse background animation

The circle element will look like the following. Essentially, we have a div thats got a large border-radius compared to its height/width.

This gives the circle effect. For the animation, we just expand/ contract the height. The keyframes and exact heights I specified below is something that I found will give the best bounce effect.

.circle {
  height: 120px;
  width: 120px;
  display: block;
  border: 5px solid #00baff;
  border-radius: 100px;
  position: absolute;
  bottom: 0;
  z-index: 1;

@keyframes circle	{
  0%   {height:120px;}
  10% {height: 120px;}
  50% {height: 130px;}
  75% {height: 150px;}
  90% {height: 130px;}
  100% {height: 120px;}

Now the next step is to style the arrow and define its animation with @keyframe.

Generally, I have made the keyframes to closely match to the circle animation keyframes.

Although there is less bouncing with the arrow.

.arrow {
  font-size: 42px;
  color: #00baff;
  bottom: 27px;
  position: absolute;
  left: 50%;
  margin-left: -18px;

@keyframes arrow {
  0%   {bottom:0;}
  75% {bottom:90px;}
  100% {bottom:0;}

Lastly, the pulse animation will be similar to our first example.

We just need to scale the element and increase/ decrease the opacity as we progress through the keyframes.

.pulse {
  margin: 0 auto;
  border-radius: 100px;
  position: absolute;
  left: 5px;
  top: 5px;
  z-index: 0;
  background-color: transparent;
  opacity: 0;
  width: 110px;
  height: 110px;
  border: 10px solid #00baff;
  border-radius: 100px;
  animation: pulse 1s linear infinite 0.3s; 

@keyframes pulse {       
  0% {transform: scale(0); opacity: 0;}
  8% {transform: scale(0); opacity: 0;}
  15% {transform: scale(0.1); opacity: 1;}
  30% {transform: scale(0.5); opacity: 1;}
  100% {transform: scale(1.5); opacity: 0; }

Example 3: Up and Down Arrow CSS Animation

A more common use of arrow css animations is with accordians or panels.

Basically, the arrow will turn up or down when the user clicks on the accordian heading - arrow will be up when the panel is collapsed and arrow to be down when the panel is expanded.

See an example as follows:

This animation of making the arrow going up and down is quite simple when we break it down.

I will go over the key bits of how to do this.

We start with our HTML looking like the following:

<div class="row">
  <div class="col">
    <div class="tabs">
      <div class="tab">
        <input type="checkbox" id="chck1"> <!-- πŸ‘ˆ Hidden checkbox to trigger toggle of accordian panel -->
        <label class="tab-label" for="chck1">Item 1</label> <!-- πŸ‘ˆ The arrow appears "after" this element -->
        <div class="tab-content">
          Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ipsum, reiciendis!
      <div class="tab">
        <input type="checkbox" id="chck2"> <!-- πŸ‘ˆ Hidden checkbox to trigger toggle of accordian panel -->
        <label class="tab-label" for="chck2">Item 2</label>
        <div class="tab-content">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. A, in!


Now to create the arrow, we can use the ::after pseudo element as follows:

.tab-label::after {
  content: "❯";
  width: 1em;
  height: 1em;
  text-align: center;
  transition: all 0.35s; /* -- πŸ‘ˆ Create a animation on all CSS properties with a duration of 0.35s */
  transform: rotate(-90deg); /* -- πŸ‘ˆ Rotate it so that the arrow points up */

Now to expand the accordian panel, we use a little checkbox trick here. This allows us to avoid resorting to any JavaScript. The basic idea is to create a <input type="checkbox"> element.

We then hide that element using opacity:0 - that way, the user will not see the checkbox, but we can attach the :checked pseudo-class with it.

Basically, the CSS should look something similar to the following:

input {
  position: absolute;
  opacity: 0; /* -- πŸ‘ˆ Hide the checkbox */
  z-index: -1;


input:checked + .tab-label::after {
  transform: rotate(90deg); /* -- πŸ‘ˆ Rotate the arrow to down when we check the checkbox */

Browsers support

  • Most modern browsers would support the above approaches to animating arrows (eg bouncing or up/ down animations). This includes using @keyframe or the transition CSS property.
  • When in doubt - use the following vendor prefixes:
-webkit-transition: all 4s ease;
-moz-transition: all 4s ease;
-ms-transition: all 4s ease;
-o-transition: all 4s ease;
transition: all 4s ease;

For keyframes:

@-webkit-keyframes moveImg { 
@-moz-keyframes moveImg {
@keyframes moveImg {


This post went through how to create arrow animations with just pure CSS. We created a arrow animation that is pulsing background, a bouncing CSS arrow animation and a animation that turns arrows up and down. When creating these animations, keep in mind the browser support and performance.

πŸ‘‹ About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember πŸ˜…)

Follow along on Twitter , GitHub and YouTube