Recently, I walked you through how to create a simple landing page that used a couple different CSS animation techniques. “Animation” is a loose term, in web design usually referring to anything that involves movement. CSS transitions are one tool we are given to manipulate elements on state changes or mouse events, and when combines with transform, can resize, rotate, skew or flip elements to create a variety of interactions and effects. In this tutorial, you’ll learn a simple way to create CSS animation with transitions and transforms.

Transitions vs Keyframes

CSS gives us two primary ways of animating elements. Transition and transform manipulate from one state to another, while animation paired with @keyframes rules can set multiple style rules at various points throughout the animation duration.

  • transform and animate performs the change
  • @keyframes defines when it happens
  • transition defines how it happens

In this tutorial, we’ll focus on what you can do with transition. Next week, I’ll go over animation keyframes and how you can create even more complex and awesome events using many of the things you learn here.


For a transition to take place, an element must have a change in state, and a different property value has to be declared on that state change. You’re probably familiar with how this works for pseudo-classes such as :hover, and have used a snippet like this one to make link hover color changes more elegant:

    color: #777777;

    color: #000000;
    transition: all ease-in-out .3s;

As you can see here, transition is always declared on the state-change rule.

Transition Shorthand

There are four transition-related sub-properties: transition-property, transition-duration, transition-timing-function, and transition-delay. Not all of these are required to build a transition, and can be put together into one declaration like this:

transition: property | duration | timing-function | delay;

For example:

transition: background .2s linear;

This says, transition the background defined on is element’s original state to the background defined on this state over .2 seconds in a linear fashion. The order is important as the first time value id assigned to the transition-duration, and the second time value is assigned to transition-delay.

Transition Property Dependency

    background-color: #EEE;
    color: #999;
    padding: 10px;
    transition: background-color .2s ease-in;
   background-color: #f53232;
   color: #FFF;

In an example like this one, you can see the original style set on .example, along with the transition. In the :hover style, we set a different background color and text color. Now on mouse hover of the .example element, the background color will transition using ease-in over .2 seconds. Let’s take a closer look at what these values mean:

Transition Property

The transition-property value tells our transition which property of the element’s original style to transform. Of course, for it to work, there needs to be a matching property on the element’s other states. A box with a background color needs a background color on hover if that is the state change you want to trigger the transition.

By default, transition will attempt to transition all of the element’s properties if this value is not set, or is set to all. Setting a transition-property value is useful if we want to set different timing, function or delay for different properties, which we can do by separating each with a comma:

transition: background .2s linear, border-radius 1s ease-in 1s; 

Transitions can be applied a wide variety of CSS properties such as opacity, border, height, width, font-size or any property with an identifiable halfway point. The font-family property is an example of a property that can’t be transitioned since it has no mid-point – it doesn’t exist on a numerical scale.

One property that can really spice up our transitions is transform, but first let’s take a closer look at the rest of the transition syntax first:

Transition Duration

The transition-duration value sets how long the transition lasts and can be written using general timing values, including seconds s and milliseconds ms. The lower the timing value, the faster the duration. For example, a good median is .3s, whereas 1s is much slower.

See the Pen Translation Delay by Vail (@vailjoy) on CodePen.27486

View Full Screen

Transition Timing AKA Transition Effects

To simplify it for those of us who are mathematically challenged, transition-timing values determine how the element behaves while it is being transitioned.

Each transition effect is created by a cubic bezier (curvy line) or, in the case of linear, a straight line. This can be as literal as something moving across the screen a certain way, or as subtle as the pulse of a hover effect. The most commonly used transition timing functions include linear, ease-in, ease-out, and ease-in-out.

See the Pen CSS transition-timing-function Examples by Vail (@vailjoy) on CodePen.27486

View Full Screen

Custom Timing

You can get creative with transition-timing by setting the cubic-bezier(x1, y1, x2, y2) value. Here is a look at the transition used on the last hamster in the above demo:

transition:  all 4s cubic-bezier(1.000, -0.530, 0.405, 1.425);

The excellent Ceaser CSS Easing Tool makes it very easy to test and generate your own cubic-bezier snippets.

Transition Delay

Setting a transition-delay is optional and useful if you want the transition to wait a bit before playing. Like transition-duration, transition-delay is set using general timing values like seconds s or fractions of seconds.

This allows us to animate the properties independently of each other, meaning that this simple technique can be used to create very complex animations.

See the Pen Alien Invasion: CSS Transition Delay Demo by Vail (@vailjoy) on CodePen.27486

View Full Screen


Transform is a CSS3 property that allows us to change the appearance of an element. When used on static elements, they can do things like help vertically center content within its parent, create perspective or resize an image.

When used on a state change such as a hover, transforms can be paired with transitions or animation keyframes to achieve simple animations – without a transition in the mix, the transform lacks grace and will appear too abruptly.

