Using CSS3 keyframe animation to create a swinging image

Created: Jan 4th, 15'

In this short tutorial, we'll see how easy it is to create an
image that swings like a pendulum continuously using CSS3
keyframes animation. Such an effect has become popular with
signage and "discount" images, drawing subtle attention to them.
Here's an example:

A percentage value (0% to 10%) donating the point in the
animation the enclosed styles should be applied at.

You can also use
the two keywords "to" and "from" to designate
0% and 100% respectively, for example:

from {background: white;}
to {background: black;}

css styles

One or more CSS styles (each separated by a semi colon)
specifying the style at this point in the animation.

Keyframes animations are supported in IE10+, FF5+, Chrome, Opera
12+, and Safari 4+. Within this list, the older versions of
Chrome, and Safari require a vendor prefix in front of
@keyframes in order to work properly, hence the two versions
of the same
@keyframes
animation definition in our example above (@-webkit-keyframes
swinging{} and @keyframes swinging{}).

Note on prefixes: There are other vendor specific prefixes
you may need to add in front of your CSS3 rule or property such as
keyframes or transition to cover all your
bases. The major vendor prefixes are -webkit-, -moz-,
-ms-, and -o-.
In general however only -webkit- is needed these days to cover
Safari browsers still stubbornly hanging on to prefixed versions of
CSS3 properties. The important thing is to test your CSS against
your target browsers to see if adding a prefix makes a difference.
You can use a tool such as
autoprefixer to intelligently add vendor prefixes to default
CSS3 rules and properties in your CSS.

Once the
@keyframes animation has been defined, we use CSS's
animation property to reference that animation inside a CSS
element or class selector, such as:

The delay (integer) before the animation started,
suffixed with either "s" or "ms" for seconds or milliseconds. Defaults
to 0s.

animation-iteration-count

Sets the number of times the animation should run before
stopping. A value of "infinite" means forever. Defaults
to 1.

animation-direction

Defines whether the animation should play as normal, in
reverse, or alternate between the two. Possible values are:

normal: The animation plays forward as normal. After each
animation cycle, the animation resets to the beginning state and
starts over again. Default value.

reverse: Plays the animation in reverse, starting from
the end state. After each animation cycle, the animation
resets to the end state and starts over again.

alternate: The animation alternates between normal and
reverse directions. In reverse, the animation starts at the end
state and plays backwards. The animation timing function is also
reversed.

alternate-reverse: The animation alternates between
reverse and normal directions, starting in reverse for the first
iteration.

animation-fill-mode

Defines how the animation should apply styles to its
target when the animation isn't playing anymore. Possible values are:

none: The animation should not apply any styles to the
target when it is not playing. Default value.

forwards: The target element will retain the computed
styles defined in the last keyframe (ie: when keyframe is at 100%)
when the animation isn't playing.

backwards: The target element will retain the computed
styles defined in the first keyframe (ie: when keyframe is at 0%)
when the animation isn't playing.

both: The target element will retain the computed styles
defined in both the first and last keyframes when the animation
isn't playing.

animation-play-state

Defines whether the animation is initially playing or
not. Possible values are "running" or "paused". Defaults to "running".

Inside the animation shorthand property, if a particular
animation property value is omitted, the default value for that
property will be used. Furthermore, the order of each property value
inside animation in general isn't important, with the exception of
the two time related properties (animation-duration and
animation-delay)- if both are defined, animation-duration should
always proceed animation-delay.

Revisiting the CSS for our swinging image

In our CSS for creating a swinging image, we have the following
defined for our "swingimage" class:

That is to say, we want the swinging keyframes animation to run
for 3.5 seconds for each cycle, using the "ease-in-out" timing
function, and for the target element to retain the last keyframe
styles afterwards. With the target element keeping the last
keyframe's styles at the end of the cycle, we create a seamless
transition between the last and first keyframe styles when the next
cycle begins. And last by not least, we want this animation to run
for an infinite number of cycles.

Now lets turn our attention to the transform-origin property
inside the CSS class. It dictates the x-offset and y-offset origin where any CSS
related transformation will take place, which in our swinging image
will be the rotation of the image. In the demo image above, the
"hinge" where the rotation should originate from is exactly midpoint
horizontally inside the image, and at the top vertically:

This is why for our transform-origin property value, we have the
following:

transform-origin: 50% 0;

Lets consider a different image now with a hinge that's not dead
center horizontally:

In this case, we'll want to adjust the transform-origin value to
35% horizontally:

The transform-origin property supports either an
explicit length value (ie: px) or percentage as its unit, so to be
even more precise, you could specify say 77px for the x-offset value
instead of 35% here.

The best way to get a handle on keyframe animation and the
animation property is to try out different values and see the
changes. You can play around with the code for the two swinging
images below: