Welcome! This is a demo for using embedded Ruby(erb) and CSS for
animation. It assumes you have some knowledge of
css @keyframes
and
Ruby/Rails.
The area above between the buttons displays the animation, and the
panel to the left shows the associated code (add in your own
browser specific prefixes). This panel provides commentary
about each step in the technique. Both panels are independently
scrollable. Use the ‘back’ and ‘forward’
buttons bracketing the animation pane to cycle through this demo.
The current animation is about as basic
as @keyframes
get. One thing to make sure of is declaring an ‘s’
for seconds in the animation
property, even if the value
is 0
. Firefox
doesn't like it if you don't.
The html
will be the
same for the next couple of panels, so I'll leave it out until it becomes relevent
again.
Not much has changed here. Perhaps the only thing worth noting is
the interaction of the top
property between the selector and
@keyframes
. We could have
left it out of the selector, and just further declared it
in @keyframes
at 0%
and 100%
.
And here's a 360° cycle. Pretty straight forward. What
about two animated elements at the same time? How about
three, four, or ten?
Here's where an erb
block
comes in handy. The css
here is the same as the previous panel, except the selector is now a
class
instead of an id
.
Right now the animation is pretty boring though, so let's amp
it up a bit. Within the block, I'd like to give each animated element it's own
'behavior' so that I don't have to hand code each one. To do so I am going to use style tags with
embedded Ruby.
So, a few significant steps have been taken here in order for the
animation to render. First, with the logic in the controller,
each animated element in the view is given a unique id
, which can be
targeted for differentiated behavior.
For the properties that are shared by the animated elements
(such as background
), we've changed the css selector
to [id*=ball]
, which
targets any element's id
that contains the sub-string
"ball" (NOTE: Be mindful of how you declare other id
's
if you use this selector).
We've moved the animation
property to the view, and animation-duration
and top
have been randomized with
Ruby's rand()
method. Since
the methods are called each iteration through the block, the targeted
elements will be assigned different animation property values, depending on
which properties we decide to randomize values for.
animation-name
has
been given a randomized suffix as well. Even though the animated
elements have unique id
's, if they all have the
same animation-name
,
only one of the 10 generated @keyframes
would apply to all of
them. The animation-duration
might be different for
each, but not the path each animated element
traverses.
Furthermore, in this context where position
has been set to absolute
, elements that end up with the same
randomly generated value for animation-duration
would stack one on top of the
other and appear as only one element to the
user.
Setting position
to absolute
or relative
is an
interesting thing to experiment with. If you find yourself needing to use position:relative
on animated elements, but want to set up identical
positions for some of the @keyframes
, a margin
can be
used that is equal to the negative value of height
, or width
, or both, depending on what you want to
accomplish (exp: .animated-div {position:relative; height: 20px; width:20px; margin:-20px;}
).
That last statement will make a lot more sense when you
start playing around with this. Inspect the
animated elements with you browser's developer tools, and change the position
to relative
. In the next section, try inspecting animated elements and not defining position
at all. Quite a bit
of behavioral variety can be accomplished just through
the position
property.
You might be wondering why all the
@keyframes
have been
declared in the view since only 25%
is variable. As it turns
out, @keyframes
don't cascade…declaring part of it in one code-space and the rest
in another doesn't work (more
here). When using cross-browser support
prefixes, this can get pretty bulky. So if for no other
reason than readability, it may be best to put the block in
a partial.
As you can
see with transform
and box-shadow
, @keyframes
can handle a wide variety of
properties. The transform
property itself can handle several animatable characteristics, such
as scale
, rotate
, and skew
. These can be nested within @keyframes
, and further extend the variety of erb
influenced animation.
Instead of 10.times do
, we could be coupling our
animation behavior to real data, thereby relating the state of data
to the user with an animated UI/UX (Check out an app here http://www.beecando.com that takes a step
in that direction). This can also include binding animation-duration
to activity over time, etc.