Move Things With CSS Jhey Tompkins 2020
Move Things With CSS Jhey Tompkins 2020
WITH CSS
https://jhey.dev
Sold to 2
hussainhafeez1100@gmail.com
CONTENTS
Howdy! 6
Why Move Things? 8
Motion Design 9
Our First Animation 10
What Can We Animate? 13
Animation Inspector 14
Common values and overlap 16
Comma Separated Values 16
Duration 17
Timing Function 18
CSS Transitions 21
An Example 21
Triggering 22
Our First Transition 22
Structure 24
transition-property 26
transition-duration 28
transition-timing-function 29
Sold to 3
hussainhafeez1100@gmail.com
transition-delay 30
Extra Touches 31
CSS Animations 33
animation-name 33
animation-duration 33
@keyframes 34
animation-iteration-count 37
animation-timing-function 40
animation-play-state 41
animation-delay 42
animation-fill-mode 50
animation-direction 52
animation 54
Other Stuff 57
Curved Animation Paths 58
CSS Variables 61
Composition 65
prefers-reduced-motion 68
JavaScript Hooks 69
JavaScript Solutions 72
Sold to 4
hussainhafeez1100@gmail.com
Conclusion 73
Resources 74
Acknowledgements 76
About the Author 77
Sold to 5
hussainhafeez1100@gmail.com
HOWDY!
You’re interested in making things move on your websites and in
your apps with CSS. I’m glad you’ve chosen me to guide you.
Thank you!
This static format isn't the best for showing animations. Look out
for demo links throughout that will take you to interactive
CodePen demos. The source code for every animation covered in
this book is available to you in a CodePen collection. This means
you can fork them, download them, edit them, etc. The code is
also available from the Zip file or Github repository.
Sold to 6
hussainhafeez1100@gmail.com
Look out for these callouts throughout the book. These
might contain small challenges, questions, etc.
I'd love to know what you think of the content or see what you
make with it. Share things with me and others over on Twitter
using #MoveThingsWithCSS.
Sold to 7
hussainhafeez1100@gmail.com
WHY MOVE THINGS?
The main reason? To enhance the usability and user experience
for users. That doesn't mean we should use animation
everywhere. There's a balance. The animation should enhance
the user experience for a user, not distract or block them. Our aim
is to direct, guide, and inform our users. Not deter them. Good use
cases for animation include things like loading spinners and micro
interactions. Poor examples? Those fancy hero animations that
block users until they've finished spring to mind.
Sold to 8
hussainhafeez1100@gmail.com
MOTION DESIGN
This is by no means a book on designing animation. But, we
should mention it. Implementing animations and transitions is only
one part of the puzzle. Making our animations feel natural and
non-intrusive is very important. Good animation should almost go
unnoticed. It enhances the user experience without becoming a
talking point.
Luckily for us, we have a very good set of principles we can follow
for designing motion. These are Disney's “Twelve basic principles
of animation”, first introduced in 1981. They still hold true now and
following them is a good move. This article does a great job of
showing ways in which to apply them to modern interface design.
Aside from those principles, “The ultimate guide to proper use of
animation in UX” is a must read. It’s full of great animated
examples and golden tips.
It's worth noting that many of the animations we cover will be
basic implementations. The examples could be great candidates
for integrating some of those principles.
Sold to 9
hussainhafeez1100@gmail.com
OUR FIRST ANIMATION
Let's hop right in and create an animation. For this animation, we
will make an element spin 360 degrees.
@keyframes [ NAME ] {
[ KEYFRAME SELECTOR ] { CSS STYLES }
}
Sold to 10
hussainhafeez1100@gmail.com
NAME is the name we give to our animation. You can have one or
many keyframe selectors. We will name our animation “spin”. To
spin our element we can use the transform property and rotate
from 0deg to 360deg. We use two keyframe selectors. One to
define the start of our animation(from) and one for the end of our
animation(to). The from and to keywords are equal to 0% and
100%.
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
We can take this further. The from styles match the initial
transform of our element. Thus, the keyframe selector is
redundant. We can remove it.
@keyframes spin {
to {
transform: rotate(360deg);
}
}
Sold to 11
hussainhafeez1100@gmail.com
Now, we need to apply that animation to our element. We can use
the animation-name and animation-duration properties.
.bear {
animation-duration: 2s;
animation-name: spin;
}
Here we are telling our element to use the animation spin with a
duration of 2 seconds.
We're only a few pages in and from that first animation, we have
enough to go off and start creating cool animations. Check out the
demo. We will dig into animations further later on. Before we do
that, let's take a look at a few other things.
Sold to 12
hussainhafeez1100@gmail.com
WHAT CAN WE ANIMATE?
We've made our first animation. We've got a taste for it. Now we're
thinking "What are the possibilities?". Before we deep dive it's
important to gain an understanding of what things we can
animate. This list from MDN contains all animatable CSS
properties. Lea Verou also put together a great demo page for
checking out animatable properties.
A good rule is to try and stick to what your browser can animate
for little performance cost. That's either transform or opacity.
For example, if we want to move an element, it's more performant
to use transform: translate(x, y). An example of a less
performant animation may be animating the width and height
of an element. This could trigger layout changes for other
elements and becomes costly.
Sold to 13
hussainhafeez1100@gmail.com
ANIMATION INSPECTOR
When creating animations, especially complex animations, we
need a way to debug them. This is where Google Chrome's
Devtools Animation Inspector comes into play.
Open a page with that has CSS animation on it (You could use the
demo for our first animation) in Google Chrome. Open the
Developer Tools. Open up the Animations panel by going into
“More tools”. If the Animations panel says "Listening for
animations...", refresh the page.
Sold to 15
hussainhafeez1100@gmail.com
COMMON VALUES AND OVERLAP
As we're covering both animations and transitions, there's going
to be some overlap. Let’s cover that before we dig in.
.bear {
animation-duration: 2s;
animation-name: spin, vanish;
}
Check the demo. Now two animations run on the element at the
same time with the same duration. If we wanted to run two
animations, one after the other, we'd need to use delays. More on
this later.
Sold to 16
hussainhafeez1100@gmail.com
DURATION
We touched on durations when making our first animation. Much
like we can define animation-duration, we can define
transition-duration too. Durations can be set in either
millisecond(ms) or second(s). We also use these time values for
animation-delay and transition-delay.
Sold to 17
hussainhafeez1100@gmail.com
TIMING FUNCTION
The timing function defines how a value changes. By this, we
mean the speed at which a value changes over the duration of an
animation or transition. The animation-timing-function
and transition-timing-function properties define speed
characteristics. We often refer to these as the “ease" for animation
or transition. Think of the easing values
Sold to 18
hussainhafeez1100@gmail.com
configurations. For example, linear ease would be equal to
cubic-bezier(0, 0, 1, 1).
Sold to 19
hussainhafeez1100@gmail.com
Depending on which browser you are using, your browsers' dev
tools can also help. For example, Google Chrome's Devtools has a
great ease visualizer. You can switch between various pre-
configured eases. Or you can drag the handles around to create
your own custom ease.
Check out this demo that visualises how the different eases
can affect the same animation #MoveThingsWithCSS
Sold to 20
hussainhafeez1100@gmail.com
CSS TRANSITIONS
Often, we can achieve our goals with CSS transitions alone. We
may not need to reach for CSS animations.
AN EXAMPLE
To showcase CSS transitions, let's create a button that has some
micro-interaction. This button will be a "Bookmark" button.
Clicking the button toggles the visual state of it. The little star fills
in when the toggle is active.
Sold to 21
hussainhafeez1100@gmail.com
TRIGGERING
It's worth noting how we can trigger transitions. In our example
currently, we are toggling a class on the button element. That
gives us an opportunity to change a property value for an
element. But, we don't need to rely on class changes only. Many
of the CSS pseudo-classes are great opportunities to trigger a
transition. For our button, :hover and :active our great
options. Applying different transitions during different states can
be very effective. We will look at an example of how to do this.
Let's start with the button element. If we look at the CSS for our
button, it changes background-color on :hover, and box-
shadow on :active.
.bookmark-button:hover {
background-color: hsl(280, 50%, 0%);
}
.bookmark-button:active {
box-shadow: 0 0 0 0 hsl(0, 0%, 0%);
}
Sold to 22
hussainhafeez1100@gmail.com
Let’s transition the box-shadow. To do this we can use the
transition property.
.bookmark-button {
transition: box-shadow 0.2s;
}
That’s it! Check the updated demo. Exaggerate your cursor press
to appreciate the transition. Now the box-shadow transitions
and it makes the button press feel more “real”. Compare the
updated demo to the original. It's a very subtle change.
Sold to 23
hussainhafeez1100@gmail.com
STRUCTURE
What did we do there? It wasn't overly exciting, was it? Don't
worry, we'll spice it up. We told the browser to transition any
change in the box-shadow property over a duration of 0.2
seconds. The transition property is a shorthand for defining
the four transition properties.
๏ transition-property - defines the name or names of
properties to transition. The keyword all will transition all
properties and is the default value.
๏ transition-duration - defines the duration of a transition
in millisecond(ms) or seconds(s).
๏ transition-timing-function - defines the ease of a
transition using the timing functions we looked at earlier.
๏ transition-delay - defines the delay for a transition in
either millisecond(ms) or seconds(s).
Sold to 24
hussainhafeez1100@gmail.com
In our first transition, we used the shorthand notation with the
default transition-timing-function and transition-
delay. That would've been equal to writing.
.bookmark-button {
transition-property: box-shadow;
transition-duration: 0.2s;
transition-timing-function: ease;
transition-delay: 0s;
}
Now we've got that out of the way, let's have a little fun with it!
Sold to 25
hussainhafeez1100@gmail.com
TRANSITION-PROPERTY
The transition-property property allows us to define the
property whose value should transition. We’re transitioning the
box-shadow for our button. Let's also transition the
background-color.
.bookmark-button {
transition-duration: 0.2s;
transition-property: background-color,
box-shadow;
}
.bookmark-button#__star {
transition: fill 0.2s;
}
Sold to 26
hussainhafeez1100@gmail.com
But we want something to pop here. Let's spin the star round
when the button becomes active. That'll give us something we
can actually show off our transition skills with.
.bookmark-button#__star {
transition: fill 0.2s, transform 0.2s;
}
.bookmark-button#--active
.bookmark-button#__star {
transform: rotate(216deg);
}
Now the star spins when the button is pressed and it gives our
button something extra. Check the demo. The button element
transitions are subtle and we can leave them as is. But, there is
room to make the star transition more appealing.
Sold to 27
hussainhafeez1100@gmail.com
TRANSITION-DURATION
The transition-duration property allows us to define the
duration it takes for a property value to change. Remember, we
can define this in millisecond(ms) or seconds(s). We may decide
that the star changes color too slow and spins too fast. We can
adjust the transition-duration for each property. Here we
keep the fill transition and slow down the transform
transition.
.bookmark-button#__star {
transition-property: fill, transform;
transition-duration: 0.2s, 0.4s;
}
Sold to 28
hussainhafeez1100@gmail.com
TRANSITION-TIMING-FUNCTION
The transition-timing-function property allows us to
define the speed characteristics for a transition. Let's add a little
bounce to the spin of our star. For this, we could use a custom
speed via cubic-bezier.
.bookmark-button#__star {
transition-property: fill, transform;
transition-duration: 0.2s, 0.6s;
transition-timing-function: ease,
cubic-bezier(.5,-1.5,.6,2.5);
}
Sold to 29
hussainhafeez1100@gmail.com
TRANSITION-DELAY
The transition-delay property allows us to delay a transition.
What if we delayed the fill of our star until it has almost spun?
.bookmark-button#__star {
transition-property: fill, transform;
transition-duration: 0.2s, 0.6s;
transition-timing-function: ease,
cubic-bezier(.5,-1.5,.6,2.5);
transition-delay: 0.4s, 0s;
}
Delaying the fill of the star gives a nice staged effect as it spins.
Check the demo. We could even chain the transitions and have
the fill happen after the spin. We'd do this with:
.bookmark-button#__star {
transition-delay: 0.6s, 0s;
}
Sold to 30
hussainhafeez1100@gmail.com
EXTRA TOUCHES
Almost there. There's a couple of improvements we could make.
When we hover our button, there's no sign that the star will do
anything. We could rotate it when we hover our button.
.bookmark-button:hover .bookmark-button#__star {
transform: rotate(45deg);
}
.bookmark-button#--active:hover
.bookmark-button#__star,
.bookmark-button#--active
.bookmark-button#__star {
transform: rotate(216deg);
}
Sold to 31
hussainhafeez1100@gmail.com
Oh no. The timing function for the star looks off when we aren't
fully rotating it. This leads us to how we can apply different
transitions for different states of our UI. For our button, we may
decide to only use our custom speed when the button is active.
.bookmark-button#__star {
transform-origin: 50% 50%;
transition-property: fill, transform;
transition-duration: 0.2s;
}
.bookmark-button#--active
.bookmark-button#__star {
transition-duration: 0.2s, 0.6s;
transition-timing-function: ease,
cubic-bezier(.5,-1.5,.6,2.5);
}
Sold to 32
hussainhafeez1100@gmail.com
CSS ANIMATIONS
We made our first animation earlier. Let's dig further into CSS
animations!
ANIMATION-NAME
Covered in the first animation we made. The animation-name
property specifies the name of the @keyframes our element
should use. You can also pass the keyword none so that there is
no animation.
ANIMATION-DURATION
Covered in the first animation we made. The animation-
duration property specifies how long an animation should play
for. We can define durations in either millisecond(ms) or
seconds(s).
Sold to 33
hussainhafeez1100@gmail.com
@KEYFRAMES
We put together our first @keyframes rule in our spin
animation.
@keyframes spin {
to {
transform: rotate(360deg);
}
}
Each selector defines styles that should apply at that point in the
animation. If we have selectors that specify the same CSS styles,
we can group them together.
Sold to 34
hussainhafeez1100@gmail.com
Let’s start with a basic example. Consider the animation of a little
spacecraft moving around the path of a square.
Sold to 35
hussainhafeez1100@gmail.com
Because our start and finish position will be the same, we can
group those keyframe selectors.
@keyframes squarePath {
0%, 100% {
transform: translate(-100%, -100%);
}
25% {
transform: translate(100%, -100%);
}
50% {
transform: translate(100%, 100%);
}
75% {
transform: translate(-100%, 100%);
}
}
.spacecraft {
animation-duration: 2s;
animation-name: squarePath;
}
And that’s it! We have a little spacecraft moving along the path of
a square. Check out the demo.
Sold to 36
hussainhafeez1100@gmail.com
ANIMATION-ITERATION-COUNT
If we want an animation to run more than once, we can use
animation-iteration-count. The property accepts a
number or the keyword infinite.
In our example, the spacecraft travels around the square and then
returns to the center. It's quite sudden and a little jarring. What if
we want the spaceship to keep traveling on that path? If we want
an animation to run an infinite amount of times, we use the
keyword infinite.
.spacecraft {
animation-duration: 2s;
animation-name: squarePath;
animation-iteration-count: infinite;
}
Sold to 37
hussainhafeez1100@gmail.com
Consider another demo where we have a racecar going round a
track. It might be the case that this race has 200 laps.
Sold to 38
hussainhafeez1100@gmail.com
.racecar {
animation-name: lap;
animation-duration: 2s;
animation-iteration-count: 200;
}
@keyframes lap {
to {
transform: rotate(360deg);
}
}
Check out the demo. I wouldn't recommend watching all 200 laps!
Sold to 39
hussainhafeez1100@gmail.com
ANIMATION-TIMING-FUNCTION
The animation-timing-function allows us to define the
speed of an animation. We discussed eases and timing functions
earlier.
.racecar {
animation-name: lap;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
Now checking the updated demo, the car races around the track
at a constant speed with no breaks.
Sold to 40
hussainhafeez1100@gmail.com
ANIMATION-PLAY-STATE
Use the animation-play-state property to change the play
state of our animations. Our animations can either run or we can
pause them. To do this we use the animation-play-state
property which defaults to running.
Check the demo and try out the checkbox. Here's another demo
where we can toggle a cellphone ringing by tapping the page.
Use your browser dev tools to inspect and experiment with the
different animations. The demo uses the pseudo-elements
belonging to the .cellphone element.
Let's start with a basic example. Let me introduce you to the most
boring drag race. Two cars race along the strip at the same speed
and take the same time.
.car {
animation: race 4s;
transform: translate(calc(-40vw + 25px), 0);
}
@keyframes race {
to {
transform: translate(calc(40vw -25px), 0);
}
}
Sold to 42
hussainhafeez1100@gmail.com
Now, it's unlikely the drivers have the exact same reaction time.
Let's make one slower than the other.
.car#--green {
animation-delay: 0.25s;
}
Now if we check the demo, the red car pulls off quicker than the
green one.
Could you make it so that green car finishes before the red
car without changing the delay? #MoveThingsWithCSS
Sold to 43
hussainhafeez1100@gmail.com
Consider this demo where all the hands raise at the same time.
.wave:nth-of-type(1) {
animation-delay: 1s;
}
.wave:nth-of-type(2) {
animation-delay: 1.2s;
}
.wave:nth-of-type(3) {
animation-delay: 1.4s;
}
That looks great. But what if we want the wave to show an infinite
amount of times? Let's make the animation-iteration-
count infinite and check the demo. Hold up. Did we lose the
delay? Correct! The animation-delay is only applied once
Sold to 44
hussainhafeez1100@gmail.com
before the animation starts. It doesn't apply to every iteration of an
animation. We've maintained the stagger, but lost the delay. We
could experiment with different delays or reach for a JavaScript
solution. But one neat trick is to adjust the @keyframes so the
delay is considered.
We can see the initial delay in the Animation Inspector but it doesn’t persist.
Sold to 45
hussainhafeez1100@gmail.com
We update our code and pad the start of the animation with
nothing:
.wave {
animation: wave 2s infinite;
}
.wave:nth-of-type(1) {
animation-delay: 0s;
}
.wave:nth-of-type(2) {
animation-delay: 0.2s;
}
.wave:nth-of-type(3) {
animation-delay: 0.4s;
}
@keyframes wave {
0%, 50%, 100% {
transform: translate(0, 0);
}
75% {
transform: translate(0, -50%);
}
}
Sold to 46
hussainhafeez1100@gmail.com
Now our animation takes into account the integrated delay.
Jumping bunnies!
Sold to 47
hussainhafeez1100@gmail.com
If you watch the demo, there's an awkward section at the start
before they all start jumping. To get rid of this, switch the
animation delays to negative.
.bunny:nth-of-type(1) {
animation-delay: 0s;
}
.bunny:nth-of-type(2) {
animation-delay: -0.2s;
}
.bunny:nth-of-type(3) {
animation-delay: -0.4s;
}
.bunny:nth-of-type(4) {
animation-delay: -0.6s;
}
.bunny:nth-of-type(5) {
animation-delay: -0.8s;
}
Now check the demo. The awkward section is gone and those
jumpers keep on jumping.
Sold to 48
hussainhafeez1100@gmail.com
makes maintaining stagger effects, etc. easier. We could refactor
our bunny code to use CSS variables.
.bunny {
animation-delay: calc(var(—-index) * -0.2s));
}
.bunny:nth-of-type(1) {
#--index: 0;
}
.bunny:nth-of-type(2) {
#--index: 1;
}
.bunny:nth-of-type(3) {
#--index: 2;
}
.bunny:nth-of-type(4) {
#--index: 3;
}
.bunny:nth-of-type(5) {
#--index: 4;
}
Sold to 49
hussainhafeez1100@gmail.com
ANIMATION-FILL-MODE
This one's magic. The animation-fill-mode property defines
how animation affects an element before and after animation. By
default, when we apply an animation to an element, it has no
effect before or after it has run.
Sold to 50
hussainhafeez1100@gmail.com
It doesn't look right at all. By default, each element has an
opacity of 1 so they are visible until the animation starts. We
want every element to be invisible. We can use backwards.
.contact {
animation-fill-mode: backwards;
}
Check the demo. Now the list elements fade in and remain as we
would expect.
Our yoyo.
Sold to 52
hussainhafeez1100@gmail.com
If you check the demo, the yoyo drops in and does nothing after
that. To make it go back up, we could use the alternate
direction value with an infinite iteration count.
.yoyo {
animation-iteration-count: infinite;
animation-direction: alternate;
}
Now check the demo. Our yoyo goes up and down and we only
define a keyframe that takes it in one direction.
Sold to 53
hussainhafeez1100@gmail.com
ANIMATION
We've covered all the specific animation properties. The last one
is the animation property. It's a shorthand property for defining
animations.
.plane {
animation-delay: 1s;
animation-direction: normal;
animation-duration: 1s;
animation-fill-mode: backwards;
animation-iteration-count: 1;
animation-name: fly-in;
animation-play-state: running;
animation-timing-function: ease;
}
.plane {
animation: fly-in 1s 1s ease 1 normal
backwards running;
}
Sold to 54
hussainhafeez1100@gmail.com
Ordering of properties is important. The most important being
durations. The first duration specified will apply to animation-
duration. If there's a second, it will apply to animation-
delay. This MDN documentation explains the syntax in greater
detail.
.plane {
animation: fly-in 1s 1s backwards,
advance 4s 2s infinite;
}
Sold to 55
hussainhafeez1100@gmail.com
The longhand version would be written as:
.plane {
animation-name: fly-in, advance;
animation-duration: 1s, 4s;
animation-delay: 1s 2s;
animation-fill-mode: backwards, none;
animation-iteration-count: 1, infinite;
}
Sold to 56
hussainhafeez1100@gmail.com
OTHER STUFF
We've covered CSS animations and transitions. You should now
know enough to go and make some awesome things with
movement. This section covers some interesting things that don't
quite fit elsewhere.
Sold to 57
hussainhafeez1100@gmail.com
CURVED ANIMATION PATHS
.ball {
animation: throw 2s infinite alternate
ease-in-out;
}
@keyframes throw {
0% {
transform: translate(-25vw, 0);
}
50% {
transform: translate(0, -20vh);
}
100% {
transform: translate(25vw, 0);
}
}
Sold to 58
hussainhafeez1100@gmail.com
That code looks right. But check the demo. It's awkward. How do
we get the desired effect? A wrapper element. If we wrap the ball
with an extra element, we can use that to handle the horizontal
movement. Then the ball only needs to worry about the vertical
movement.
.ball {
animation: vertical 2s infinite ease-in-out
alternate;
}
.ball#__wrapper {
animation: horizontal 2s infinite ease-in-out
alternate;
}
@keyframes horizontal {
0% {
transform: translate(-25vw, 0);
}
100% {
transform: translate(25vw, 0);
}
}
@keyframes vertical {
50% {
transform: translate(0, -20vh);
}
}
Sold to 59
hussainhafeez1100@gmail.com
Now check the demo. The ball travels on a curved path.
Sold to 60
hussainhafeez1100@gmail.com
CSS VARIABLES
CSS variables are awesome. But we can’t animate the values yet.
Check this demo and you'll see how the value changes as if it has
stepped timing. Can we use CSS variables with our animation?
Yes. We can use their values to create dynamic animations.
Sold to 61
hussainhafeez1100@gmail.com
In this demo, each medal has a scoped CSS variable defining the
scale for when it grows.
.medal {
animation: scale 0.5s forwards;
}
@keyframes scale {
to {
transform: scale(var(#--scale));
}
}
.medal#--bronze {
#--scale: 1.25;
}
.medal#--silver {
#--scale: 1.5;
}
.medal#--gold {
#--scale: 1.75;
}
Sold to 62
hussainhafeez1100@gmail.com
Before, you couldn't update an animation at run time by changing
CSS variable values. The trick in this scenario would be to flip the
animation on its head and update the initial state of an element.
.bunny {
transform:
translate(0, calc(var(—height) * -1px));
}
@keyframes jump {
50% {
transform: translate(0, 0);
}
}
Sold to 63
hussainhafeez1100@gmail.com
Animations will respond to changing CSS variables at runtime
now. We could update our bunny demo so that the slider updates
the scale at the same time. We can change the animation code so
that the transform responds to variable change.
@keyframes jump {
50% {
background-image: url(“./bunny-jump.png");
transform:
translate(0, calc(var(#--height) * -1px))
scale(calc(1 + ((var(#--height, 1) / 100) * 2)));
}
}
Now check the demo and move the slider. A greater value gives a
higher jump with a larger scale. This opens up various
opportunities for our animations.
Sold to 64
hussainhafeez1100@gmail.com
COMPOSITION
The composition of animations can become complex. Especially if
we want to create timeline style animations. Imagine an animation
timeline where a car pulls up to a crossing, waits, and then pulls
away.
Sold to 65
hussainhafeez1100@gmail.com
We could create one set of keyframes and calculate a delay that
we embed in the keyframes.
@keyframes drive {
0% {
transform: translate(0, 50vh);
}
50%, 70% {
transform: translate(0, 0);
}
100% {
transform: translate(0, -100vh);
}
}
Check the demo. The car pauses from 50% to 70%. The
animation-duration is set to 2s. The car pauses from 1s to
1.4s. If the requirements change and we want a 1s gap, we can
extend the animation-duration. But It's a change that
requires extra calculation.
Sold to 66
hussainhafeez1100@gmail.com
Or, we could create two animations and use variables to configure
the timeline.
:root {
-—pull-up: 1;
—-wait: 1;
—-pull-off: 0.6;
}
.car {
animation: pull-up calc(var(#--pull-up) * 1s),
pull-off calc(var(#--pull-off) * 1s)
calc((var(#--pull-up) + var(#--wait)) * 1s);
}
@keyframes pull-up {
from {
transform: translate(0, 50vh);
}
}
@keyframes pull-off {
To {
transform: translate(0, -100vh);
}
}
Check out the demo. Now variables dictate the car’s journey.
Sold to 67
hussainhafeez1100@gmail.com
PREFERS-REDUCED-MOTION
What if our users would prefer reduced motion or don't want to
see motion at all? This is very important for accessibility. We
should consider users with vestibular motion disorders.
@media (prefers-reduced-motion) {
.bunny {
animation-name: none;
}
}
Sold to 69
hussainhafeez1100@gmail.com
Those bunnies love jumping!
let span = 0
BUNNY.addEventListener('animationiteration',
UPDATE)
Check out the demo. We now keep track of the number of jumps.
Sold to 70
hussainhafeez1100@gmail.com
The hooks open up a bunch of opportunities. What if our bunny
jumped, but after each jump took a little break? And we wanted to
make that break a random length each time?
BUNNY.addEventListener('animationend', UPDATE)
Check out the demo. Now the bunny jumps at random intervals.
Sold to 71
hussainhafeez1100@gmail.com
JAVASCRIPT SOLUTIONS
If you've gone through this book, you should now know enough to
get things moving with CSS. It might seem like an odd topic to end
on but is CSS the right tool for you to move things? Yes and no.
Hear me out. CSS animations and transitions are great. You can
achieve so many wonderful things. But if your animations start to
become complex, they become harder to maintain. This animation
challenge series from Carl Schoof proved that. I attempted to
complete the challenges with CSS variables.
Sold to 72
hussainhafeez1100@gmail.com
CONCLUSION
We've covered a lot in a short space of time. By reading this book,
you now have the skills to go and start making things move with
CSS. Being able to animate your work is a valuable skill for making
it stand out. We've built up a good foundation for how to get
things moving with CSS animations and transitions. But we've only
scratched the surface for the possibilities. Now it's time to go off
and practice, practice, practice! That's the best way to hone your
animation skills. I hope you've enjoyed reading this book and the
material has inspired you. Inspired you to go and make wonderful
experiences for others on the web! I can't wait to see them.
Sold to 73
hussainhafeez1100@gmail.com
RESOURCES
I've linked out to and mentioned various resources along the way.
Please do check them out, especially the demos. Here's a list of
resources shared:
๏ “Move Things With CSS” Codepen Collection from Jhey
Tompkins: https://codepen.io/collection/
3c9c46ea96d05c765e3133109e8db922?
grid_type=grid&sort_order=asc&sort_by=id
๏ “Twelve basic principles of animation”, Wikipedia: https://
en.wikipedia.org/wiki/Twelve_basic_principles_of_animation
๏ “Disney’s motion principles in designing interface animations”,
Ruthi: https://medium.com/@ruthiran_b/disneys-motion-
principles-in-designing-interface-animations-9ac7707a2b43
๏ “The ultimate guide to proper use of animation in ux”, Taras
Skytskyi: https://uxdesign.cc/the-ultimate-guide-to-proper-use-
of-animation-in-ux-10bd98614fa9
๏ “Animatable CSS properties”, MDN: https://
developer.mozilla.org/en-US/docs/Web/CSS/
CSS_animated_properties
๏ “Animatable" from Lea Verou: http://projects.verou.me/
animatable/
๏ “High performance animations”, Paul Lewis and Paul Irish:
https://www.html5rocks.com/en/tutorials/speed/high-
performance-animations/
Sold to 74
hussainhafeez1100@gmail.com
๏ “Inspect animations”, Kayce Basques: https://
developers.google.com/web/tools/chrome-devtools/inspect-
styles/animations
๏ “CSS Triggers”: https://csstriggers.com/
๏ “Easings.net”: https://easings.net/
๏ “The basics of easing”, Paul Lewis: https://
developers.google.com/web/fundamentals/design-and-ux/
animations/the-basics-of-easing
๏ “Pseudo classes”, MDN: https://developer.mozilla.org/en-US/
docs/Web/CSS/Pseudo-classes
๏ “animation property”, MDN: https://developer.mozilla.org/en-US/
docs/Web/CSS/animation
๏ “Create a responsive CSS motion-path? Sure we can”, Jhey
Tompkins: https://css-tricks.com/create-a-responsive-css-
motion-path-sure-we-can/
๏ “Using the Web Animations API”, MDN: https://
developer.mozilla.org/en-US/docs/Web/API/
Web_Animations_API/Using_the_Web_Animations_API
๏ “No frills web animation sequencing challenge”, Carl Schoof:
https://www.snorkl.tv/challenge/
๏ "Vestibular symptoms”, vestibular.org: https://vestibular.org/
article/what-is-vestibular/symptoms/
๏ “Setting multiple animation property values”, MDN: https://
developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/
Using_CSS_animations#Setting_multiple_animation_property_
values
๏ “Easing function”, MDN: https://developer.mozilla.org/en-US/
docs/Web/CSS/easing-function
Sold to 75
hussainhafeez1100@gmail.com
ACKNOWLEDGEMENTS
I'd like to thank the group of people that joined me on this “Info
Product Challenge”. It’s pushed me to create this content for you.
And thank you! Thank you for picking up a copy of "Move Things
with CSS".
STAY AWESOME!
Sold to 76
hussainhafeez1100@gmail.com
ABOUT THE AUTHOR
Jhey Tompkins makes awesome
things for awesome people! He's a
developer with a wealth of experience
known for sharing his creative and
visual work online. He thrives on
bringing ideas to life!
Sold to 77
hussainhafeez1100@gmail.com
FIN.
Sold to 78
hussainhafeez1100@gmail.com