See the Pen CSS Transforms by Vail (@vailjoy) on CodePen.27486

View Full Screen

In this demo, a simple ease transition is used to make each transform appear smooth. The transition is declared on the element’s original style rule, whereas the changed transform is applied to the state change rule.

  transform: scale(1, 1);
  transition: transform 0.5s ease;
.box:hover .scale{
  transform: scale(1.5, 1.5);

Here is a rundown of transform functions and what they do:


scale() makes an element larger or smaller and can be set to specifically affect the width (X-axis) or height (Y-axis).

  • To set a scale for just one axis, you can define X or Y on the property. For example, transform: scaleX(2).
  • To combine different values for X an Y, separate them with a comma. For example, transform: scale(1, 2);


rotate() rotates the element clockwise with a positive value, such as 90deg, or rotates the element counter-clockwise with a negative value, such as -90deg.

  • You can spin an element beyond one rotation by using a value over 360.


translate() value moves an element based on the values given for the X (horizontal) and/or Y (vertical) axes. Positive X and Y values move the element to the right or downwards, respectively.Negative X and Y values move the element to the left or upwards. The values themselves can be any length unit in CSS such as pixels, precentages or rems.

  • To set a translate for just one axis, you can define X or Y on the property. For example, transform: translateX(50%);.
  • To combine different values for X an Y, separate them with a comma. For example, transform: translate(20px, 50px);
  • You can also use 3d values


skew() tilts the element based on the values given for the X and Y axes. A positive X value tilts the element left, a negative X value tilts it right. A positive Y value tilts it down, and a negative Y value tilts it up.

  • To set a translate for just one axis, you can define X or Y on the property. For example, transform: translateX(50%);.
  • To combine different values for X an Y, separate them with a comma. For example, transform: translate(20px, 50px);


By default, transforms use the center of your element as the origin point, or anchor. The transform-origin property allows us to change that.

For example, if you are using the transform: rotate(); property but want it to rotate not from the center, but from the top left corner, you’d use the value 0% 0% or left top. For the bottom right corner, you would use 0% 100% or right bottom.

See the Pen Transform Origin Example by Rachel Cope (@rachelcope) on CodePen.27486

View Full Screen

Notes on Transform

Transforming an element will also transform the element’s contents. If you need to maintain the original state of a child element, you can use the opposite value of your transforms on the child elements selector(s) to offset the parent’s styling.

Multiple transforms can be set in one declaration – simply divide each with a space.

transform: rotate(90deg) scale(2) translateY(-50%) translateX(50%);


So, you now know how to set a transition on any element you wish to add an effect to and pair it with a change or transform using :hover, :target or other pseudo-elements for mouse events. If you wanted to effect change on click instead, you can turn to jQuery or use form handlers.


jQuery can be used to detect a click on any CSS selector to add a CSS class containing your transforms or changes to take place on the click. Here is the example from our hamster demo above:

$(document).ready(function() {
  // Add the active class. You can also just use :active
 $(".foo").click(function() {

This adds the active class to the div selected by the existing foo class when it is clicked. Our .foo .ball elements each have a transition like this one:

    transition: all 1.4s ease-in;

When the .foo element is clicked, the active class is added by jQuery, changing the margin and adding a transform that moves the element over and rotates it.

.active {
    margin-left: 495px;
    transform: rotate(720deg);


You can also use form elements such as the checkbox or radio button which have a clicked state you can select through CSS via the :checked pseudo-class. The following example demonstrates how to animate a burger menu icon with a simple transition and transform.

See the Pen Pure CSS Menu Transition by Vail (@vailjoy) on CodePen.27486

View Full Screen

On the main element wrapper we set the transition on all child elements with the wildcard selector:

.spinner-master *{
    transition: all 0.3s;

And on the :checked state declare the changes to take effect with the transition:

.spinner-master input[type=checkbox]:checked ~ .spinner-spin > .horizontal {
    opacity: 0;
.spinner-master input[type=checkbox]:checked ~ .spinner-spin > .diagonal.part-1 {
    transform: rotate(405deg);
.spinner-master input[type=checkbox]:checked ~ .spinner-spin > .diagonal.part-2 {
    transform: rotate(-405deg);
    margin-top: -16px;

Now you’re ready to combine transforms and transitions with animation keyframes to create even more complex interactions, which I’ll touch on in-depth in our next tutorial.



  1. Mark Cameron-Smith
    Jan 20, 2017 @ 4:37 pm

    Thank you. This is hands down the best tutorial I’ve seen on animation. Concise, clear, detailed, and great examples. Bravo.


  2. Yuvraj
    Jan 27, 2017 @ 7:26 am

    This article made my day. A very help knowledge about css has learnt today. Thank you very much.


Leave a Reply