Skip to main content

Create cool UI animations with CSS

In this final tutorial we'll look at how we can combine all of the elements we've covered in the article into one single animation. 

We'll be creating a record player animation where the arm of the record player moves into position over the record, as well as rotating the record itself at two different speeds. We'll create the animation using SVG transitions and keyframes, and we'll be using custom properties in order to make our animation configurable.

01. Create and export our SVG

The first step is to create and export our SVG code. You can do this using many different graphics editors (the example is Sketch for Mac). The shapes being used are simple – mostly straight and poly lines combined with circles. We want to create the SVG in the initial state of our animation.

02. Optimise our SVG

When we have the exported code from our editor we need to optimise that code to make it easier for us when creating our animation. Firstly we'll run it through SVGOMG making sure to only optimise the parts we need. Once we've done this, we'll paste our code into CodePen and create some basic page styles. We'll be using Sass to take advantage of the nesting capability.

03. Edit by hand

Next we will need to edit our SVG by hand. We are going to need to remove any inline transforms on elements that we are going  to animate into our CSS. Doing this will make it easier to animate, because we'll be able to see all of our transform properties in one place.

#arm-top {
  transform: translate(9.5px, 3px)
rotate(-90deg);
  transform-origin: -1px 11px;
}
#record-container {
  transform: translate(7px, 0)
rotate(0deg);
  transform-origin: 24px 24px;
}
#record {
  transform: rotate(0deg);
  transform-origin: 24px 24px;
}

04. Animate the arm

We can achieve most of what we are trying to do using transitions. We will start with the record arm and animating the arm into position over the record. To do this we will need to rotate the arm of the record from -90deg to 0deg. In order to transition rotation we need to use the transform property. This means we also need to keep any other transform properties the same when changing the rotation.

#record-svg:hover, #record-svg:active,
  #record-svg:focus {
    #arm-top {
      transform: translate(9.5px,3px) rotate(0deg); 
      transition: transform 1s;
    }
}

05. Slowly rotate the record

Next we can use another transition to complete the first, slower rotation of our record. To do this we will need to target the container and apply our transition code, much like we did in the previous step, except this time we will be adding a delay of a quarter of the time it takes for the arm to move into position.

#record-svg:hover, #record-svg:active,
  #record-svg:focus {
    #record-container {
      transform: translate(7px, 0)
rotate(360deg);
      transition: transform
1s 500ms linear;
    }
}

06. Speed up the rotation

In order to speed up the rotation, and for it to repeat infinitely, we'll need to use a keyframe animation. The animation we need to create is simple, we just need to rotate the record 360 degrees.

@keyframes rotate-record {
to 
{
transform: rotate(360deg);
    }
}

Then when we're applying our animation, we need to make sure to set the delay correctly so our animation starts at the end of the container stopping.

#record-svg:hover, #record-svg:active,
  #record-svg:focus 
{
#record {
    animation: 400ms linear
  1250ms infinite rotate-record;
    }
}

07. Reverse the movement

Everything is working now and our animation is complete – until the interaction stops. At that point, both the arm and record stop animating and jump back to their original positions. This is where the setup of our SVG is important. The record element itself sits inside of a container. By animating the container using a transition we can also perform another transition in reverse with just a couple of lines of code.

#arm-top {
    ...
    transition: transform 500ms;
}
#record-container {
    ...
    transition: transform 500ms linear;
}

08. Introduce custom properties

Now we've got our complete animation, we'll make it configurable with custom properties. We can do this by setting our custom properties on the root element in our CSS.

:root {
    --background-color: #2A2A2A;
    --record-colour: white;
    --record-size: 12rem;
}

We can then apply them to the property values where needed, making sure to provide a fallback for each one.

.container {
    max-width: var(--record-size, 15rem);
    max-height: calc(var(--record-size,
15rem) * 1.166);
    ...
}

We can also use custom properties as part of calc() functions, which is particularly useful for sizing and for creating durations and delays.

09. Make the duration configurable

We can utilise the calc() function in order to make the animation duration configurable. Firstly we need to set a new custom property for our duration with a value, in seconds. We can then use this value in order to set all of the other animation time values.

transition: transform 500ms;

Given the custom property --animation-duration being two seconds becomes:

transition: transform calc(var(--animation-
duration, 2s) / 4);

By doing this for every time value in our animation, we can control the speed of the entire animation by simply changing the custom property at the top of our CSS.

10. Optimise the animation

Now we can add our accessibility options for prefers-reduced-motion and add the will-change property to all of the elements.

This article was originally published in creative web design magazine Web Designer. Buy issue 282 or subscribe.

Read more: