Historically, whenever elements needed to be moved or animated around the screen, it was the sole domain of JavaScript. Nowadays, CSS can handle the majority of motion jobs via three principal agents: CSS transitions, CSS transforms, and CSS animations. In fact, only transitions and animations are directly related to motion, transforms simply allow us to change elements, but as we shall see, they are often integral to successful motion effects.
To clearly understand what each of these things is responsible for, I will offer this, perhaps overly simplistic summary:
Right, so we had better crack on and get our heads around how we can wield all these capabilities. In this chapter, we'll cover:
ease, cubic-bezier, and so on)scale, rotate, skew, translate, and so on)keyframesTransitions are the simplest way to create some visual 'effect' between one state and another with CSS. Let's consider a simple example, an element that transitions from one state to another when hovered over.
When styling hyperlinks in CSS, it's common practice to create a hover state; an obvious way to make users aware that the item they are hovering over is a link. Hover states are of little relevance to the growing number of touch screen devices but for mouse users, they're a great and simple interaction between website and user. They're also handy for illustrating transitions, so that's what we will start with.
Traditionally, using only CSS, hover states are an on/off affair. There is one set of properties and values on an element as the default, and when a pointer is hovered over that element, the properties and values are instantly changed. However, CSS3 transitions, as the name implies, allow us to transition between one or more properties and values to other properties and values.
A couple of important things to know up front. Firstly, you can't transition from display: none;. When something is set to display: none; it isn't actually 'painted' on the screen so has no existing state you can transition from. In order to create the effect of something fading in, you would have to transition opacity or position values. Secondly, not all properties can be transitioned. To ensure you're not attempting the impossible, here is the list of transitionable (I know, it's not even a word) properties: http://www.w3.org/TR/css3-transitions/
If you open up example_08-01 you'll see a few links in a nav. Here's the relevant markup:
<nav>
<a href="#">link1</a>
<a href="#">link2</a>
<a href="#">link3</a>
<a href="#">link4</a>
<a href="#">link5</a>
</nav>And here's the relevant CSS:
a {
font-family: sans-serif;
color: #fff;
text-indent: 1rem;
background-color: #ccc;
display: inline-flex;
flex: 1 1 20%;
align-self: stretch;
align-items: center;
text-decoration: none;
transition: box-shadow 1s;
}
a + a {
border-left: 1px solid #aaa;
}
a:hover {
box-shadow: inset 0 -3px 0 #CC3232;
}And here are the two states, first the default:

And then here's the hover state:

In this example, when the link is hovered over, we add a red box-shadow at the bottom (I chose a box-shadow as it won't affect the layout of the link like a border might). Ordinarily, hovering over the link snaps from the first state (no red line) to the second (red line); it's an on/off affair. However, this line:
transition: box-shadow 1s;
Adds a transition to the box-shadow from the existing state to the hover state over 1 second.
You'll notice in the CSS of the preceding example we're using the adjacent sibling selector +. This means if a selector (an anchor tag in our example) directly follows another selector (another anchor tag) then apply the enclosed styles. It's useful here as we don't want a left border on the first element.
Note that the transition property is applied in the CSS to the original state of the element, not the state the element ends up as. More succinctly, apply the transition declaration on the 'from' state, not the 'to' state. This is so that different states such as :active can also have different styles set and enjoy the same transition.
A transition can be declared using up to four properties:
transition-property: The name of the CSS property to be transitioned (such as background-color, text-shadow, or all to transition every possible property).transition-duration: The length of time over which the transition should occur (defined in seconds, for example .3s, 2s, or 1.5s).transition-timing-function: How the transition changes speed during the duration (for example ease, linear, ease-in, ease-out, ease-in-out, or cubic-bezier).transition-delay: An optional value to determine a delay before the transition commences. Alternatively, a negative value can be used to commence a transition immediately but part way through its transition 'journey'. It's defined in seconds, for example, .3s, 1s, or 2.5s.Used separately, the various transition properties can be used to create a transition like this:
.style {
/*...(more styles)...*/
transition-property: all;
transition-duration: 1s;
transition-timing-function: ease;
transition-delay: 0s;
}We can roll these individual declarations into a single, shorthand version:
transition: all 1s ease 0s;
One important point to note when writing the shorthand version is that the first time related value is given is always taken to be the transition-duration. The second time related value is taken to be the transition-delay. The shorthand version is the one I tend to favor as I generally only need to define the duration of the transition and the properties that should be transitioned.
It's a minor point, but only define the property or properties you actually need to transition. It's really handy to just set all but if you only need to transition the opacity, then only define the opacity as the transition property. Otherwise you're making the browser work harder than necessary. In most cases this isn't a big deal but if you're hoping to have the best performing site possible, especially on older devices, then every little helps.
Transitions are very well supported but, as ever, ensure you have a tool like Autoprefixer set up to add any vendor prefixes relevant to the browsers you need to support. You can also check which browsers support the various capabilities at caniuse.com.
The short version:
Transitions and 2D transforms work everywhere apart from IE9 and below, 3D transforms work everywhere except IE9 and below, Android 2.3 and below, and Safari 3.2 and below.
Where a rule has multiple properties declared you don't have to transition all of them in the same way. Consider this rule:
.style {
/* ...(more styles)... */
transition-property: border, color, text-shadow;
transition-duration: 2s, 3s, 8s;
}Here we have specified with the transition-property that we'd like to transition the border, color, and text-shadow. Then with the transition-duration declaration, we are stating that the border should transition over 2 seconds, the color over 3 seconds, and the text-shadow over 8 seconds. The comma-separated durations match the comma-separated order of the transition properties.
When you declare a transition, the properties, durations, and delays are relatively simple to understand. However, understanding what each timing function does can be a little trickier. Just what do ease, linear, ease-in, ease-out, ease-in-out, and cubic-bezier actually do? Each of them is actually a pre-defined cubic-bezier curve, essentially the same as an easing function. Or, more simplistically, a mathematical description of how the transition should look. It's generally easier to visualize these curves so I recommend you head over to http://cubic-bezier.com/ and http://easings.net/.
Both these sites let you compare timing functions and see the difference each one makes. Here is a screenshot of http://easings.net—you can hover over each line for a demonstration of the easing function.

However, even if you can write your own cubic-bezier curves blindfolded, the likelihood is, for most practical situations, it makes little difference. The reason being that, like any enhancement, it's necessary to employ transition effects subtly. For 'real world' implementations, transitions that occur over too great a period of time tend to make a site feel slow. For example, navigation links that take 5 seconds to transition are going to frustrate, rather than wow your users. The perception of speed is incredibly important for our users and you and I must concentrate on making websites and applications feel as fast as possible.
Therefore, unless there is a compelling reason to do so, using the default transition (ease) over a short interval is often best; a maximum of 1 second is my own preference.
Did you ever have one of those occasions growing up when one parent was out for the day and the other parent said something to the effect of, "OK, while your mom/dad are out we're going to put sugar all over your breakfast cereal but you have to promise not to tell them when they come back"? I'm certainly guilty of that with my little ankle biters. So here's the thing. While no one is looking, let's have a bit of fun. I don't recommend this for production, but try adding this to your responsive project.
* {
transition: all 1s;
}Here, we are using the CSS universal selector * to select everything and then setting a transition on all properties for 1 second (1s). As we have omitted to specify the timing function, ease will be used by default and there will be no delay as again, a default of 0 is assumed if an alternative value is not added. The effect? Well, try resizing your browser window and most things (links, hover states, and the like) behave as you would expect. However, because everything transitions, it also includes any rules within media queries, so as the browser window is resized, elements sort of flow from one state to the next. Is it essential? Absolutely not! Is it fun to watch and play around with? Certainly! Now, remove that rule before your mom sees it!