tag up by a factor of two, not only would that div be twice as wide and
tall, but also the text inside would be twice as big, as would any images inside it.
Of course, you may be wondering why you’d ever use this. After all, you could just
as easily increase or decrease the width and height of the element using the CSS
width and height properties, and you can scale text size up or down using the fontsize property. The most common use for scale is to make a visual change to an
element dynamically on the page. For example, mousing over a button may make
that button momentarily bigger. You could achieve this effect with the :hover state.
For example, say you have a link on a page with the .button class applied. You can
create a simple style like this to format that button:
.button {
font: .9em Arial, Helvetica, sans-serif;
border-radius: .5em;
background-color: rgb(34,255,23);
border: 1px solid rgba(0,0,0,.5);
padding: .5em;
}
Chapter 10: CSS Transforms, Transitions, and Animations
323
TRANSFORMS
To really emphasize that button, you can make it get slightly bigger when a visitor
mouses over it, like this:
.button:hover {
-webkit-transform: scale(1.2);
-ms-transform: scale(1.2);
transform: scale(1.2);
}
When the visitor mouses off the button, the transform is removed and the button
returns to its regular size. On page 330, you’ll even learn how you can animate this
change in size by using CSS transitions.
TIP You can use a similar idea for images. Display a gallery of small images, and then add a :hover style
to them so that when a visitor mouses over the image, it grows larger. To make this look good, you should insert
the final, enlarged version of the image inside the HTML, but set its size smaller by using either CSS or the
tag’s width and height properties.
You can even scale the horizontal and vertical dimensions separately. To do this,
supply two values separated by a comma inside the parentheses; the first number
is the horizontal scale, and the second is the vertical scale. For example, to make
an element half as wide but twice as tall, use this declaration:
transform: scale(.5,2);
You can see the effect at bottom left in Figure 10-3.
CSS also provides separate functions for horizontal and vertical scaling: scaleX scales
along the horizontal axis, while scaleY scales vertically. For example, to make an
element twice as tall without changing its width, you’d write this:
transform: scaleY(2);
NOTE
Again, to save space, this example shows only the un-prefixed version of the transform property. For
this to work in Safari and Internet Explorer 9, you’ll need to add the proper prefixes -webkit- and -ms-.
But to make an element three and a half times as wide, but not taller or shorter,
you’d use:
transform: scaleX(3.5);
There’s another visual trick that scaling offers: the ability to flip an element upside
down and backwards. No one’s quite sure what branch of mathematics the W3C
used to come up with this system, but if you use a negative number with scale, you
actually flip an element around. For example, here’s how to flip an element upside
down and left to right:
transform: scale(-1);
324
CSS: THE MISSING MANUAL
This produces the image pictured in Figure 10-4, left. You can also flip the element
on only one axis. In the middle image in Figure 10-4, the image is flipped only on its
horizontal axis. Flipping the element along its vertical axis produces the middle image:
TRANSFORMS
transform: scale(-1,1);
It produces the effect of a mirror held to the side of the element, or like you’ve flipped
the element over and are looking through its back. What fun!
FIGURE 10-4
There’s no end to the ways
you can use CSS to confuse
and enrage your website’s
visitors. The box at left is
flipped on the horizontal
axis, the box in the
middle is flipped on the
vertical axis, and at right
it’s flipped both ways.
Of course, if you want to
create a tribute site to
Leonardo DaVinci (www.
mos.org/sln/Leonardo/
LeonardoRighttoLeft.html),
creating a mirror image of
all the text on a page may
be just the thing!
Translate
The transform property’s translate function simply moves an element from its
current position a set amount left or right and up or down. By itself, it’s really not
that useful. As you read on page 320, when a web browser transforms an element,
it doesn’t rearrange the page; it lays the page out as if the element had no transformation. Accordingly, when you move a div or other tag using the translate
function, the browser leaves an empty space where the tag would normally appear,
and then draws the element in its new position (see Figure 10-5). If you simply want
to position an element on the page, you can use absolute or relative positioning, as
described in Chapter 14.
Chapter 10: CSS Transforms, Transitions, and Animations
325
TRANSFORMS
FIGURE 10-5
The translate function
moves an element a set
number of pixels, ems,
or a percentage from its
normal spot on a page.
This often leaves an
empty space: The blank
area between the two
headlines is where the
outlined
tag would
normally appear.
However, translate does come in handy when you want to make subtle movements
in response to a hover or click. For example, in many user interface designs, when
you click a button, it moves slightly down and to the left, simulating the look of a
real 3D button being pressed into a keypad. You can simulate this effect using the
translate function and the :active state of a link:
.button:active {
-webkit-translate(1px,2px);
-ms-translate(1px,2px);
translate(1px,2px);
}
The translate function takes two values: The first specifies the horizontal movement,
and the second the vertical movement. In this example, clicking an element with the
.button class moves that element one pixel to the right and two pixels down. Use a
negative number for the first value to move the element to the left; use a negative
number for the second value to move the element up.
You’re not limited to pixel values, either. Any valid CSS length value—px, em, %, and
so on will work.
CSS also provides two additional functions for moving an element just to the left or
right—translateX—and up or down—translateY. For example, to move an element
up .5 ems, use the translateY function like this:
transform: translateY(-.5em);
326
CSS: THE MISSING MANUAL
The real fun with the translate function is when used with CSS transitions. With
the CSS transition, you can then animate the movement of the element, so that it
travels across the screen. You’ll learn how to do that on page 330.
TRANSFORMS
Skew
Skewing an element lets you slant it on its horizontal and vertical axes; this can give
an element a three-dimensional feel (see Figure 10-6). For example, to slant all the
vertical lines so that they lean to the left 45 degrees (as in the first image in Figure
10-6), you’d write this code:
transform: skew(45deg, 0);
To do the same along the y-axis (middle image in Figure 10-6), you’d write this:
transform: skew(0,45deg);
You can skew an element on both axes at once. For example, here is the code used
to produce the third image in Figure 10-6:
transform: skew(25deg,10deg);
The first value is a degree value from 0deg to 360deg, proceeding in a counterclockwise direction from the top of the element. For example, in the first image in
Figure 10-6, the 45 degrees are represented by a line drawn from the center of the
element and rotated 45 degrees counter-clockwise (bottom-left).
FIGURE 10-6
The skew function is one
way to simulate a 3D
look. However, as you’ll
see in the box on page
330, CSS actually offers
another way to simulate
three dimensions: with 3D
transforms.
NOTE Remember to add browser-prefixed versions of the transform property to your finished CSS:
-webkit-transform, -ms-transform.
Chapter 10: CSS Transforms, Transitions, and Animations
327
TRANSFORMS
The second value is also a degree value from 0deg to 360deg. But this one proceeds
in a clockwise position from the right of the element. So the middle image in Figure
10-6 shows a 45-degree slant of all of the horizontal lines.
TIP Visit http://westciv.com/tools/transforms/index.html to play with an online tool for visualizing CSS
transforms.
As with translate and scale, CSS offers separate functions for the x- and y-axes:
skewX and skewY.
NOTE
CSS provides yet another transformation method called a matrix. A matrix is an array of numbers, as
used in advanced algebra. They’re pretty mind-bending and not at all intuitive unless you’re Stephen Hawking.
But if you want to learn how they work, visit https://dev.opera.com/articles/understanding-the-css-transformsmatrix/ for as lucid an explanation as possible.
Multiple Transformations
You’re not limited to just a single transformation. You can both scale an image and
skew it; rotate it and translate it; or use any of the four different transform functions simultaneously. Simply add additional functions to the transform property,
each separated by a space. For example, here’s how you can rotate an element 45
degrees and enlarge it to twice its normal size:
transform: rotate(45deg) scale(2);
Here’s an example with all four transformations applied at the same time:
transform: skew(45deg,0deg) scale(.5) translate(400px,500px) rotate(90deg);
The order in which you place the transform functions is the order in which the
browser applies these effects. For example, in the second example, the element
is first skewed, then scaled, then translated, and finally rotated. The order doesn’t
really matter unless you’re using translate. Since translate actually moves the
element, if you place it before a rotate, for example, the browser first moves the
element and then rotates it. Since the element moved first, the point around which it
rotates has changed. On the other hand, if you rotate it first, you’re then moving the
rotated element a certain amount from its center (which is now in a new location).
Origin
Normally, when you apply a transformation to an element, the web browser uses the
center of the element as the transformation point. For example, when you rotate an
element, the browser rotates it around its center point (Figure 10-7, left). However,
CSS lets you change that transformation point, using the transform-origin property.
It works just like the background-position property (page 236); you can supply
keyword values, absolute values in pixels, and relative values in ems and percentages.
328
CSS: THE MISSING MANUAL
For example, to rotate a div around its top-left point (Figure 10-7, middle), you can
use the left and top keywords, like this:
TRANSFORMS
transform-origin: left top;
You can also use pixel values:
transform-origin: 0 0;
Or percentages:
transform-origin: 0% 0%;
Likewise, to rotate an element around its bottom-right corner (Figure 10-7, right),
use the right and bottom keywords:
transform-origin: right bottom;
Which is also equivalent to:
transform-origin: 100% 100%;
When using pixel, em, or percentage values, the first number is the horizontal position, and the second is the vertical position.
NOTE The transform-origin property has no effect on elements that are only moved using the
translate function.
FIGURE 10-7
Setting the transformorigin property changes
the point on the element
where the transformation
is applied. The default
origin is the middle of the
element (left), but you can
change it to the top left
(middle) or bottom right
(right). The dotted squares
represent the element if
it hadn’t been rotated (its
regular position on the
page).
Chapter 10: CSS Transforms, Transitions, and Animations
329
TRANSITIONS
POWER USERS’ CLINIC
3D Transforms
CSS also offers a much more complex type of transformation.
3D transforms let you simulate a three-dimensional space on
the flat screen of a monitor, tablet, or phone.
For a short introduction to 3D transforms, visit http://coding.
smashingmagazine.com/2012/01/06/adventures-in-thethird-dimension-css-3-d-transforms/ and for a more detailed
explanation with lots of examples, check out http://desandro.
github.io/3dtransforms/. To see some great examples of 3D
transforms in action, visit these sites:
• Apple’s Morphing Power Cubes page (www.webkit.org/
blog-files/3d-transforms/morphing-cubes.html ), one of
the first examples of the power of 3D transformations,
demonstrates a rotating cube, which you can change into
a rotating set of tiles.
• Here’s an example of a 3D “flip” effect: http://davidwalsh.
name/css-flip —an animated effect that looks like you’re
turning over a card to show its back.
Transitions
While transforms can be fun (especially the rotate function), they really bring your
page to life when coupled with a CSS transition. A transition is simply an animation
from one set of CSS properties to another set over a specific amount of time. For
example, you can make a banner rotate 360 degrees over the course of two seconds.
To make a transition work, you need a few things in place:
• Two styles. One style represents the beginning look of the element—a red
nav button, for example—while the second style is the ending look—a blue nav
button. The web browser will take care of the process of animating the change
between the two styles (changing the button from red to blue, for example).
• The transition property. CSS adds the transition property—the secret sauce
that makes the animation possible. In general, you apply the transition property to the original style, the style that defines the look of an element before
the animation begins.
• A trigger. The trigger is the action that causes the change between the two
styles. With CSS, you can use several pseudo-classes to trigger an animation.
The most common is the :hover pseudo-class. With it, you can animate the
change between an element’s normal appearance and how it looks when a
visitor mouses over it. You’ll see an example of that in just a minute. In addition,
you have :active (when the mouse is clicked on an element), :target (when
an element is the target of link), and :focus (when a link is tabbed to, or a
form field is clicked into or tabbed to). Beyond that, you can use JavaScript to
dynamically change the style of any tag (see the box on page 335).
330
CSS: THE MISSING MANUAL
When the trigger no longer applies—when the visitor mouses off a navigation
button, for example—then the browser returns the tag to its previous style and
animates the entire process. In other words, you only need to set a transition
to an element once, and the browser takes care of animating from one style to
another and back to the original style.
TRANSITIONS
A web browser can’t animate every single CSS property, but you still have a long
list of properties to choose from. In addition to the rotate, scale, translate, and
skew transformations you just read about, you can also animate color, backgroundcolor, border-color, border-width, font-size, height, width, letter-spacing,
line-height, margin, opacity, padding, and word-spacing; the positioning properties—top, left, right, and bottom—which you’ll learn about in Chapter 15; and
many other properties. You can find a complete list at www.w3.org/TR/css3transitions/#animatable-properties.
NOTE
CSS transitions work in most browsers. Unfortunately, when it comes to Internet Explorer, only version 10 and later understand CSS transitions. If you’re still concerned about IE and earlier, use transitions simply
as a way to add visual excitement. Mostly, this is just fine: IE9 and earlier will, in most cases, be able to switch
between two styles (for example, show a :hover style) without animating that change.
Adding a Transition
At the heart of CSS transitions are four properties that control which properties
to animate, how long the animation takes, the type of animation used, and an optional delay before the animation begins. Here’s a simple example. Say you want a
navigation button’s background color to change from orange to blue when a visitor
mouses over it. First, you start with the two styles needed to switch between these
two colors. For example, you can apply a class of .navButton to the link and then
create two styles, like this:
.navButton {
background-color: orange;
}
.navButton:hover {
background-color: blue;
}
These styles will work in any browser; hovering over the nav button will change its
background from orange to blue. However, the change is instantaneous. To make
the color animate over one second, add two new properties to the .navButton
style, like this:
.navButton {
background-color: orange;
transition-property: background-color;
transition-duration: 1s;
}
Chapter 10: CSS Transforms, Transitions, and Animations
331
TRANSITIONS
.navButton:hover {
background-color: blue;
}
The transition-property specifies which properties to animate. You can specify
a single property (as in the above example), use the keyword all to animate all
CSS properties that change, or use a comma-separated list to specify more than
one (but not all) properties. For example, say you create a :hover style so the text
color, background color, and border color all change. You list out all three of those
properties like this:
transition-property: color, background-color, border-color;
Or, to make it simple, use the all keyword, like this:
transition-property: all;
In most cases, using all works well, since every CSS change is animated, which
creates a pleasing visual effect.
To specify how long the animation takes to complete, use the transition-duration
property. This property takes a value in either seconds or milliseconds (thousandths
of a second). For example, to make a transition take half a second to complete, you
can use either:
transition-duration: .5s;
Or:
transition-duration: 500ms;
It’s even possible to set separate timings for each animated property. For example,
when a visitor mouses over a button, you may want the text color to change rapidly,
the background color to change a little more slowly, and the border color to change
really slowly. To do so, you need to list the animated properties, using transitionproperty and then list the times, using transition-duration, like this:
transition-property: color, background-color, border-color;
transition-duration: .25s, .75s, 2s;
The order in which you list the times must match the order in which you list the
properties. So, in the above example, .25s goes with the color property, .75s with
the background-color property, and 2s with the border-color property. If you move
the properties around, then their timing changes.
Transition Timing
To have a working, animated transition, you only need to set transition-property
and transition-duration. However, you can control the rate of the animation by
using the transition-timing-function property. This property can be a little confusing: It doesn’t control how long the animation takes (that’s what the transitionduration property is for). Instead it controls the speed during the animation. For
332
CSS: THE MISSING MANUAL
example, you can begin the animation slowly and then quickly complete it, creating
an effect where the background color changes almost imperceptibly at first, and
then quickly completes its color change.
TRANSITIONS
The transition-timing-function property can take one of five keywords: linear,
ease, ease-in, ease-out, and ease-in-out. If you don’t specify a timing function,
the browser uses the ease method, which begins the animation slowly, speeds up
in the middle, and slows down at the end, providing a more organic change. The
linear option provides a steady change along the entire length of the animation.
No option is really any better than the other: they just provide different looks, so
try them out to see which one you like best.
To use it, simply add the transition-timing-function property and the method
you’d like to use:
transition-timing-function: ease-in-out;
NOTE
It’s a lot easier to see the different timing functions than to describe them. Visit www.the-art-of-web.
com/css/timing-function/ to see an excellent side-by-side comparison of the five timing methods.
You can also use what’s called a cubic-bezier value for the transition-timingfunction property. The Bezier curve plots the progress of the animation over time
(see Figure 10-8). If you’ve used a drawing program like Adobe Illustrator, you’re
probably familiar with Bezier curves. By adjusting two control points you can control
how the line curves: the steeper the line, the faster the animation; the flatter the line,
the slower. For example, the Bezier curve pictured in Figure 10-8 starts off steep (the
animation begins quickly), then flattens in the middle (the animation slows down),
and then grows steep again (the animation rapidly progresses to its final state). To
create this kind of animation, add this line of code:
transition-timing-function: cubic-bezier(.20, .96, .74, .07);
Cubic Bezier curves aren’t something you can come up with off the top of your head.
You’re better off using one of the many online tools for creating and testing different
timing functions. Mathew Lein’s Ceaser tool is one of the best: http://matthewlein.
com/ceaser/.
As with the transition-duration property, you can apply different timings to different properties.
Chapter 10: CSS Transforms, Transitions, and Animations
333
TRANSITIONS
FIGURE 10-8
Creating a cubic Bezier
curve lets you create a
wide range of interesting
timing functions for your
animations. You can make
them start really slowly
and end quickly, or vice
versa. The online Ceaser
tool makes creating cubic
Bezier curves a breeze:
Just grab the control
handle on the bottom-left
point and drag to change
the slope of the line, and
then drag the control point
on the top-right point. The
steeper the line, the faster
the progress of the animation at that stage. In this
example, the line starts
off relatively flat, meaning
the animation will move
slowly at first, then ramps
up steeply at the end,
meaning the animation
will quickly progress to
the finish at the end of the
transition’s duration.
Delaying a Transition’s Start
Finally, you can prevent a transition from animating right away with the transitiondelay property. For example, if you want to wait a half second before the animation
begins, you can add this code:
transition-delay: .5s;
334
CSS: THE MISSING MANUAL
TRANSITIONS
POWER USERS’ CLINIC
Using JavaScript to Trigger Transitions
CSS transitions are easy-to-use animations built right into
web browsers (at least, most web browsers). You can create
complex effects simply by defining a set of CSS properties to
begin with, and a set of CSS properties to end with, and then
step out of the way and let the web browser handle the rest.
Unfortunately, you’re limited to just a handful of CSS selectors
for triggering those transitions. Most commonly, you’ll use
the :hover pseudo-class to make an element change when
moused over. You can also use the :focus pseudo-class on
a form element to make it animate when a user clicks inside
it (for example, you can make a multiline text area grow in
height when focused, then shrink to just a few lines when a
visitor clicks out of it).
For example, CSS doesn’t have a :click pseudo-class, so
if you want to trigger a transition when someone clicks on
an element, you can’t do it with CSS. Likewise, if you want to
hover over one element but trigger an animation on another
element, you’re out of luck…if you’re only using CSS. But CSS
transitions work anytime a CSS property changes, even if you
change the CSS property using JavaScript.
JavaScript is a programming language that lets you add
interactivity to web pages, build dynamic user interfaces,
and loads of other things. But you can also use JavaScript to
simply add or remove a class from an element, or change any
CSS property you’d like. Using JavaScript, you can add a class
to an image when a visitor clicks a “Show bigger image” link.
That new class simply scales up the image (using the scale
transform discussed on page 322). By adding a transition to
the image, you’ll have an instant animation.
JavaScript is a big topic worthy of its own book… there just so
happens to be JavaScript & jQuery: The Missing Manual by this
author that’s worth a read. But if you want to get started with
the simplest way to use CSS transitions triggered by JavaScript,
read this short tutorial: https://css-tricks.com/controlling-cssanimations-transitions-javascript/.
Most of the time, you won’t want to use a delay for all properties, since it kind of
undermines the transition’s potential for interactivity. After all, it’s more like a cruel
trick to make your visitors wait a second before they see any visual changes when
they mouse over your button. However, if you’re animating several properties, you
may want to make one property wait until the others finish before its animation
starts. For example, say you have a button whose background color and text color
you want to change, and then have its border color change suddenly after the other
two properties have finished. Here’s how you might do that:
.navButton {
color: black;
background-color: #FF6603;
border: 5px solid #660034;
transition-property: color, background-color, border-color;
transition-duration: 1s, 1s, .5s;
transition-delay: 0, 0, 1s;
}
.navButton:hover {
color: white;
background-color: #660034;
Chapter 10: CSS Transforms, Transitions, and Animations
335
border-color: #FF6603;
TRANSITIONS
}
As with the transition-duration property, you can specify different delay values for
each property. The order in which you list the times must match the order of the
properties listed for transition-property. For instance, in the preceding code,
there’s no delay for the transition between the color and background color, but
there’s a one-second delay before the border color changes.
TIP
Usually you put the transition properties into the starting style (for example, .navButton on page
331), not the final style (.navButton:hover). However, here’s a trick for use with CSS drop-down menus (see
the box on page 296). One problem with drop-down menus in CSS is that they usually disappear very quickly
if you accidentally mouse off the menu. However, you can make the menu appear quickly but disappear slowly
using the transition-delay property. To do so, you add the following code to the original style:
transition-delay: 1s;
Then add no delay to the :hover style:
transition-delay: 0;
It’s somewhat counterintuitive, but this code basically makes the :hover transition happen immediately, with
no delay. But to return to the regular style (where the menu disappears) takes 1 second. During that time, a visitor
has enough time to move his errant mouse back over the menu before it disappears.
Transition Shorthand
Writing out all the different properties—transition-property, transition-duration, transition-timing-function, and transition-delay—can get pretty tiring.
Especially when you consider you need to also create vendor-prefixed versions of
each of those as well. Fortunately, there’s a faster way to create transitions—the
transition property.
This property bundles all of the other properties into one. To use it, simply list the
property, duration, timing function, and delay in a space-separated list. For example,
to animate all CSS properties for one second using the ease-in timing function, with
a half-second delay, write the following:
transition: all 1s ease-in .5s;
You need to list either all or a single CSS property and a duration, but the timing
function and delay are optional. By default, the timing function is ease, and there’s
no delay. So if you simply want to animate the transition of all CSS properties for
one second, then write this:
transition: all 1s;
If you only want to animate the change in the background color, then list that
property:
transition: background-color 1s;
336
CSS: THE MISSING MANUAL
You can only list a single CSS property here, so if you wish to animate multiple
CSS properties (but not all), then you can write a comma-separated list of spaceseparated transition properties. Take the example from page 335, where the bordercolor property is animated separately from the color and background color. You
can rewrite that code like this:
TRANSITIONS
transition: color 1s, background-color 1s, border-color .5s 1s;
To make the code easier to read, many web designers put each transition on a
separate line, like this:
transition: color 1s,
background-color 1s,
border-color .5s 1s;
This is perfectly legal as long as you remember to separate them with a comma and
end the whole shebang with a semicolon.
POWER USERS’ CLINIC
Getting Smoother Animations
Animating many different properties can take a toll on a web
browser. Whether you’re using CSS transitions or CSS animations, browsers need to do a lot of work to animate changes in
CSS properties. Too many animations and transitions going on
at once can bring a browser to a crawl and even crash it. This is
particularly true with mobile devices and tablets, which have
significantly slower CPUs than desktop and laptop computers.
However, there are four things that browsers can animate
without a lot of CPU power: opacity (page 671), and the
translate, scale, and rotate options of the transform property (page 319). These four properties are treated
more efficiently than other CSS properties, so any transitions
or animations you create with them will be smoother. (To find
out the technical details, check out: http://www.html5rocks.
com/en/tutorials/speed/high-performance-animations/ ).
In addition, you can also force animations to be moved to
a computer’s GPU, or graphic processing unit. GPUs are really super-fast computers, and they can do specific types of
calculations much more quickly than the computer’s CPU. You
can trick the browser into handing a style to the GPU by adding
a 3D transform property to the style. For example, if you plan
to animate the background color of an element when a visitor
mouses over it, you could create the style with the original
background color, like this:
. highlight {
background-color: rgb(231,0,23);
transition: background-color 1s;
transform: translateZ(0);
}
.highlight:hover {
background-color: rgb(0,0,255);
}
The transform: translateZ(0) line doesn’t do
anything visually. It tells the browser to move the element 0
pixels along a three dimensional z-axis; in other words, move
it not at all. However, because it uses a 3D transformation,
browsers give this style to the GPU to process. The upshot is
that the animation might appear to play back more smoothly
because of the GPU’s greater horsepower.
But before you start slapping transform: translateZ(0) on every style, be aware that the GPU can only
handle so much, and piling too many visual effects for it to
handle can slow the browser to a crawl.
In addition, too many animations and transitions can have a
very negative effect on a page’s performance, especially on
mobile devices. Make sure you test all of your transition and
animation effects in multiple browsers and on a mobile phone
to make sure your page works well.
Chapter 10: CSS Transforms, Transitions, and Animations
337
ANIMATIONS
Animations
CSS provides another, more feature-rich mechanism for creating animations. With
CSS transitions, you can only animate from one set of CSS properties to another.
CSS animations let you animate from one set of properties to another set to another
set, and so on. In addition, you can have an animation repeat, pause when a visitor
mouses over it, and even reverse itself once the animation reaches its end.
CSS animations are a bit more complicated than transitions, but they have the added
benefit of not necessarily needing a trigger to begin the animation. While you can
add an animation to a :hover state so the animation plays when the mouse hovers
over an element, you can also have an animation start when the page loads. This
effect lets you draw attention to a banner or logo by animating it across the page
when a visitor first enters your site.
NOTE
CSS animations, like transitions, don’t work in Internet Explorer 9 or earlier. They’re well supported
in all current browsers, however.
The first step in creating an animation is creating a set of keyframes. In animation,
a keyframe is a single frame of an animation that dictates how the scene looks.
Suppose the first keyframe shows a ball on one side of a soccer field. By adding a
second keyframe, you can define an ending point for the animation—like the ball
inside the goal on the other side of the soccer field. A web browser then provides the
animation between the two keyframes by drawing all of the intermediate steps—the
ball traveling across the field on its way to the goal.
If you’re thinking transitions use a similar idea, you’re right. In a transition, you define
two styles and let the browser animate the change from one style to another. In this
way, you could think of each of those styles as a keyframe. However, CSS animations
let you define multiple keyframes, so you can create much more complex animated
effects: a soccer ball traveling from one side of the field, to a player, to another
player, and then into the goal, for example.
There are two steps in creating an animation:
1. Define the animation.
This involves setting up keyframes that list the CSS properties to animate.
2. Apply the animation to an element.
Once defined, you can apply the animation to any number of elements on a page.
You can even set up separate timings, delays, and other animation properties
for each element. So you can use the same animation with slightly different
settings multiple times on a page.
Defining Keyframes
The first step is to set up your keyframes. The syntax involved may look kind of
strange, but here’s the basic structure:
338
CSS: THE MISSING MANUAL
@keyframes animationName {
from {
/* list CSS properties here */
}
ANIMATIONS
to {
/* list CSS properties here */
}
}
You start with @keyframes, followed by a name. The name is what you call the animation. You’ll end up using that name later when you apply the animation to an element
on the page, so make it descriptive, like “fadeOut” or “fadeIn.”
NOTE
The term @keyframes isn’t a CSS property, it’s called an at rule. Other at rules in CSS include the
@import statement for loading an external style sheet from another style sheet, and @media to define styles
for different types of media such as a printer or different screen sizes and resolutions (page 465).
You then add at least two keyframes. In the current example, the keywords from
and to are used to create the beginning keyframe (from) and the final keyframe
(to). Inside each keyframe you add one or more CSS properties—just as if you were
creating a style. In fact, you can think of each keyframe as just a CSS style filled with
one or more CSS properties. For example, say you want to create an animation that
fades an element into view. You could start with an opacity value of 0 (invisible),
and end with a value of 1 (fully visible):
@keyframes fadeIn{
from {
opacity: 0;
}
to {
opacity: 1;
}
}
You’re not limited to just two keyframes, either. You can use percentage values to
define multiple keyframes. The percentage represents where in the overall length
of the animation the change should occur. For example, say you want to create an
effect where the background of an element changes from yellow to blue to red.
You can write this:
@keyframes backgroundGlow {
from {
background-color: yellow;
}
50% {
background-color: blue;
Chapter 10: CSS Transforms, Transitions, and Animations
339
}
to {
background-color: red;
}
ANIMATIONS
}
In this case, the blue background will appear halfway through the animation. If you
want the yellow to last longer and the blue to appear after three-quarters of the
animation is complete, use 75% instead of 50%. You can continue to add additional
keyframes this way (for example, at 25%, 66%, and so on).
NOTE
You can replace the from keyword with 0% and the to keyword with 100%.
Nor are you limited to a single CSS property. You can place any number of animatable properties (page 331) inside each keyframe—background-color, opacity, width,
height, and so on:
@keyframes growAndGlow {
from {
background-color: yellow;
}
50% {
transform: scale(1.5);
background-color: blue;
}
to {
transform: scale(3);
background-color: red;
}
}
In the above example, not only does the background color cycle through three colors,
it also scales up in size until it’s three times its original size.
You can also get pretty tricky with the percentage values by adding multiple percentage values for one set of CSS properties. This is useful in a couple of cases: First, it’s
good if you want to animate to a certain point, pause, and then continue. For example,
say you’d like to begin with a yellow background color for a
tag. Then you’d
like to change that color to blue, stay at blue for a while, and then finish with a red
color. In other words, you want a sort of pause in the middle while the background
color stays constant before changing again. You can do that with this code:
@keyframes glow {
from {
background-color: yellow;
340
CSS: THE MISSING MANUAL
}
25%, 75% {
background-color: blue;
}
to {
background-color: red;
}
ANIMATIONS
}
Notice the 25%, 75% in line 5. That means 25% of the way through the animation,
the background color of the element should be blue. However, it should be blue
75% of the way through as well. In other words, from the 25% mark to the 75% mark,
the background will remain solid blue, before finally turning red. If this animation
ran for 4 seconds, then for the middle 2 seconds of the animation, the element’s
background would remain solid blue.
You can also use percentages when you want to use the same set of CSS properties for different parts of the animation. For example, say you want to animate the
background color again, but this time go from yellow to blue to orange to blue to
orange to red. Blue and orange appear twice, so instead of writing their backgroundcolor properties multiple times, you can instead do this:
@keyframes glow {
from {
background-color:
}
20%, 60% {
background-color:
}
40%, 80% {
background-color:
}
to {
background-color:
}
}
yellow;
blue;
orange;
red;
In this case, the background color will turn blue at the 20% mark, orange at the 40%
mark, then blue again at the 60% mark, and orange one last time at the 80% mark
before finally turning red.
Unfortunately, as of this writing, to use CSS animations in Chrome, Safari, and Opera,
you must also use the -webkit- vendor prefix (see the box on page 321). In other
words, you need to create one animation for those browsers, and another animation
(without any vendor prefix) for Firefox and Internet Explorer 10 and above:
@-webkit-keyframes fadeIn {
from {
opacity: 0;
Chapter 10: CSS Transforms, Transitions, and Animations
341
}
to {
opacity: 1;
}
ANIMATIONS
}
@keyframes fadeIn{
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Notice the two hyphens—one between the @ and the vendor prefix and one between
the vendor prefix and the word keyframes.
Applying an Animation
Once you’ve completed a set of keyframes, the animation is ready. However, to make
it work, you need to apply it to an element on your page. You can add an animation
to any style for any element on a page. If you simply add the animation to a style
that applies immediately to an element—for example, an h1 tag style—the animation
will apply when the page loads. You can use this technique to add an introductory
animation to a page that makes a logo zoom into place in the page’s upper-left, or
make a particular box of content glow to draw attention to it.
In addition, you can apply an animation to one of the pseudo-classes, including
:hover, :active, :target, or :focus to make an animation run when a visitor mouses
over a link, for example, or clicks into a form field. Finally, you can apply the animation to a class style and use JavaScript to dynamically apply that class in response
to a visitor clicking a button or some other page element (see the box on page 335).
CSS provides a handful of animation-related properties to control how and when
an animation plays back (as well as a shorthand version that encompasses all the
individual properties). At a minimum, to get an animation running, you need to supply the name you gave the original animation (in the @keyframes rule as discussed
on page 338), and a duration for the animation.
Here’s a simple example. Say you want a div with an important announcement to fade
into view when the page loads. You’ve given that div a class name of announcement:
.
1. Create the fade-in animation with the @keyframes rule:
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
342
CSS: THE MISSING MANUAL
TIP
If you’re only animating a single property, it can be easier to read to if you put the keyframes on a single
line:
from
ANIMATIONS
{ opacity: 0; }
However, if you’re animating many properties, it’s easier to read (and type) if you spread that code over several
lines:
from {
opacity: 0;
color: red;
width: 50%;
}
2. Apply that animation to the style for the
tag:
.announcement {
animation-name: fadeIn;
animation-duration: 1s;
}
The animation-name property simply tells the browser which animation to use.
It’s the same name you provided when you created the animation in step 1. The
animation-duration property sets the time the animation takes from start to
finish. In this example, these are the only two animation properties listed, but
you can (and probably will) put other non-animation properties in the style as
well. For example, in the real world, you’d probably add properties such as width,
background-color, border, and so on to this .announcement style.
NOTE
Putting the animation’s name inside quotes—'fadeIn'—isn’t technically required, and it’s not
done in this example, but doing so can prevent any conflicts that might arise if you use a CSS keyword for an
animation name.
As with the @keyframes rule, each of the animation properties require the -webkitvendor prefix to work in Chrome, Safari, and Opera, so the above .announcement style
would need to be written like the following to work in as many browsers as possible:
.announcement {
-webkit-animation-name: fadeIn;
-webkit-animation-duration: 1s;
animation-name: fadeIn;
animation-duration: 1s;
}
It may seem a bit of a pain to define the animation in one place with the @keyframes
rule and then apply it in another (the style); however, once you’ve defined the
animation, you’re free to use it any number of times in any number of styles. For
example, you can create a generic fade-in type of animation and apply it to different elements. What’s more, you can control the animation independently for each
Chapter 10: CSS Transforms, Transitions, and Animations
343
ANIMATIONS
style—for example, make the header fade in over the course of half a second, but
make another page element fade in for five seconds.
In addition, you can apply more than one animation to an element. Say you create
one animation named fadeIn to make an element fade in and another animation
named blink to make the background color blink wildly. To apply both animations
to the element, you provide a comma-separated list of names like this:
animation-name: fadeIn, blink;
To give the animations separate timings, provide a list of comma-separated times:
animation-name: fadeIn, blink;
animation-duration: 1s, 3s;
The order in which you place the times applies to the animation name in the same
order. For example, the first animation gets the first time listed. In the above example,
fadeIn takes one second to complete, while blink takes three seconds.
You can apply several other useful animation properties as well. Read on.
Timing the Animation
You’ve already seen that the animation-duration property lets you control an animation’s length. As with transitions, you can use milliseconds (750ms, for example)
or seconds (.75s, for example) to specify the duration.
As with transitions, you can also set a specific type of timing function to control
the rate of the animation throughout that duration. For example, you can start the
animation slowly and end it quickly, using a cubic-Bezier curve (page 333) or using
one of the built-in keyword methods: linear, ease, ease-in, ease-out, or ease-inout. These work the same as the transition-timing-function property discussed
on page 332.
You can use the animation-timing-function to control the entire animation or
just specific keyframes. For example, to apply the ease-out timing function for the
fadeIn animation presented earlier (step 1 on page 342), add the timing function to
the .announcement style (step 2 on page 345):
.announcement {
animation-name: fadeIn;
animation-duration: 1s;
animation-timing-function: ease-out;
}
However, you can also control the timing function for the animation between keyframes. For example, say you create an animation that has three keyframes with
three different background colors. The web browser will animate from one color
to another and then to a third. Perhaps you want it to slowly move from the first to
the second color using a cubic Bezier curve, and then move in a uniform time from
the middle to the end. You can do that by adding two timing functions, one to the
344
CSS: THE MISSING MANUAL
first keyframe (which controls the animation from keyframe 1 to 2), and one at the
second keyframe to control the animation from keyframe 2 to 3:
ANIMATIONS
@keyframes growAndGlow {
from {
background-color: yellow;
animation-timing-function: cubic-bezier(1, .03, 1, .115);
}
50% {
transform: scale(1.5);
background-color: blue;
animation-timing-function: linear;
}
to {
transform: scale(3);
background-color: red;
}
}
You can also delay the beginning of the animation using the animation-delay property. It works the same as the transition-delay property for transitions (page 334),
and simply waits a specific number of milliseconds or seconds before the animation
begins. For example, if you want to wait one second before the “announcement” div
fades into view, you can rewrite that .announcement class like this:
.announcement {
animation-name: fadeIn;
animation-duration: 1s;
animation-delay: 1s;
}
Adding a delay to an animation is a great way to catch people’s attention and add
surprise to a page.
NOTE The animation-timing-function and animation-delay properties require the
-webkit- vendor prefix for Chrome, Safari, and Opera, so make sure you add the appropriate -webkitanimation-timing-function, and so on to your animated styles.
Finishing the Animation
With CSS, you can control a few additional aspects of an animation, including
whether to repeat an animation, which direction the animation runs if it’s animated
more than once, and how the browser should format the element when the animation is complete.
Transitions are animations that only run once—mouse over a button and the button
grows, for example. Animations, however, can run once, twice, or continuously, thanks
Chapter 10: CSS Transforms, Transitions, and Animations
345
ANIMATIONS
to the animation-iteration-count property. If you want an animation to run 10
times (fade in and out 10 times, perhaps), add this code to the style you’re animating:
animation-iteration-count: 10;
Normally a browser only plays the animation once, and if that’s all you’re after, then
leave off this iteration count property. If you want the animation to play continuously, the animation-iteration-count property accepts one keyword: infinite.
So to run the fadeIn animation an infinite number of times on the announcement
div, you can create this style:
.announcement {
animation-name: fadeIn;
animation-duration: .25s;
animation-iteration-count: infinite;
}
That, however, would annoy your visitors to no end, so please don’t do it. However,
you could use a style like this for a simple “pulsing” effect where a “sign up today”
button gently glows (by animating the box-shadow property discussed on page 201).
Normally, when an animation runs more than once, a web browser literally starts
the animation over from the beginning. So if you animated a background color from
yellow to blue and repeated it twice, the browser would show a yellow box turning
blue, and then suddenly the yellow box would return and then animate to blue once
again. This effect can be pretty jarring. In this case, it would look better if, for the
second time through the animation, the browser simply reversed the effect. That’s
how transitions work. For example, when you mouse over an element, the browser
animates the transition from the regular state to the rollover state. When you move
the mouse off the element, the browser simply reverses the animation to return to
the regular state. To make an animation move forward on odd runs and backward
on even runs, use the animation-direction property and the alternate keyword.
For example, to make an element fade out and then back in again, you can create
an animation called fadeOut, like this:
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
Then, play that animation twice, reversing its direction on the second time:
.fade {
animation-name: fadeOut;
animation-duration: 2s;
animation-iteration-count: 2;
animation-direction: alternate;
}
346
CSS: THE MISSING MANUAL
This code tells the web browser to run the fadeOut animation on any element with
the class of fade. The animation should run for two seconds and then repeat. Because of the alternate value for animation-direction, the animation will fade out
the first time (go from totally opaque—an opacity of 1—to invisible—an opacity of
0), but will run backwards the second time (from 0 to 1 opacity), which makes it
fade back into view.
ANIMATIONS
TIP To have an animation run a number of times but end up back at the beginning state, use an even number
of iterations and set the animation-direction property to alternate.
No matter how many times you have a web browser run an animation, once the
animation is completed, the browser displays the animated element in its original,
pre-animation state. For example, say you animate an image so it slowly grows to
twice its size. Once the animation is completed, the web browser snaps the image
back down to its original size, creating a jarring visual effect. Fortunately, you can
tell the browser to keep the animated element formatted the same as when the
animation ended by setting the animation-fill-mode property to forwards.
animation-fill-mode: forwards;
Apply this property to the element you’re animating, along with the animation-name,
animation-duration, and other animation properties.
Animation Shorthand
As you can see, there are a lot of animation properties, and writing all of them out in
addition to all of the vendor-prefixed versions is a recipe for carpal tunnel syndrome.
While you still need vendor-prefixed versions, you can simplify things by using the
animation shorthand property. This single property combines animation-name,
animation-duration, animation-timing-function, animation-iteration-count,
animation-direction, animation-delay, and animation-fill-mode into a single
property. For example, you can take this code:
.fade {
animation-name: fadeOut;
animation-duration: 2s;
animation-timing-function: ease-in-out;
animation-delay: 5s;
animation-iteration-count: 2;
animation-direction: alternate;
animation-fill-mode: forwards;
}
And rewrite it like this:
.fade {
animation: fadeOut 2s ease-in-out 5s 2 alternate forwards;
}
Chapter 10: CSS Transforms, Transitions, and Animations
347
ANIMATIONS
That’s one line of code instead of seven! You should list the property values in the
order used above: name, duration, timing function, count, direction, delay, and fillmode. In addition, make sure each value is separated by a space. Only the name
and duration are actually required. The other values are optional.
If you want to apply more than one animation to an element, simply use commaseparated lists of animation properties. For example, to apply two animations (say
fadeOut and glow) to the .fade style, write this:
.fade {
animation: fadeOut 2s ease-in-out 5s 2 alternate forwards,
glow 5s;
}
Of course, in real usage you’d need to use the -webkit- vendor prefix as well:
.fade {
-webkit-animation: fadeOut 2s ease-in-out 5s 2 alternate forwards,
glow 5s;
animation: fadeOut 2s ease-in-out 5s 2 alternate forwards,
glow 5s;
}
In general, you should opt to use the animation shorthand—it’s much more concise
and gentler on your fingers and the keyboard.
Pausing an Animation
CSS includes another animation property—animation-play-state—to control an
animation’s playback. It accepts only one of two keywords: running or paused. To
pause an animation, simply apply this declaration to a style:
animation-play-state: paused;
There’s only one way to really apply that using CSS, however—a pseudo-class. As
with transitions, you need some kind of trigger to pause an animation. One way to
do this is to pause any animation when a visitor mouses over the animation. Here’s
an example using the .fade class style:
.fade {
animation: fadeOut 2s ease-in-out 2 alternate 5s forwards,
glow 5s;
}
This code runs two animations—fadeOut and glow—on any element with the fade
class applied to it. Say you want to let visitors pause this animation simply by mousing over it. You’d only need to add one more style:
.fade:hover {
animation-play-state: paused;
}
348
CSS: THE MISSING MANUAL
Of course, you’ll need all the -webkit- vendor prefixed version as well: -webkitanimation-play-state.
TUTORIAL
A more powerful way to pause an animation would be to dynamically apply the
animation-play-state property to the element using JavaScript. In this way, you
can create a complex animation and add a Pause button that pauses the animation
when clicked. See the box on page 335 for more on JavaScript and CSS animations.
Animating on Hover
So far, the animations you’ve seen here would all run when the page loads. You have
a few other options, including several pseudo-classes and using JavaScript, to trigger
a CSS animation. The most common pseudo-class for animation is :hover. With it,
you can run an animation when a visitor mouses over any element; for example, you
can make a logo do fancy gymnastics, move off the page, and then move back again.
To animate an element when a visitor’s mouse hovers over it, start by creating an
animation with the @keyframes rule (step 1 on page 342). Then, create a :hover
pseudo-class for whatever element you wish to animate. In that style, you simply
add the animation properties (step 2 on page 343). Now the animation runs only
when the visitor hovers over the element.
Tutorial
In this exercise, you’ll add transformations, animation, and transitions to a banner.
To get started, download the tutorial files from this book’s companion website at
https://github.com/sawmac/css_mm_4e. Click the tutorial link and download the
files. All the files are enclosed in a zip archive, so you need to unzip them first. (You’ll
find detailed instructions on the website.) The files for this tutorial are contained
inside the 10 folder.
1. In a text editor, open 10→styles.css .
The banner.html file includes a banner with a logo graphic, headline, and set
of navigation buttons (see Figure 10-9). The styles.css file is the style sheet attached to the banner.html page. First, you’ll add a transformation so that when
a visitor mouses over a button it scales up in size.
FIGURE 10-9
A normal, static banner
just waiting to come to life
with animation, transformations, and transitions.
Chapter 10: CSS Transforms, Transitions, and Animations
349
TUTORIAL
2. At the bottom of the styles.css file add the following rule:
nav a:hover {
-webkit-transfrom: scale(1.5);
-ms-transform: scale(1.5);
transform: scale(1.5);
}
The buttons on the page are contained inside an HTML nav element. This descendant selector targets links inside the
tag in their hover state (that is,
when a visitor mouses over the link). The style applies the scale function (page
322) to make the button slightly larger. Unfortunately, you need to add the
-webkit- and -ms- vendor-prefixed versions for Safari and Internet Explorer 9.
3. Save styles.css and preview the banner.html file in a web browser. Mouse
over the links below the headline.
When you mouse over a button, it grows larger, almost popping off the page
(Figure 10-10). Very cool, but it would look even better if you added an animation to the effect.
FIGURE 10-10
Pop goes the button. By adding a scale transformation to a button’s hover state, you can make it almost
pop off the page. The enlarged button doesn’t affect
any of the content around it (for example, it doesn’t
push the other buttons out of the way). This is a unique
aspect of all CSS transformations.
4. Add another style before the nav a:hover style you just created:
nav a {
transition: all .5s;
}
Here, you’re instructing the web browser to animate all changes to the CSS
properties of the tags inside the element, and to make the animation
last half a second. To make things more interesting, you’ll add a background
color to the hover state.
5. Locate the nav a:hover style and add background-color: red;, so the finished style looks like this:
nav a:hover {
background-color: red;
-webkit-transform:scale(1.5);
-ms-transform: scale(1.5);
transform: scale(1.5);
}
350
CSS: THE MISSING MANUAL
If you save the page and preview it now, you’ll see that not only do the buttons
grow larger when hovered over, they also fade to red. But now you’ll add separate
timings to these transitions, so the button first grows larger and then turns red.
TUTORIAL
6. Delete the code inside the nav a style and add two new properties:
nav a {
-webkit-transition: -webkit-transform .5s,
background-color 1s ease-in .5s;
transition: transform .5s,
background-color 1s ease-in .5s;
}
You need to add two properties: one for Safari and one for all other browsers. Even
though Safari understands the transition property (without a vendor prefix),
you have to use the -webkit- vendor prefix because you’re using the –webkittransform property, and that wouldn’t make sense to any other browser.
The second property—the plain transition property—is for all other browsers.
The first part—transform .5s—informs the browser that you want to animate
any changes in the transform property over the course of half a second. The
second part—background-color 1s ease-in .5s—indicates that you wish to
animate the background color change over the course of one second, using the
ease-in timing method (page 332), but wait half a second before starting. That
.5s at the end is important, since it matches the .5s of the transform animation.
In other words, the browser will wait until the transform transition is complete
before changing the background color.
7. Save styles.css and preview the banner.html file in a web browser.
Mouse over a button. First, the button gets larger. Keep the mouse over the
button, and it then turns red. You can of course, tweak the timing—for example,
remove the delay for the background-color transition, and the color change
will begin at the same time as the size change. However, since the color change
lasts for one second, it will continue after the button has reached its final size.
Adding an Animation
Now it’s time to try out CSS animations. You’ll begin by simply spinning and scaling
the logo image. The first step in creating a CSS animation is to use the @keyframes
rule to set up the keyframes of the animation. This example starts you off with a
simple animation and just two keyframes.
TIP
Because CSS animations require a fair amount of code, it’s a good idea to start by using only the vendorprefix for the browser you most often use. Test the page in that browser, and once you’ve perfected the animation,
then add the code for the other browsers. This example uses code that will work in Chrome, Safari, and Opera. If
you prefer Firefox or Internet Explorer 10 or later, then leave off the -webkit- part for now.
Chapter 10: CSS Transforms, Transitions, and Animations
351
TUTORIAL
1. Open the styles.css file and add the following style to the bottom of that
file, after the nav a:hover style:
@-webkit-keyframes logo {
from {
-webkit-transform: rotate(0) scale(.5);
}
to {
-webkit-transform: rotate(-720deg) scale(1);
}
}
This example uses the WebKit syntax, which means it’ll work in Chrome, Safari
and Opera. If you’re using Firefox or Internet Explorer (10 or later) as your main
browser, replace @-webkit-keyframes with @keyframes.
This code is telling the browser that it should start the element with no rotation—
rotate(0)—and at half its size—scale(.5). It should then animate the change
from that to the animation’s “to” state—in this case rotating it –720 degrees,
which is three counter-clockwise rotations—and scaling it back up to its normal
size. In other words, this animation will spin an element and make it grow.
Now, you need to apply it to any element on the page.
2. Create a new style after the one you just added:
.logo {
-webkit-animation: logo 1s;
}
The logo in the banner has a class of logo applied to it, so this class selector
adds an animation to it. The animation property can take many values, but you
only need the name and duration. Here, you’re specifying the animation you
created in the last step—logo—and telling a web browser to make the animation last one second.
3. Save the styles.css file and preview banner.html in your browser.
The logo should spin, grow in size, and then stop. If it doesn’t, double-check
your code and make sure you’re previewing the page in the proper browser. If
all goes according to plan, this animation should look great, but it would be even
better if it moved in from off the page and then stopped in its proper spot in
the banner. To do that, you’ll simply animate the element’s position on the page.
4. Edit the @keyframes rule so it looks like this (addition in bold):
@-webkit-keyframes logo {
from {
-webkit-transform: rotate(0) scale(.5);
left: 120%;
}
352
CSS: THE MISSING MANUAL
to {
-webkit-transform: rotate(-720deg) scale(1);
left: 0;
}
TUTORIAL
}
Here you begin the logo’s position to the right of the banner and navigation
buttons at the edge of the screen (basically, you’re placing the logo’s left edge
1.2x the width of the banner). To get this to work, you need to take advantage
of the CSS position property. You’ll learn about it in-depth in Chapter 15, but
for now you just need to know that CSS gives you the power to position any
element anywhere in the browser window—even outside the browser window.
The final keyframe places the logo at the 0 position, where it normally would
appear on the page at the left side of the banner.
5. Save the styles.css file and preview the banner.html file in Chrome or Safari.
Looking good. But you can still do better. Add another keyframe so the logo
rolls into place and then rotates in the opposite direction as it gets bigger.
6. Change the code you added in step 4 to look like this:
@-webkit-keyframes logo {
from {
-webkit-transform: rotate(0) scale(.5);
left: 120%
}
50% {
-webkit-transform: rotate(-720deg) scale(.5);
left: 0;
}
to {
-webkit-transform: rotate(0) scale(1);
}
}
Now you have three keyframes: one at the beginning, another right in the middle,
and a third at the end. The browser will animate the properties as they change
from frame 1 to frame 2 to frame 3.
The first keyframe is the same as in step 4: The logo is unrotated, half its size,
and placed off to the right side. The second keyframe keeps the logo at the
same size, rotates it three times, and moves it to the left side of the banner.
Finally, once the logo is in the place, the browser scales it up while rotating it
back from the –720 degree position to the 0 degree position; in other words,
the logo now spins three times clockwise.
Chapter 10: CSS Transforms, Transitions, and Animations
353
TUTORIAL
7. Save the style sheet and preview the web page in Chrome or Safari.
The logo should roll in from the right side of the banner to the left, stop, grow,
and spin clockwise. If it’s not working, double-check your code against the code
in step 6. At this point, though, the animation is a bit too fast. That’s an easy fix.
8. Edit the .logo style so the animation lasts for three seconds instead of one:
.logo {
-webkit-animation: logo 3s;
}
Now you just need to duplicate this code and remove the -webkit- vendor
prefix to have it work in Firefox and Internet Explorer 10 and later. You’ll tackle
the @keyframes rule first.
9. Copy the vendor-prefixed @keyframes rule and paste a duplicate just below
it. Remove the -webkit- prefix, so your code looks like this:
@-webkit-keyframes logo {
from {
-webkit-transform: rotate(0) scale(.5);
left: 120%
}
50% {
-webkit-transform: rotate(-720deg) scale(.5);
left: 0;
}
to {
-webkit-transform: rotate(0) scale(1);
}
}
@keyframes logo {
from {
transform: rotate(0) scale(.5);
left: 120%
}
50% {
transform: rotate(-720deg) scale(.5);
left: 0;
}
to {
transform: rotate(0) scale(1);
}
}
354
CSS: THE MISSING MANUAL
At some point, in a beautiful future, all the browsers will use the single nonprefixed @keyframes rule and a non-prefixed transform property. But at this
point, you’re stuck duplicating a lot of code.
TUTORIAL
Fortunately, adding the @keyframes rule is the hardest part. Adding the animation to the .logo style isn’t nearly as much work.
10. Edit the .logo style by adding one new line:
.logo {
-webkit-animation: logo 3s;
animation: logo 3s;
}
11. Save styles.css and check it out in Firefox or Internet Explorer.
The logo should roll along the page and enlarge on all of those browsers. Of
course, in Internet Explorer 9 and earlier, you won’t see any animation. However,
the logo will still be correctly placed and the page will look just fine. You’ll find
a finished version of this tutorial in the 10_finished folder.
To take this further, add an animation that makes one of the navigation buttons
glow when the mouse is positioned over it. (Hint: create an animation that cycles
through different box shadow values. Use the inset value to add the shadow
inside the box as described on page 201. Then add that animation to the nav
a:hover style so it only plays when the mouse hovers over a button.)
FIGURE 10-11
Books can do a lot, but
they can’t, unfortunately,
show you the amazing
animation that you just
created. Here’s what the
page should look like
when the animation has
run its course and you
mouse over the Home
button.
Chapter 10: CSS Transforms, Transitions, and Animations
355
CHAPTER
Formatting Tables
and Forms
11
T
he formatting powers of CSS go way beyond text, images, and links. You can
make tables of information like schedules, sports scores, and music playlists
easier to read by adding borders, backgrounds, and other visual enhancements.
Similarly, you can use CSS to organize the elements of a form to help your visitors
through the process of ordering items, signing up for your newsletter, or using your
latest web application.
This chapter shows you how to display tables and forms with HTML and how to lay
out and style them using CSS. In two tutorials at the end of the chapter, you’ll create
a table and a form, using the tricks you’ve learned along the way.
Using Tables the Right Way
HTML tables have seen a lot of use in the short history of the Web. Originally created to display data in a spreadsheet-like format, tables became a popular layout
tool. Faced with HTML’s limitations, designers got creative and used table rows and
columns to position page elements like banner headlines and sidebars. As you’ll see
in Part Three of this book, CSS does a much better job of laying out web pages. You
can concentrate on using (and formatting) tables for their original purpose—displaying data (Figure 11-1).
357
USING TABLES
THE RIGHT WAY
FIGURE 11-1
You can do all of your page
layout and design with CSS
and use tables for what
they were intended—displaying rows and columns
of information. CSS created the attractive fonts,
borders, and background
colors in this table about
indoor lawn mowers, but
the underlying structure is
all thanks to HTML.
HTML (and XHTML) has a surprising number of tags dedicated to table building. This
chunk of HTML creates the very simple table pictured in Figure 11-2.
Table 1: CosmoFarmer.com's Indoor Mower Roundup
Brand
Price
Power Source
358
CSS: THE MISSING MANUAL
STYLING
TABLES
Chinook Push-o-matic Indoor Mower
$247.00
Mechanical
Sampson Deluxe Apartment Mower
$370.00
Mechanical
Even with only three rows and three columns, the table uses nine unique HTML tags:
, , , , , , , , and . In
general, more HTML isn’t a good thing, and you don’t need all of these tags: You
can get away with just the , , and tags (and usually as well).
However, a table’s various tags give you lots of useful hooks to hang CSS styles on.
The headers of each column—the tags—can look different from other table
cells if you create a tag style, and you can use the tag as an easy
way to set the width of a table column. This saves you the hassle of having to create
lots of classes—like .tableHeader—and then apply them by hand to individual table
cells. In the next section, you’ll see examples of how you can use these different
tags to your advantage.
FIGURE 11-2
Data tables, like this one, usually have
headers created with the tag.
Header cells announce what type of
information appears in a row or column.
Price tells you that you’ll find the cost
of each lawn mower listed in the cells
below. The actual data presented in a
table is enclosed in tags.
Styling Tables
You can use many of the CSS properties you’ve read about to dress up the appearance of a table and its contents. You can use the color property, for example, to set
a table’s text color, just like anywhere else. You’ll find a few properties, however,
Chapter 11: Formatting Tables and Forms
359
STYLING
TABLES
that are particularly useful with tables, as well as a couple aimed specifically at
formatting tables.
Because tables are composed of several HTML tags, it helps to know which tag to
apply a particular CSS property to. Applying padding to a tag, for example,
has no effect. The next few sections cover CSS properties for formatting tables and
which HTML tags they get along with.
Adding Padding
As you read on page 187, padding is the space between an element’s border and
its content. You can use padding to provide a little space between the edges of a
paragraph’s text and its border. When it comes to tables, the borders are the edges
of a cell, so padding adds space around any content you’ve placed inside of a table
cell (see Figure 11-2). Using padding, you can individually control space between a
cell’s content and each of its four edges.
You apply padding to either a table header or a table cell tag, but not to the
tag itself. So, to add 10 pixels of space to the inside of all table cells, use this style:
td, th { padding: 10px; }
You can also control the spacing separately for each edge. To add 10 pixels of space
to the top of each table data cell, 3 pixels to the bottom of that cell, and 5 pixels on
both the left and right sides, create this style:
td {
padding-top: 10px;
padding-right: 5px;
padding-bottom: 3px;
padding-left: 5px;
}
Or, use the padding shortcut property:
td {
padding: 10px 5px 3px 5px;
}
Adjusting Vertical and Horizontal Alignment
To control where content is positioned within a table cell, use the text-align and
vertical-align properties.
Text-align controls horizontal positioning and can be set to left, right, center,
and justify (see Figure 11-3). It’s an inherited property. (See Chapter 4 for more
on inheritance.) When you want to right-align the contents of all table cells, create
a style like this:
table { text-align: right; }
360
CSS: THE MISSING MANUAL
This property comes in handy with tags, since browsers usually center-align
them. A simple style like th { text-align: left; } makes table headers align
with table cells.
STYLING
TABLES
FIGURE 11-3
You can control which edge of a
table cell its content aligns with
by using the text-align
property. Be careful with the
justify option, however.
Browsers aren’t very good at
aligning text to both the left
and right edges of an element.
The result is often big, distracting chunks of empty space in
the text.
Table cells have a height as well. Web browsers normally align content vertically in
the middle of a table cell (see the middle example in Figure 11-4). You can control
this behavior by using the vertical-align property. Use one of these four values:
top, baseline, middle, or bottom. Top pushes content to the top of the cell; middle
centers content; and bottom pushes the bottom of the content to the bottom of the
cell. Baseline works just like top, except the browser aligns the baseline of the first
line of text in each cell in a row (Figure 11-4). Unless you’re a real perfectionist, you
won’t even notice the subtlety of the baseline option. More importantly, neither will
your visitors. Unlike text-align, the vertical-align property isn’t inherited, so you
can use it only on styles that apply directly to and tags.
NOTE So far, the table formatting you’ve learned applies to all your tables. When you want to style individual
tables (or table cells), change the selector you use. To apply a special design to a certain table, give it a class
name——and create descendant selectors like .stocks td or stocks .th
to uniquely format individual cells. If you want to style a particular cell differently than other cells in a table, then
apply a class to the tag——and create a class style to format that cell.
Chapter 11: Formatting Tables and Forms
361
STYLING
TABLES
FIGURE 11-4
When padding is applied to a cell, the
content never actually aligns to the any
of the cell borders: There’s always a gap
equal to the padding setting.
Creating Borders
The CSS border property (page 194) works pretty much the same with tables as
with other elements, but you need to keep a couple of things in mind. First, applying a border to a style that formats the