Pure CSS animated scrolldown arrows

0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- Filament.io 0 Flares ×

Let’s do this:

The above demo shows how to create an animated scrolldown button in pure CSS. This can be useful in one-page-websites or in parallax projects or wherever you want a nice button which invites to scroll down.

All with ZERO lines of javascript!

HOW TO MAKE IT

The button is made by 3 HTML elements:

  • a container anchor (the white circle)
  • an upper triangular div
  • a second triangular div
<a class="button_down_container" title="SCROLL DOWN">
		<div class="arrow-down arrow_pos1 arrowflip1"></div>
		<div class="arrow-down arrow_pos2 arrowflip2"></div>
	</a>

The outer container anchor element (HTML “a” tag) has the following style:

.button_down_container {
  width: 100px;
  height: 100px;
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  -ms-border-radius: 50%;
  -o-border-radius: 50%;
  border-radius: 50%;
  border: 1px rgba(255,255,255,0.4) solid;
  position: absolute;
  top: 50%;
  margin-top: -50px;
  right: 20px;
  z-index: 88;
  cursor: pointer;
  overflow: hidden;
  text-align: center;
}
.button_down_container:hover, .button_down_container:active {
  border: 2px rgba(255,255,255,1) solid;
}

The arrows have their own style divided by 3 different classes for a more readable and reusable CSS:

FIRST ARROW:

  • arrow-down
  • arrow_pos1
  • arrowflip1

SECOND ARROW:

  • arrow-down
  • arrow_pos2
  • arrowflip2

The main class for styling the arrows is “arrow-down”:

.arrow-down {
  position: absolute;
  width: 0;
  height: 0;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
  border-top: 20px solid rgba(255,255,255,0.7);
  margin-top: -10px;
  margin-left: -20px;
}

“arrow_pos1” and “arrow_pos2” are used for arrows default positioning:

.arrow_pos1 {
  top: 60%;
  left: 50%;
}
.arrow_pos2 {
  top: 40%;
  left: 50%;
}

Last, we build the CSS3 animation style for making them move. It’s basically a keyframe function per arrow:

@-webkit-keyframes flip-in1 {
  0% {
    margin-top: -40px;
    opacity: 0;
  }
  50% {
    margin-top: 0px;
    opacity: 1;
  }
  99% {
    margin-top: 40px;
    opacity: 0;
  }
  100% {
    margin-top: -40px;
    opacity: 0;
  }
}
@-webkit-keyframes flip-in2 {
  0% {
    margin-top: -40px;
    opacity: 0;
  }
  60% {
    margin-top: 0px;
    opacity: 1;
  }
  99% {
    margin-top: 40px;
    opacity: 0;
  }
  100% {
    margin-top: -40px;
    opacity: 0;
  }
}

The only difference is the keyframe when arrows get to the center of the animation: at 50% and at 60%.
Finally we recall these keyframes functions by the 2 last CSS classes:

.arrowflip1 {
  -webkit-animation-name: flip-in1;
  -webkit-animation-duration: 2.0s;
  -webkit-animation-timing-function: cubic-bezier(1,0,0,1);
  -webkit-animation-iteration-count: infinite;
     -moz-animation-name: flip-in1;
     -moz-animation-duration: 2.0s;
     -moz-animation-timing-function: cubic-bezier(1,0,0,1);
     -moz-animation-iteration-count: infinite;
      -ms-animation-name: flip-in1;
      -ms-animation-duration: 2.0s;
      -ms-animation-timing-function: cubic-bezier(1,0,0,1);
      -ms-animation-iteration-count: infinite;
       -o-animation-name: flip-in1;
       -o-animation-duration: 2.0s;
       -o-animation-timing-function: cubic-bezier(1,0,0,1);
       -o-animation-iteration-count: infinite;
          animation-name: flip-in1;
          animation-duration: 2.0s;
          animation-timing-function: cubic-bezier(1,0,0,1);
          animation-iteration-count: infinite;
}
.arrowflip2{
  -webkit-animation-name: flip-in2;
  -webkit-animation-duration: 2.0s;
  -webkit-animation-timing-function: cubic-bezier(1,0,0,1);
  -webkit-animation-iteration-count: infinite;
     -moz-animation-name: flip-in2;
     -moz-animation-duration: 2.0s;
     -moz-animation-timing-function: cubic-bezier(1,0,0,1);
     -moz-animation-iteration-count: infinite;
      -ms-animation-name: flip-in2;
      -ms-animation-duration: 2.0s;
      -ms-animation-timing-function: cubic-bezier(1,0,0,1);
      -ms-animation-iteration-count: infinite;
       -o-animation-name: flip-in2;
       -o-animation-duration: 2.0s;
       -o-animation-timing-function: cubic-bezier(1,0,0,1);
       -o-animation-iteration-count: infinite;
          animation-name: flip-in2;
          animation-duration: 2.0s;
          animation-timing-function: cubic-bezier(1,0,0,1);
          animation-iteration-count: infinite;
}

That’s all.
Here’s the complete code including CROSS BROWSER hacks:

<style><!--
.divcontenitore {
position: relative;
width: 100%;
height: 120px;
background-color: #000;
}
.button_down_container {
width: 100px;
height: 100px;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
border: 1px rgba(255,255,255,0.4) solid;
position: absolute;
top: 50%;
margin-top: -50px;
right: 20px;
z-index: 88;
cursor: pointer;
overflow: hidden;
text-align: center;
}
.button_down_container:hover, .button_down_container:active {
border: 2px rgba(255,255,255,1) solid;
}
.arrow-down {
position: absolute;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid rgba(255,255,255,0.7);
margin-top: -10px;
margin-left: -20px;
}
.arrow_pos1 {
top: 60%;
left: 50%;
}
.arrow_pos2 {
top: 40%;
left: 50%;
}
.arrowflip1{
-webkit-animation-name: flip-in1;
-webkit-animation-duration: 2.0s;
-webkit-animation-timing-function: cubic-bezier(1,0,0,1);
-webkit-animation-iteration-count: infinite;
-moz-animation-name: flip-in1;
-moz-animation-duration: 2.0s;
-moz-animation-timing-function: cubic-bezier(1,0,0,1);
-moz-animation-iteration-count: infinite;
-ms-animation-name: flip-in1;
-ms-animation-duration: 2.0s;
-ms-animation-timing-function: cubic-bezier(1,0,0,1);
-ms-animation-iteration-count: infinite;
-o-animation-name: flip-in1;
-o-animation-duration: 2.0s;
-o-animation-timing-function: cubic-bezier(1,0,0,1);
-o-animation-iteration-count: infinite;
animation-name: flip-in1;
animation-duration: 2.0s;
animation-timing-function: cubic-bezier(1,0,0,1);
animation-iteration-count: infinite;
}
@-webkit-keyframes flip-in1 {
0% {
margin-top: -40px;
opacity: 0;
}
50% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@-moz-keyframes flip-in1 {
0% {
margin-top: -40px;
opacity: 0;
}
50% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@-ms-keyframes flip-in1 {
0% {
margin-top: -40px;
opacity: 0;
}
50% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@-o-keyframes flip-in1 {
0% {
margin-top: -40px;
opacity: 0;
}
50% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@keyframes flip-in1 {
0% {
margin-top: -40px;
opacity: 0;
}
50% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@-webkit-keyframes flip-in2 {
0% {
margin-top: -40px;
opacity: 0;
}
60% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@-moz-keyframes flip-in2 {
0% {
margin-top: -40px;
opacity: 0;
}
60% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@-ms-keyframes flip-in2 {
0% {
margin-top: -40px;
opacity: 0;
}
60% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@-o-keyframes flip-in2 {
0% {
margin-top: -40px;
opacity: 0;
}
60% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
@keyframes flip-in2 {
0% {
margin-top: -40px;
opacity: 0;
}
60% {
margin-top: 0px;
opacity: 1;
}
99% {
margin-top: 40px;
opacity: 0;
}
100% {
margin-top: -40px;
opacity: 0;
}
}
.arrowflip2{
-webkit-animation-name: flip-in2;
-webkit-animation-duration: 2.0s;
-webkit-animation-timing-function: cubic-bezier(1,0,0,1);
-webkit-animation-iteration-count: infinite;
-moz-animation-name: flip-in2;
-moz-animation-duration: 2.0s;
-moz-animation-timing-function: cubic-bezier(1,0,0,1);
-moz-animation-iteration-count: infinite;
-ms-animation-name: flip-in2;
-ms-animation-duration: 2.0s;
-ms-animation-timing-function: cubic-bezier(1,0,0,1);
-ms-animation-iteration-count: infinite;
-o-animation-name: flip-in2;
-o-animation-duration: 2.0s;
-o-animation-timing-function: cubic-bezier(1,0,0,1);
-o-animation-iteration-count: infinite;
animation-name: flip-in2;
animation-duration: 2.0s;
animation-timing-function: cubic-bezier(1,0,0,1);
animation-iteration-count: infinite;
}
--></style>

<div class="divcontenitore">
	<a class="button_down_container" title="SCROLL DOWN">
		<div class="arrow-down arrow_pos1 arrowflip1"></div>
		<div class="arrow-down arrow_pos2 arrowflip2"></div>
	</a>
</div>
0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- Filament.io 0 Flares ×