# CSS-animations
CSS animations allow to do simple animations without JavaScript at all.
JavaScript can be used to control CSS animation and make it even better with a little of code.
## CSS transitions [#css-transition]
The idea of CSS transitions is simple. We describe a property and how its changes should be animated. When the property changes, the browser paints the animation.
That is: all we need is to change the property. And the fluent transition is made by the browser.
For instance, the CSS below animates changes of `background-color` for 3 seconds:
```css
.animated {
transition-property: background-color;
transition-duration: 3s;
}
```
Now if an element has `.animated` class, any change of `background-color` is animated during 3 seconds.
Click the button below to animate the background:
```html run autorun height=60
```
There are 4 properties to describe CSS transitions:
- `transition-property`
- `transition-duration`
- `transition-timing-function`
- `transition-delay`
We'll cover them in a moment, for now let's note that the common `transition` property allows to declare them together in the order: `property duration timing-function delay`, and also animate multiple properties at once.
For instance, this button animates both `color` and `font-size`:
```html run height=80 autorun no-beautify
```
Now let's cover animation properties one by one.
## transition-property
In `transition-property` we write a list of property to animate, for instance: `left`, `margin-left`, `height`, `color`.
Not all properties can be animated, but [many of them](http://www.w3.org/TR/css3-transitions/#animatable-properties-). The value `all` means "animate all properties".
## transition-duration
In `transition-duration` we can specify how long the animation should take. The time should be in [CSS time format](http://www.w3.org/TR/css3-values/#time): in seconds `s` or milliseconds `ms`.
## transition-delay
In `transition-delay` we can specify the delay *before* the animation. For instance, if `transition-delay: 1s`, then animation starts after 1 second after the change.
Negative values are also possible. Then the animation starts from the middle. For instance, if `transition-duration` is `2s`, and the delay is `-1s`, then the animation takes 1 second and starts from the half.
Here's the animation shifts numbers from `0` to `9` using CSS `translate` property:
[codetabs src="digits"]
The `transform` property is animated like this:
```css
#stripe.animate {
transform: translate(-90%);
transition-property: transform;
transition-duration: 9s;
}
```
In the example above JavaScript adds the class `.animate` to the element -- and the animation starts:
```js
stripe.classList.add('animate');
```
We can also start it "from the middle", from the exact number, e.g. corresponding to the current second, using the negative `transition-delay`.
Here if you click the digit -- it starts the animation from the current second:
[codetabs src="digits-negative-delay"]
JavaScript does it by an extra line:
```js
stripe.onclick = function() {
let sec = new Date().getSeconds() % 10;
*!*
// for instance, -3s here starts the animation from the 3rd second
stripe.style.transitionDelay = '-' + sec + 's';
*/!*
stripe.classList.add('animate');
};
```
## transition-timing-function
Timing function describes how the animation process is distributed along the time. Will it start slowly and then go fast or vise versa.
That's the most complicated property from the first sight. But it becomes very simple if we devote a bit time to it.
That property accepts two kinds of values: a Bezier curve or steps. Let's start from the curve, as it's used more often.
### Bezier curve
The timing function can be set as a [Bezier curve](/bezier-curve) with 4 control points that satisfies the conditions:
1. First control point: `(0,0)`.
2. Last control point: `(1,1)`.
3. For intermediate points values of `x` must be in the interval `0..1`, `y` can be anything.
The syntax for a Bezier curve in CSS: `cubic-bezier(x2, y2, x3, y3)`. Here we need to specify only 2nd and 3rd control points, because the 1st one is fixed to `(0,0)` and the 4th one is `(1,1)`.
The timing function describes how fast the animation process goes in time.
- The `x` axis is the time: `0` -- the starting moment, `1` -- the last moment of `transition-duration`.
- The `y` axis specifies the completion of the process: `0` -- the starting value of the property, `1` -- the final value.
The simplest variant is when the animation goes uniformly, with the same linear speed. That can be specified by the curve `cubic-bezier(0, 0, 1, 1)`.
Here's how that curve looks:

...As we can see, it's just a straight line. As the time (`x`) passes, the completion (`y`) of the animation steadily goes from `0` to `1`.
The train in the example below goes from left to right with the permanent speed (click it):
[codetabs src="train-linear"]
The CSS `transition` is based on that curve:
```css
.train {
left: 0;
transition: left 5s cubic-bezier(0, 0, 1, 1);
/* JavaScript sets left to 450px */
}
```
...And how can we show a train slowing down?
We can use another Bezier curve: `cubic-bezier(0.0, 0.5, 0.5 ,1.0)`.
The graph:

As we can see, the process starts fast: the curve soars up high, and then slower and slower.
Here's the timing function in action (click the train):
[codetabs src="train"]
CSS:
```css
.train {
left: 0;
transition: left 5s cubic-bezier(0, .5, .5, 1);
/* JavaScript sets left to 450px */
}
```
There are several built-in curves: `linear`, `ease`, `ease-in`, `ease-out` and `ease-in-out`.
The `linear` is a shorthand for `cubic-bezier(0, 0, 1, 1)` -- a straight line, we saw it already.
Other names are shorthands for the following `cubic-bezier`:
| ease
* | ease-in
| ease-out
| ease-in-out
|
|-------------------------------|----------------------|-----------------------|--------------------------|
| (0.25, 0.1, 0.25, 1.0)
| (0.42, 0, 1.0, 1.0)
| (0, 0, 0.58, 1.0)
| (0.42, 0, 0.58, 1.0)
|
|  |  |  |  |
`*` -- by default, if there's no timing function, `ease` is used.
So we could use `ease-out` for our slowing down train:
```css
.train {
left: 0;
transition: left 5s ease-out;
/* transition: left 5s cubic-bezier(0, .5, .5, 1); */
}
```
But it looks a bit differently.
**A Bezier curve can make the animation "jump out" of its range.**
The control points on the curve can have any `y` coordinates: even negative or huge. Then the Bezier curve would also jump very low or high, making the animation go beyond its normal range.
In the example below the animation code is:
```css
.train {
left: 100px;
transition: left 5s cubic-bezier(.5, -1, .5, 2);
/* JavaScript sets left to 400px */
}
```
The property `left` should animate from `100px` to `400px`.
But if you click the train, you'll see that:
- First, the train goes *back*: `left` becomes less than `100px`.
- Then it goes forward, a little bit farther than `400px`.
- And then back again -- to `400px`.
[codetabs src="train-over"]
Why it happens -- pretty obvious if we look at the graph of the given Bezier curve:

We moved the `y` coordinate of the 2nd point below zero, and for the 3rd point we made put it over `1`, so the curve goes out of the "regular" quadrant. The `y` is out of the "standard" range `0..1`.
As we know, `y` measures "the completion of the animation process". The value `y = 0` corresponds to the starting property value and `y = 1` -- the ending value. So values `y<0` move the property lower than the starting `left` and `y>1` -- over the final `left`.
That's a "soft" variant for sure. If we put `y` values like `-99` and `99` then the train would jump out of the range much more.
But how to make the Bezier curve for a specific task? There are many tools. For instance, we can do it on the site