In the early days of the web HTML was at its humble beginnings then CSS came around and it allow web developers to add effects like color and changing text font sizes. Fast forward to the year 1995 JavaScript was invented and it opened the door for developers to add dynamic effects to a web page like Animations and Popups. The latter was heavily misused for advertisement purposes and gaining user attention.
Years passed by and JavaScript was the de facto technology for adding animations to HTML elements and developers who did not know how to program can seek the help of a JavaScript programmer to complete some part of their project that require stuff like animations.
The dependency on JavaScript for adding animations and transitions reduced when animations and transitions was added natively to CSS specifically CSS3. CSS3 technologies are set of modules and you should not be surprised that animations and transitions each have their own specifications.
With CSS animations you can move page element around, change color based on user interaction and with transitions you can change property values over a specified duration all without JavaScript.
The following HTML and CSS will be used with slight modifications along the way. Please save them and make sure the CSS is linked with the HTML.
<div class="parent">
<div class="box"></div>
</div>
.parent {
width: 70%;
outline: 5px solid #dddddd;
margin: 0 auto;
height: 500px;
}
And kindly note that all screenshots are from Firefox 70 web browser and its Developer Tools.
When starting out with CSS animations there is a particular technical term that we need to familiarize oursleves with and that is keyframes. Keyframes make animation possible.
From the specification (emphasis mine):
Keyframes are used to specify the values for the animating properties at various points during the animation . The keyframes specify the behavior of one cycle of the animation; the animation may iterate zero or more times.
That's pretty straight forward, but now the question is: How can we translate this theoretical definition to code? To answer this question we will have to know how keyframes are specified.
The specification states:
Keyframes are specified using the
@keyframes
at-rule
After the @keyframes
at rule three things have to included:
- the keyframes name
- the keyframe block
- the keyframe selector
the keyframes name
The keyframes name is the name of the animation and it can be a custom indent or a string and the name is case sensitive.
the keyframe block
This is the block that will contain code that specify how the animation will behave.
the keyframe selector
This specify the starting and ending position of the animation using a combination of from
and to
keyword or comma-separated list of percentage values.
All these can be summed up in the code snippet below:
@keyframes <keyframes name> {
/* We are inside the keyframe block */
/*
* The from and to code blocks are the keyframe
* selectors
*/
from {
/* code here*/
}
to {
/* code here*/
}
/*
* Another alternative is to use comma-seprated
* percentage values
*/
0%,20% {
/* code here */
}
20%,70% {
/* code here */
}
70%,100% {
/* code here */
}
}
If you declare multiple @keyframes
rules with the same name (i.e the animation name), the cascade comes into effect and the last one in the document order wins, while all preceding ones are ignored.
Keyframes is just part of the picture when it comes to creating animations in CSS and some properties ensure that it works as expected. They are:
animation-name
animation-duration
animation-delay
animation-iteration-count
animation-direction
animation-timing-function
animation-fill-mode
animation-play-state
animation
These properties are bound to the element that you wish to animate.
div {
/* All animation for the div element will be here */
}
Now, let's discuss these properties in detail.
animation-name
This is the name of the @keyframes
at-rule that decsribe the animation keyframes.
Update the .box
with an animation name, we'll call it slide:
.box {
/* All other properties remain the same */
/*
* "slide" will be the name given to our animation
*/
animation-name: slide;
}
animation-duration
The animation-duration
property defines how long an animation would take to complete one cycle.
We'll make the animation last for 5s
for simplicity.
.box {
/* All other properties remain the same */
animation-duration: 5s;
}
With these two properties in play we can animate the box by setting up a keyframe using the @keyframe
at rule.
The keyframe below will move the box from its current location until the top
offset property is 300px
and the left
offset property is 250px
.
@keyframes slide {
from {
top: 0; /* The box current */
left: 0; /* location */
}
to {
top: 300px; /* The box location */
left: 250px; /* during animation */
}
}
Save and refresh your browser. You will realize the box will not move. Can you guess why?
When we talked about CSS positioning we made it clear that offset properties like top
,left
have no effect on an element with its position
property set to static
.
Use "Inspect Element" on the box and you can confirm this in the Developer Tools.
A simple position: relative
applied to the box
will fix this issue.
.box {
/* All other properties remain the same */
position: relative;
}
Go ahead and save the file and refresh the browser, the box will now move as expected. You can also check the Animation tab in the browser Developer Tools to note details of the animation.
animation-delay
This specify the delay before an animation starts. This is as simple as its name.
Update your code:
.box {
/* All other properties remain the same */
animation-delay: 3s;
}
Save and refresh your browser, the animation will start after three seconds.
animation-iteration-count
By default the animation will run just once, using animation-iteration-count
we can specify the number of times an animation should run.
.box {
/* All other properties remain the same */
animation-iteration-count: 3;
}
The total execution time of this animation will be 18s
because the animation-duration
is 5s
and the animation will run three times which gives us:
- 3 * 15 = 15s
Added to the animation-delay
of 3s
we get:
- 15s + 3 = 18s
You can confirm this in the Developer Tools after the animation execution.
animation-direction
As the name implies the animation-direction
determines the direction of the animation which can be any of the following:
-
normal
- This is the default and the animation played as normal (forwards) -
reverse
- The animation is played in reverse direction -
alternate
- This combine the behavior ofnormal
andreverse
and the animation is played forwards first and then backwards -
alternate-reverse
- This is opposite ofalternate
and the animation is played backwards first then forwards
The effect of this property is really cool. If you want you can delete the animation-delay
property just to speed things up.
.box {
/* All other properties remain the same */
animation-direction: alternate;
}
Save and refresh your browser.
You should experiment with the remaining values.
animation-timing-function
From the specification:
The
animation-timing-function
property describes how the animation will progress between each pair of keyframes
"How the animation will progress" means how fast or how slow an animation will start and end.
The animation-timing-function
accepts the following values:
-
ease
- This is the default value and the animation will start slow, then fast, then end slowly -
linear
- The animation will start and end with the same speed -
ease-in
- The specifies an animation with a slow start -
ease-out
- This is opposite ofease-in
and it specifies an animation with a slow end -
ease-in-out
- This combine the behavior ofease-in
andease-in-out
therefore the animation will have a slow start and end
.box {
/* All other properties remain the same */
animation-timing-funtion: ease-in-out;
}
Note the speed of the animation at the beginning and at the end.
animation-fill-mode
From the specification:
The
animation-fill-mode
property defines what values are applied by the animation outside the time it is executing.
This is quite tricky, so let's do some explanation.
By default CSS animations do not affect an element before the first keyframe or after the last keyframe.
The first keyframe means any code inside the from
code block or comma-separated percentage values and the last keyframe means the code inside the to
code block or comma-separated percentage values.
Using animation-fill-mode
we can override this behavior and the animation can still be in effect after its execution time.
The animation-fill-mode
property accept the following values:
-
none
- This is the default value. Animation will not apply any styles to the element before or after it is executing -
forwards
- The element will retain the style values that is set by the last keyframe -
backwards
- The element will get the style values that is set by the first keyframe -
both
- The animation will follow the rules for both forwards and backwards, extending the animation properties in both directions
.box {
/* All other properties remain the same */
animation-fill-mode: forwards;
}
Observe the result in the browser and take note of the execution time of 15s
(excluding animation delay) which means the animation has completed but with the animation-fill-mode
in play the box retains the last keyframe of the animation.
animation-play-state
This specify whether the animation is running or paused.
It accepts the following value:
running
-
paused
.box {
/* All other properties remain the same */
animation-play-state: paused;
}
Save and refresh your browser, you will realize the box will not move as the animation is paused.
You can click the play button in the Developer Tools to run the animation.
animation
This is the shorthand for animation-name
, animation-duration
, animation-timing-function
, animation-delay
, animation-iteration-count
, animation-direction
in that particular order.
Armed with this we can re-write our code as
.box {
/* All non-animation properties remain the same */
/*
* 1. animation-name
* 2. animation-duration
* 3. animation-timing-function
* 4. animation-delay
* 5. animation-iteration-count
* 6. animation-direction
*/
/*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/
animation: slide 3s ease-in-out 3s 3 alternate;
You should know that all these properties are ignored in the keyframe block, with the exception of animation-timing-function
.
@keyframes slide {
/*
* All animation properties like animation-delay and
* animation-duration are ignored in this block with
* the exception of the animation-timing-function.
*
*/
}
CSS TRANSITIONS
CSS Transitions are presentation effects and they allow property changes in CSS values to occur smoothly over a specified duration.
To create a transition effect, two requirement must be satisfied:
- A CSS property
- The duration of the effect
The following properties are used to create transitions:
transition-poperty
transition-duration
transition-timing-function
transition-delay
transition
transition-poperty
The transition-property
specifies the name(s) of the CSS properties to which transitions should be applied.
You should comment or delete the keyframes and all related animation properties from the box before proceeding.
Now update the .box
with the following:
.box {
/*
* All non-animation properties remain the same
* with the exception of the background-color which
* has been updated to #1560bd
*
*/
transition-property: height;
}
transition-duration
The duration over which the transition should occur.
.box {
/* All other properties remain the same */
transition-duration: 3s;
}
At this point we can see some transition effect based on human interaction. We'll check when the user Mouse over the box and then increase its height.
.box:hover {
height: 200px;
}
The effect in the browser when the user mouse over the box:
transition-timing-function
This is similar to animation-timing-function
and it specifies the speed of the transition.
Thetransition-timing-function
accepts the following value:
ease
linear
ease-in
ease-out
ease-in-out
step-end
step-start
- the
steps()
function
These values have been explained earlier with the exception of step-end
, step-start
and the steps()
function.
The best way to understand step-*
family of values is to write to some code.
Update your code with snippet below and don't forget to save.
.box {
/* All other properties remain the same */
transition-timing-function: step-end;
}
Switch over to your browser and Mouse over the box, the height of the box will increase sharply at the end of the duration specified with the transition-duration
.
Make sure you have the Developer Tools opened and you've switched to the Animation tab.
The step-start
is the opposite of step-end
and the animation will occur instantaneously when you Mouse over the box.
On the other hand the steps()
function allow you to specify the number of steps the animation should take. It accepts two parameters:
- The number of steps e.g 2, 3
- A timing function value between
step-start
andstep-end
specified by eliminating thestep-
prefix.
Switch to your code editor and update your code:
.box {
/* All other properties remain the same */
transition-timing-function: steps(2, start);
}
Observe the steps in the second panel of the Developer Tools. The steps in the third panel indicate the step is applied at the beginning of the animation.
If you update the value to steps(2, end)
the step direction will be different.
transition-delay
The transition-delay
property specifies a delay (in seconds) for the transition effect.
.box {
/* All other properties remain the same */
transition-delay: 3s;
}
In the image below the blue part in the second panel indicate when the transition will start as a result of the transition-delay
property.
transition
This is shorthand for setting transition-property
, transition-duration
, transition-timing-function
, transition-delay
in that particular order.
.box {
/*
* 1. transition-property
* 2. transition-duration
* 3. transition-timing-funtion
* 4. transition-delay
*/
/*1*/ /*2*/ /*3*/ /*4*/
transition: height 3s step-start 3s;
}
We've come along way but i have left out the following as they seem advanced:
-
cubic-bezier()
- used in the timing function for both animations and transitions - Transforms - When transforms are combined with transitions and animations, some cool effects can be created
- Applying transitions to more than one property
- Using
animation-timing-function
inside a keyframe.
If you are feeling adventurous you can read Andreas Müller post on CSS animation by creating some loaders.
Learn CSS animation by creating pure CSS loaders
Andreas ・ Nov 26 '19
The next topic is more of theory than code and it's about Naming Conventions in CSS.