Many times animations are implemented on a web page to improve the user experience, making it more attractive and intuitive. With the animation property and the @keyframes rule, you can create any animation you have in mind by manipulating a large number of properties. This article shows the basics of making animations using a small project as an example, consisting of four squares jumping into four other squares as they move to the right and end up stacked in a tower. Before starting with the animations we need to create a container in the index.html file, which we will call canvas, this will be the place where all the animations will occur. Also, we will create static squares and those that will be in motion. index.html < = > div class "canvas" < = > div class "static-square" </ > div < = > div class "static-square" </ > div < = > div class "static-square" </ > div < = > div class "static-square" </ > div < = > div class "animated-square" </ > div < = > div class "animated-square" </ > div < = > div class "animated-square" </ > div < = > div class "animated-square" </ > div </ > div Our canvas will have a relative position and the rest of the elements will have an absolute position, that way we can easily manipulate them and place them in the desired place. It is important that the canvas has an overflow property with the value hidden so that no element is displayed outside the canvas. And the static squares will be at the bottom of the canvas with bottom: 0 and we will distribute them along with the canvas by the left property. style.css { : hidden; : relative; : ; : ; : black; : auto ; } { : absolute; : ; : ; : ; : (251, 255, 0); } { : ; } { : ; } { : ; } { : ; } .canvas overflow position height 500px width 1000px background margin 15px 0 .canvas .static-square position bottom 0 height 100px width 100px background-color rgb .canvas .static-square :nth-child(1) left 100px .canvas .static-square :nth-child(2) left 300px .canvas .static-square :nth-child(3) left 500px .canvas .static-square :nth-child(4) left 700px Now it's time to start the animations. All animated squares will appear from the top left of the canvas just 100px outside the canvas waiting for their turn to appear on the scene, then they will start jumping over the static squares. To achieve this we will use different properties to accomplish the animation. We also need to determine the length of time the animation will last with animation-duration; since we are going to see this animation several times we will keep a short duration of 4 seconds. With animation-timing-function we can decide the speed curve, there are several different speeds so we will use a different one for each square. Each animation needs a name, with animation-name we can name our animation, in this case, we will call it "bounce". In this example, you will see the different speed curves https://www.w3schools.com/css/tryit.asp?filename=trycss3_animation_speed. This would be enough to start working on animation, but there would be several problems. The first of them is that when the animation ends, the square will return to its initial position; to avoid this we will use animation-fill-mode: forwards, in this way the square will maintain the final position of the animation. The next problem is that the animations of the four squares started at the same time, so we will be adding a second delay from the animation of the second square with animation-delay: 1s. style.css { : absolute; : ; : - ; : ; : ; } { : (255, 0, 0); : bounce; : ; : ; : linear; : forwards; } { : (4, 0, 255); : bounce; : ; : ; : ease; : forwards; } { : (0, 228, 11); : bounce; : ; : ; : ease-in; : forwards; } { : (0, 171, 214); : bounce; : ; : ; : ease-in-out; : forwards; } .canvas .animated-square position top 50px left 100px height 100px width 100px .canvas .animated-square :nth-child(5) background-color rgb animation-name animation-duration 4s animation-delay 0s animation-timing-function animation-fill-mode .canvas .animated-square :nth-child(6) background-color rgb animation-name animation-duration 4s animation-delay 1s animation-timing-function animation-fill-mode .canvas .animated-square :nth-child(7) background-color rgb animation-name animation-duration 4s animation-delay 2s animation-timing-function animation-fill-mode .canvas .animated-square :nth-child(8) background-color rgb animation-name animation-duration 4s animation-delay 3s animation-timing-function animation-fill-mode Perfect! Now we can start the animation. It is here when we need the @keyframes rule where we can give the animation instructions in a range from 0% to 100%. In this range, we will change the values of top and left to move the squares up and down as they move to the right until they occupy their final position to form a stack. And to give it a little more life we will use the transform property and the rotate function to which we will add 180 degrees of rotation in each step. One second, how will we know the perfect time to give the instructions? Well, for the bounce animation we have 8 key points, the squares will move 4 times down and 4 times up; so we will divide 100 by 8 and the result is 12.5. Therefore the first set of instructions will be 12.5%, the second 25%, and so on. style.css @ bounce { 12 % { : ; : ; : (180deg); } 25% { : ; : ; : (360deg); } 37 % { : ; : ; : (540deg); } 50% { : ; : ; : (720deg); } 62 % { : ; : ; : (900deg); } 75% { : ; : ; : (1080deg); } 87 % { : ; : ; : (1260deg); } 100% { : ; : ; : (1440deg); } } keyframes .5 left 100px top 320px transform rotate left 200px top 50px transform rotate .5 left 300px top 320px transform rotate left 400px top 50px transform rotate .5 left 500px top 320px transform rotate left 600px top 50px transform rotate .5 left 700px top 320px transform rotate left 800px top 50px transform rotate Now we need to add a second animation to move the squares to their final position. To do this we must return to the properties of the first animation and separate the values of the second animation with a comma. Since each square will occupy a different position, we will need 4 animations, which we will call , , , and . final final2 final3 final4 In order for the second animation to start right after the first animation, it is necessary to add a time delay equivalent to the duration of the first animation and its delay, if any. The value of animation-duration will be one second. Since we have 4 animations we also need 4 @keyframes and we will only give the instructions so that the squares occupy their final position to form the tower. style.css { : (255, 0, 0); : bounce, final; : , ; : , ; : linear; : forwards; } { : (4, 0, 255); : bounce, final2; : , ; : , ; : ease; : forwards; } { : (0, 228, 11); : bounce, final3; : , ; : , ; : ease-in; : forwards; } { : (0, 171, 214); : bounce, final4; : , ; : , ; : ease-in-out; : forwards; } @ final { 0% { : ; : ; : (1440deg); } 40% { : ; : ; : (1530deg); } 80% { : ; : ; : (1440deg); } 100% { : ; : ; : (1440deg); } } @ final2 { 0% { : ; : ; : (1440deg); } 50% { : ; : ; : (1530deg); } 100% { : ; : ; : (1530deg); } } @ final3 { 0% { : ; : ; : (1440deg); } 40% { : ; : ; : (1530deg); } 100% { : ; : ; : (1530deg); } } @ final4 { 0% { : ; : ; : (1440deg); } 40% { : ; : ; : (1530deg); } 100% { : ; : ; : (1530deg); } } .canvas .animated-square :nth-child(5) background-color rgb animation-name animation-duration 4s 1s animation-delay 0s 4s animation-timing-function animation-fill-mode .canvas .animated-square :nth-child(6) background-color rgb animation-name animation-duration 4s 1s animation-delay 1s 5s animation-timing-function animation-fill-mode .canvas .animated-square :nth-child(7) background-color rgb animation-name animation-duration 4s 1s animation-delay 2s 6s animation-timing-function animation-fill-mode .canvas .animated-square :nth-child(8) background-color rgb animation-name animation-duration 4s 1s animation-delay 3s 7s animation-timing-function animation-fill-mode keyframes left 800px top 50px transform rotate left 900px top 300px transform rotate left 900px top 400px transform rotate left 900px top 400px transform rotate keyframes left 800px top 50px transform rotate left 900px top 300px transform rotate left 900px top 300px transform rotate keyframes left 800px top 50px transform rotate left 900px top 200px transform rotate left 900px top 200px transform rotate keyframes left 800px top 50px transform rotate left 900px top 100px transform rotate left 900px top 100px transform rotate As you can see 3 of the @keyframes have equal values for 50% and 100%, this is completely necessary to keep the animation flowing. With this we would finish the animation of the jumping squares; now how about we give a little life to static squares. Let's do something simple, when the static square is hit by the animated square, we will reduce its height and increase its width, and then recover its original shape. This time we will use the animation shortcut to write everything on one line. Then, the animation name will be "smash", with a duration of one second, the speed curve will be linear and the fill-mode will be forwards. Unlike past animations this time we will need the animation to repeat 4 times, for this we will use iteration-count to specify the number of iterations that the animation will have, in our case, it will be 4. We can add a second animation in which the static square acquires the color of the animated square when they come into contact and finally recovers its color. We will call this animation "splash". style.css { : absolute; : ; : ; : ; : (251, 255, 0); : smash linear forwards, splash linear forwards; } @ smash { 49% { : ; : ; } 50% { : ; : ; } 100% { : ; : ; } } @ splash { 9% { : (251, 255, 0); } 10% { : (255, 0, 0); } 29% { : (255, 0, 0); } 30% { : (4, 0, 255); } 49% { : (4, 0, 255); } 50% { : (0, 228, 11); } 69% { : (0, 228, 11); } 70% { : (0, 171, 214); } 100% { : (251, 255, 0); } } .canvas .static-square position bottom 0 height 100px width 100px background-color rgb animation 1s 4 5s 1 keyframes height 100px width 100px height 75px width 125px height 100px width 100px keyframes background-color rgb background-color rgb background-color rgb background-color rgb background-color rgb background-color rgb background-color rgb background-color rgb background-color rgb As you can see , so now we are going to replicate the resource used in the old cartoons in which they repeated the background while the characters moved horizontally or vertically. it is possible to manipulate the background-color in the animations We will first create a new element in index.html with the top-bar class. The key to creating this effect is that the beginning of the background must be exactly the same as the end, to fulfill this purpose in a simple way we will use gradient-linear (you can also use an image that meets the previous condition). For this animation we must increase the background-size depending on the direction in which the background moves; in our animation, it will scroll vertically so we will increase the height of the background-size. Regarding the properties of the animation, the name will be ''party-bar'', the duration of four seconds (changing this value you can change the speed of the animation), the speed curve will be linear and as in this occasion we want the animation to repeat indefinitely, we will use the infinite value for iteration-count. The @keyframes is quite simple, you just have to change the vertical value of the background-position. Due to this simplicity, we are able to use the keywords "from" and "to" that are equal to 0% and 100% respectively. index.html < = > div class "canvas" < = > div class "static-square" </ > div < = > div class "static-square" </ > div < = > div class "static-square" </ > div < = > div class "static-square" </ > div < = > div class "animated-square" </ > div < = > div class "animated-square" </ > div < = > div class "animated-square" </ > div < = > div class "animated-square" </ > div < = > div class "top-bar" </ > div </ > div style.css { : absolute; : ; : ; : ; : ; : ( 0deg, rgba(255, 0, 230, 1) , (23, 250, 255, 1) , (0, 177, 238, 1) , (255, 0, 230, 1) ); : ; : party-bar; : ; : linear; : infinite; } @ party-bar { { : ; } { : ; } } .top-bar position top 0 left 0 height 70px width 100% background linear-gradient 15% rgba 40% rgba 65% rgba 85% background-size 100% 1000% animation-name animation-duration 4s animation-timing-function animation-iteration-count keyframes from background-position 0% 0% to background-position 0% 100% One last animation, I promise. This time we will create lights that turn on and off in the background and for this animation to work properly we have to change the background of the canvas to a radial-gradient, and we will see why. This animation will be called ''light'', it will have a duration of two seconds, an ease-in-out speed curve, and of course, the iterations will be infinite. Now that we have a radial background we can move the center of the background in the @keyframes as well as change its color. style.css { : hidden; : relative; : ; : ; : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); : auto ; : light ease-in-out infinite; } @ light { 5% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 10% { : ( circle at 15% 30%, rgba(242, 255, 23, 1) , (237, 238, 0, 1) , (20, 20, 20, 1) , (4, 4, 4, 1) ); } 15% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 25% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 30% { : ( circle at 85% 30%, rgba(58, 214, 0, 1) , (0, 185, 3, 1) , (0, 0, 0, 1) , (0, 0, 0, 1) ); } 35% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 45% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 50% { : ( circle at 15% 70%, rgba(0, 160, 237, 1) , (10, 99, 191, 1) , (0, 0, 0, 1) , (0, 0, 0, 1) ); } 55% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 65% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 70% { : ( circle at 85% 70%, rgba(255, 0, 0, 1) , (224, 11, 11, 1) , (3, 0, 0, 1) , (0, 0, 0, 1) ); } 75% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 85% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } 90% { : ( circle at 50% 50%, rgba(124, 0, 255, 1) , (102, 1, 190, 1) , (0, 0, 0, 1) , (0, 0, 0, 1) ); } 95% { : ( circle, rgba(0, 0, 0, 1) , (0, 0, 0, 1) ); } } .canvas overflow position height 500px width 1000px background radial-gradient 0% rgba 100% margin 15px 0 animation 2s keyframes background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 5% rgba 45% rgba 65% background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 5% rgba 45% rgba 65% background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 5% rgba 45% rgba 65% background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 5% rgba 45% rgba 65% background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 100% background radial-gradient 0% rgba 15% rgba 55% rgba 100% background radial-gradient 0% rgba 100% Now you know the basics to create animations! You can see the complete project here: . https://codepen.io/LoboArcano/pen/eYNqRYJ Don't stop experimenting!