Nowadays, more and more websites are using animations, whether that be in the form of GIFs, SVGs, WebGL, background videos and so on. When used properly, animation on the web brings life and interactivity, adding an extra layer of feedback and experience for users.
In this tutorial I am going to introduce you to CSS animations; a highly performant way of doing things which is becoming more and more popular as browser support improves. Having covered the basics, we're going to build a quick example which will animate a square element into a circle:
The designers on Envato Market have been busy creating a range of CSS animations for you to plug in to your websites, from shadows to ribbons, sliders, and more.
You can also hire a CSS expert on Envato Studio to help you with a wide range of fixes and customizations for your project.
The main component of CSS animations is @keyframes
, the CSS rule where animation is created. Think of @keyframes
as being stages along a timeline. Inside @keyframes
, you can define these stages, each having a different style declaration.
Next, to make CSS animations work, you need to bind the @keyframes
to a selector. This will gradually parse all the code inside the @keyframes
declarations and change the initial style to the new style, based on the stages.
Here we'll set the animation stages. Our @keyframes
properties are:
For example:
1 2 3 4 5 6 7 8 | @keyframes tutsFade { 0% { opacity: 1 ; } 100% { opacity: 0 ; } } |
or:
1 2 3 4 5 6 7 8 | @keyframes tutsFade { from { opacity: 1 ; } to { opacity: 0 ; } } |
or the shorthand:
1 2 3 4 5 | @keyframes tutsFade { to { opacity: 0 ; } } |
The code above will apply a transition to the opacity of an element, from opacity: 1
to opacity: 0
. Each of the approaches above will achieve the same end result.
The animation
property is used to call @keyframes
inside a CSS selector. Animation can have multiple properties:
animation-name
: @keyframes
name (remember we chose tutsFade).animation-duration
: the timeframe length, the total duration of the animation from start to the end.animation-timing-function
: sets the animation speed ( linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier ).animation-delay
: the delay before our animation will start.animation-iteration-count
: how many times it will iterate through animation.animation-direction
: gives you the ability to change the loop direction, from start to end ,or from end to start, or both.animation-fill-mode
: specifies which styles will be applied to the element when our animation is finished ( none | forwards | backwards | both )For example:
1 2 3 4 5 6 7 8 | .element { animation-name: tutsFade; animation-duration: 4 s; animation-delay: 1 s; animation-iteration-count: infinite; animation-timing-function: linear; animation- direction : alternate; } |
or shorthand:
1 2 3 | .element { animation: tutsFade 4 s 1 s infinite linear alternate; } |
The code above will create a blinking effect, with a 1 second animation delay, a 4 second total animation duration, with alternate direction and infinite linear loop iterations.
Whilst a working draft, we need to use browser-specific prefixes to ensure the best browser support possible. The standard prefixes apply:
-webkit-
-moz-
-o-
-ms-
An animation
property using vendor prefixes will look like:
1 2 3 4 5 6 7 | .element { -webkit-animation: tutsFade 4 s 1 s infinite linear alternate; -moz-animation: tutsFade 4 s 1 s infinite linear alternate; -ms-animation: tutsFade 4 s 1 s infinite linear alternate; -o-animation: tutsFade 4 s 1 s infinite linear alternate; animation: tutsFade 4 s 1 s infinite linear alternate; } |
alongside with @keyframes
:
1 2 3 4 5 | @-webkit-keyframes tutsFade { /* your style */ } @-moz-keyframes tutsFade { /* your style */ } @-ms-keyframes tutsFade { /* your style */ } @-o-keyframes tutsFade { /* your style */ } @keyframes tutsFade { /* your style */ } |
For the sake of readability during this tutorial I will continue further without using prefixes, but the final version will include them and I would like to encourage you to use them in your CSS code.
To find out more about vendor prefixes, you can check http://css3please.com/, which is a great website for vendor prefixes resources.
You can add multiple animations using a comma separator. Let’s say that we want to add an additional rotation to our tutsFade
element, we'd do so by declaring extra @keyframes
and then binding them to our element:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | .element { animation: tutsFade 4 s 1 s infinite linear alternate, tutsRotate 4 s 1 s infinite linear alternate; } @keyframes tutsFade { to { opacity: 0 ; } } @keyframes tutsRotate { to { transform: rotate( 180 deg); } } |
Let’s jump in and create a simple shape transition; a square to circle animation using the above principles. We will have five stages in total and for each stage we will define a border-radius, a rotation and a different background color to our element. Enough talking, let’s jump into coding.
First, let’s create the markup, an element to animate. We're not even going to bother with class names, we're just going to use a plain div for now:
1 | < div ></ div > |
Then, using an element selector (div {}
), add default styling to the div:
1 2 3 4 5 | div { width : 200px ; height : 200px ; background-color : coral; } |
Now let’s prepare @keyframes
, which we'll call square-to-circle
, and the five stages
1 2 3 4 5 6 7 | @keyframes square-to- circle { 0% {} 25% {} 50% {} 75% {} 100% {} } |
We need to define some styes within these stages, so let's begin by dictating the border-radius
for each corner of the square:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | @-webkit-keyframes square-to- circle { 0% { border-radius: 0 0 0 0 ; } 25% { border-radius: 50% 0 0 0 ; } 50% { border-radius: 50% 50% 0 0 ; } 75% { border-radius: 50% 50% 50% 0 ; } 100% { border-radius: 50% ; } } |
Additionally we can declare a different background-color
for each stage.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 | @keyframes square-to- circle { 0% { border-radius: 0 0 0 0 ; background :coral; } 25% { border-radius: 50% 0 0 0 ; background :darksalmon; } 50% { border-radius: 50% 50% 0 0 ; background :indianred; } 75% { border-radius: 50% 50% 50% 0 ; background :lightcoral; } 100% { border-radius: 50% ; background :darksalmon; } } |
To really hit the idea home, let's go beyond border-radius
and background-color
by rotating the div and adding a little visual interest.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | @keyframes square-to- circle { 0% { border-radius: 0 0 0 0 ; background :coral; transform:rotate( 0 deg); } 25% { border-radius: 50% 0 0 0 ; background :darksalmon; transform:rotate( 45 deg); } 50% { border-radius: 50% 50% 0 0 ; background :indianred; transform:rotate( 90 deg); } 75% { border-radius: 50% 50% 50% 0 ; background :lightcoral; transform:rotate( 135 deg); } 100% { border-radius: 50% ; background :darksalmon; transform:rotate( 180 deg); } } |
Having defined our square-to-circle animation, we need to apply it to the div:
1 2 3 4 5 6 | div { width : 200px ; height : 200px ; background-color : coral; animation: square-to- circle 2 s 1 s infinite alternate; } |
Here you see we've added a shorthand animation
property, which states:
square-to-circle
.2s
.1s
.infinite
, so it will carry on indefinitely.alternate
, so it will play from beginning to end, then back to the beginning, then again to the end, and so on. One last value we can add to the animation property is the animation-timing-function
. This will define the speed, acceleration and deceleration of our movement. This function can be a very detailed value, which is awkward to calculate manually, but there are a lot of free websites which provide resources and live customisation for animation timing functions.
One such tool is the CSS Easing Animation Tool, so let's use that to calculate our timing function.
I would like to add an elastic effect to our square-to-circle
animation, using a cubic-bezier function.
Having played around with the handles and generated some kind of bezier curve, update the animation timing-function value using the snippet provided.
1 2 3 4 5 6 | div { width : 200px ; height : 200px ; background-color : coral; animation: square-to- circle 2 s 1 s infinite cubic-bezier( 1 ,. 015 ,. 295 , 1.225 ) alternate; } |
The final code, without using vendor prefixes ( -webkit-
, -moz-
, -ms-
, -o-
) is as follows:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | div { width : 200px ; height : 200px ; background-color : coral; animation: square-to- circle 2 s . 5 s infinite cubic-bezier( 1 ,. 015 ,. 295 , 1.225 ) alternate; } @keyframes square-to- circle { 0% { border-radius: 0 0 0 0 ; background :coral; transform:rotate( 0 deg); } 25% { border-radius: 50% 0 0 0 ; background :darksalmon; transform:rotate( 45 deg); } 50% { border-radius: 50% 50% 0 0 ; background :indianred; transform:rotate( 90 deg); } 75% { border-radius: 50% 50% 50% 0 ; background :lightcoral; transform:rotate( 135 deg); } 100% { border-radius: 50% ; background :darksalmon; transform:rotate( 180 deg); } } |
All works well in modern browsers, but Firefox has a nasty habit of rendering transforming objects poorly. Take a look at these jagged lines to see what I mean:
Luckily, there's a workaround for this. Add the following transparent outline to your div and Firefox will render things perfectly!
1 | outline : 1px solid transparent ; |
That's it! We've used CSS Animation syntax to create a simple, repeating animation.
For up-to-date information on the browsers support for CSS animation, check out Can I use.. but in a nutshell, supporting browsers include: Firefox 5 , IE 10 , Chrome, Safari 4 , Opera 12 .
联系客服