CSS properties are characteristics of an element in a markup language (HTML, SVG, XML, and so on) that control their style and/or presentation. These characteristics are part of a constantly evolving standard from the W3C.
A basic example of a CSS property is border-radius
:
input {
border-radius: 100px;
}
There is an incredible number of CSS properties, and learning them all is virtually impossible. Adding more into this mix, there are CSS properties that need to be vendor prefixed (-webkit-
, -moz-
, -ms-
, and so on), making this equation even more complex.
Vendor prefixes are short pieces of CSS that are added to the beginning of the CSS property (and sometimes CSS values too). These pieces of code are directly related to either the company that makes the browser (the "vendor") or to the CSS engine of the browser.
There are four major CSS prefixes: -webkit-
, -moz-
, -ms-
and -o-
. They are explained here:
Google Chrome and Opera both support the -webkit-
prefix. However, these two browsers do not use the Webkit engine anymore. Their engine is called Blink and is developed by Google.
A basic example of a prefixed CSS property is column-gap
:
.column { -webkit-column-gap: 5px; -moz-column-gap: 5px; column-gap: 5px; }
Knowing which CSS properties need to be prefixed is futile. That's why it's important to keep a constant eye on CanIUse.com. However, it's also important to automate the prefixing process with tools such as Autoprefixer
or -prefix-free
, or mixins in preprocessors, and so on.
However, vendor prefixing isn't in the scope of the book, so the properties we'll discuss are absent of any vendor prefixes. If you want to learn more about vendor prefixes, you can visit Mozilla Developer Network (MDN) at http://tiny.cc/mdn-vendor-prefixes.
Let's get the CSS properties reference rolling.
Unlike the old days of Flash, where creating animations required third-party applications and plugins, today we can accomplish practically the same things with a lot less overhead, better performance, and greater scalability all through CSS only.
Forget plugins and third-party software! All we need is a text editor, some imagination, and a bit of patience to wrap our heads around some of the animation concepts CSS brings to our plate.
Before we dive into all the animation properties, we will use the following markup and animation structure as our base:
HTML:
<div class="element"></div>
CSS:
.element { width: 300px; height: 300px; } @keyframes fadingColors { 0% { background: red; } 100% { background: black; } }
In the examples, we will only see the .element
rule since the HTML and @keyframes fadingColors
will remain the same.
Ok, let's do this.
The animation-name
CSS property is the name of the @keyframes
at-rule that we want to execute, and it looks like this:
animation-name: fadingColors;
In the HTML and CSS base example, our @keyframes
at-rule had an animation where the background color went from red to black. The name of that animation is fadingColors
.
So, we can call the animation like this:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
}
This is a valid rule using the longhand. There are clearly no issues with it at all. The thing is that the animation won't run unless we add animation-duration
to it.
The
animation-duration
CSS property defines the amount of time the animation will take to complete a cycle, and it looks like this:
animation-duration: 2s;
We can specify the units either in seconds using s
or in milliseconds using ms
. Specifying a unit is required. Specifying a value of 0s
means that the animation should actually never run.
However, since we do want our animation to run, we do the following:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
}
As mentioned earlier, this will make a box go from its red background to black in 2
seconds and then stop.
The
animation-iteration-count
CSS property defines the number of times the animation should be played, and it looks like this:
animation-iteration-count: infinite;
Here are two values: infinite
and a number, such as 1
, 3
, or 0.5
. Negative numbers are not allowed.
Add the following code to the prior example:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
}
This will make a box go from its red background to black, start over again with the red background and go to black, infinitely.
The
animation-direction
CSS property defines the direction in which the animation should play after the cycle, and it looks like this:
animation-direction: alternate;
There are four values: normal
, reverse
, alternate
, and alternate-reverse
.
normal
: This makes the animation play forward. This is the default value.reverse
: This makes the animation play backward.alternate
: This makes the animation play forward in the first cycle, then backward in the next cycle, then forward again, and so on. In addition, timing functions are affected, so if we have ease-out
, it gets replaced by ease-in
when played in reverse.We'll look at these timing functions in a minute.
alternate-reverse
: This is the same thing as alternate
, but the animation starts backward, from the end.In our current example, we have a continuous animation. However, the background color has a "hard stop" when going from black (end of the animation) to red (start of the animation).
Let's create a more "fluid" animation by making the black background fade into red and then red into black without any hard stops. Basically, we are trying to create a "pulse-like" effect:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
The
animation-delay
CSS property allows us to define when exactly an animation should start. This means that as soon as the animation has been applied to an element, it will obey the delay before it starts running.
It looks like this:
animation-delay: 3s;
We can specify the units either in seconds using s
or in milliseconds using ms
. Specifying a unit is required.
Negative values are allowed. Take into consideration that using negative values means that the animation should start right away, but it will start midway into the animation for the opposite amount of time as the negative value.
Use negative values with caution.
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
}
This will make the animation start after 3 seconds have passed.
The
animation-fill-mode
CSS property defines which values are applied to an element before and after the animation. Basically, outside the time the animation is being executed.
It looks like this:
animation-fill-mode: none;
There are four values: none
, forwards
, backwards
, and both
.
none
: No styles are applied before or after the animation.forwards
: The animated element will retain the styles of the last keyframe. This the most used value.backwards
: The animated element will retain the styles of the first keyframe, and these styles will remain during the animation-delay
period. This is very likely the least used value.both
: The animated element will retain the styles of the first keyframe before starting the animation and the styles of the last keyframe after the animation has finished. In many cases, this is almost the same as using forwards
.The prior properties are better used in animations that have an end and stop. In our example, we're using a fading/pulsating animation, so the best property to use is none
.
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
}
The
animation-play-state
CSS property defines whether an animation is running or paused, and it looks like this:
animation-play-state: running;
There are two values: running
and paused
. These values are self-explanatory.
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
}
In this case, defining animation-play-state
as running
is redundant, but I'm listing it for purposes of the example.
The
animation-timing-function
CSS property defines how an animation's speed should progress throughout its cycles, and it looks like this:
animation-timing-function: ease-out;
There are five predefined values, also known as easing functions, for the Bézier curve (we'll see what the Bézier curve is in a minute): ease
, ease-in
, ease-out
, ease-in-out
, and linear
.
The ease
function sharply accelerates at the beginning and starts slowing down towards the middle of the cycle, and it looks like this:
animation-timing-function: ease;
The
ease-in
function starts slowly accelerating until the animation sharply ends, and it looks like this:
animation-timing-function: ease-in;
The
ease-out
function starts quickly and gradually slows down towards the end and it looks like this:
animation-timing-function: ease-out;
The
ease-in-out
function starts slowly and it gets fast in the middle of the cycle. It then starts slowing down towards the end. And it looks like this:
animation-timing-function:ease-in-out;
The
linear
function has constant speed. No accelerations of any kind happen. It looks like this:
animation-timing-function: linear;
Now, the easing functions are built on a curve named the Bézier curve and can be called using the cubic-bezier()
function or the steps()
function.
The
cubic-bezier()
function allows us to create custom acceleration curves. Most use cases can benefit from the already defined easing functions we just mentioned (ease
, ease-in
, ease-out
, ease-in-out
and linear
), but if you're feeling adventurous, cubic-bezier()
is your best bet.
Here's what a Bézier curve looks like:
The
cubic-bezier()
function takes four parameters as follows:
animation-timing-function: cubic-bezier(x1, y1, x2, y2);
X and Y represent the x and y axes. The numbers 1
and 2
after each axis represent the control points. 1
represents the control point starting on the lower left, and 2
represents the control point on the upper right.
Let's represent all five predefined easing functions with the cubic-bezier()
function:
animation-timing-function: cubic-bezier(.25, .1, .25, 1);
animation-timing-function: cubic-bezier(.42, 0, 1, 1);
animation-timing-function: cubic-bezier(0, 0, .58, 1);
animation-timing-function: cubic-bezier(.42, 0, .58, 1);
animation-timing-function: cubic-bezier(0, 0, 1, 1);
I'm not sure about you, but I prefer to use the predefined values.
Now, we can start tweaking and testing each value to the decimal, save it, and wait for the live refresh to do its thing. However, that's too much time wasted testing if you ask me.
The amazing Lea Verou created the best web app to work with Bézier curves. You can find it at cubic-bezier.com. This is by far the easiest way to work with Bézier curves. I highly recommend this tool.
The Bézier curve image showed earlier was taken from the cubic-bezier.com website.
Let's add animation-timing-function
to our example:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: ease-out;
}
The
steps()
timing function isn't very widely used, but knowing how it works is a must if you're into CSS animations.
It looks like this:
animation-timing-function: steps(6);
This function is very helpful when we want our animation to take a defined number of steps.
After adding a steps()
function to our current example, it looks like this:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: steps(6);
}
This makes the box take six steps to fade from red to black and vice versa.
There are two optional parameters that we can use with the steps()
function: start
and end
.
start
: This will make the animation run at the beginning of each step. This will make the animation start right away.end
: This will make the animation run at the end of each step. This is the default value if nothing is declared. This will give the animation a short delay before it starts.After adding a steps()
function to our current example, it looks like this:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: steps(6, start);
}
Granted, the pulsating effect in our example isn't quite noticeable when we add the steps()
function. However, you can see it more clearly in this pen from Louis Lazarus when hovering over the boxes, at http://tiny.cc/steps-timing-function
Here's an image taken from Stephen Greig's article in Smashing Magazine, Understanding CSS Timing Functions, that explains start
and end
from the steps()
function:
Also, there are two predefined values for the steps()
function: step-start
and step-end
.
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: step-end;
}
The
animation
CSS property is the shorthand for animation-name
, animation-duration
, animation-timing-function
, animation-delay
, animation-iteration-count
, animation-direction
, animation-fill-mode
, and animation-play-state
.
animation: fadingColors 2s;
For a simple animation to work, we need at least two properties: animation-name
and animation-duration
.
If you feel overwhelmed by all these properties, relax. Let me break them down for you in simple bits.
Using the animation
longhand, the code would look like this:
CSS:
.element { width: 300px; height: 300px; animation-name: fadingColors; animation-duration: 2s; }
Using the animation
shorthand, which is the recommended syntax, the code would look like this:
CSS:
.element {
width: 300px;
height: 300px;
animation: fadingColors 2s;
}
This will make a box go from its red background to black in 2 seconds, and then stop.
Let's see how all the animation properties look in one final example showing both the longhand and shorthand styles.
.element { width: 300px; height: 300px; animation-name: fadingColors; animation-duration: 2s; animation-iteration-count: infinite; animation-direction: alternate; animation-delay: 3s; animation-fill-mode: none; animation-play-state: running; animation-timing-function: ease-out; }
.element { width: 300px; height: 300px; animation: fadingColors 2s infinite alternate 3s none running ease-out; }
Here is a demo in CodePen: http://tiny.cc/animation
3.144.39.144