Chapter 6
In This Chapter
Adding reflections
Working with opacity
Manipulating text with strokes and shadows
Adding transformations to elements
Animating with transitions
CSS is great for adding visual interest to websites. Newer implementations of CSS go even further, adding new capabilities to web pages that once required hours of work in an image editor or programming language. In this chapter, you discover what you need to know to make your page elements pop out, reflect, turn, move, and even respond to basic input, all with CSS.
CSS allows you to apply some interesting special effects to your pages. These effects can be applied to any element, but they generally are applied to images and headlines. Note that these are still considered experimental, so the browser implementations vary.
CSS3 has complete support for adjustable opacity. This is reflected in a couple of ways. First, any element has an opacity attribute that can be set from 0 (fully transparent) to 1 (fully opaque).
Figure 6-1 shows a div with partial transparency superimposed on an image.
The complete code for this page is easy to follow:
<!DOCTYPE HTML>
<html lang = "en">
<head>
<title>opacity.html</title>
<meta charset = "UTF-8" />
<style type = "text/css">
body {
background-image: url("apoyo.jpg");
background-repeat: no-repeat;
}
h1 {
color: rgba(0, 0, 0, .3);
}
#box {
position: absolute;
top: 350px;
left: 100px;
height: 100px;
width: 100px;
border: 1px solid red;
background-color: white;
opacity: .3;
}
</style>
</head>
<body>
<h1>Opacity Demo</h1>
<div id = "box"></div>
</body>
</html>
All of the code is common HTML and CSS2 stuff, except the last attribute. The opacity attribute takes a single floating point value between 0 and 1. Zero (0) is completely transparent and one (1) is completely opaque.
Note that Figure 6-1 also illustrates the other main form of transparency supported by CSS — the headline uses the RGBA model to add alpha transparency to a color. Take a look at Chapter 4 of this mini-book for more on the rgba and hsla color models. In general, use alpha when you want to add partial transparency to an individual color. Opacity can be used for an entire element, even something complex like an image or a video.
All of the recent browser versions support opacity without requiring vendor-specific prefixes. Older browsers simply display the element as fully opaque, so anything under a partially transparent element may be invisible to older browsers.
Reflection is another one of those visual elements that adds quite a bit to a page when done well. Although it's not a formal part of the CSS3 specification, it is a promising technology. Currently only the WebKit-based browsers (that is, Safari, iPhone/iPad, and Chrome) support this capability. However, it shows such promise that some form of this capability is likely to appear in the other browsers at some point.
Figure 6-2 shows a reflected headline and image.
Apply the following CSS to make any element with the reflect class have a nice-looking reflection in the supported browsers:
-webkit-box-reflect: below 2px;
Basic reflections are quite simple:
Unfortunately, there is no generic version, nor has the reflect attribute been duplicated by other browsers.
Normally the reflection goes below the primary element, but it can also be above, left, or right.
The reflection can be placed right next to the original element, but often it looks better with a small gap. The gap is normally measured in pixels.
This will produce a very nice reflection.
However, reflections aren't usually pixel-perfect duplications. They tend to fade out over distance. WebKit allows you to add a gradient to a reflection. In this case, the gradient goes from completely opaque (white) to completely transparent (transparent).
.reflect {
-webkit-box-reflect: below 2px
-webkit-linear-gradient(bottom, white, transparent 40%, transparent); }
The standard part of the reflection is just like the previous example, but it includes a gradient that fades the reflection to transparency.
The gradient for a reflection is nearly linear. Note that the gradient is NOT a new CSS rule, but simply a parameter in the existing reflection rule.
Use top to indicate the gradient starts at the top, and bottom to indicate the gradient starts at the bottom. These values represent the top and bottom of the original image, not the reflection (which will, of course, be reversed). Normally, your gradient starts at the bottom of the original image (which is at the top of the reflected image).
The bottom of the original image is the top of the reflected image, and the top of the reflected image should be completely opaque. This gradient isn't really about color, but about which parts of the reflection are visible. Setting the initial color to white makes the top of the reflection completely opaque. (Of course, you can use rgba() to set any other transparency value you want, but only the alpha part is important in this context.)
The top of the original image (the bottom of the reflection) should be completely transparent, so end the gradient with the special color keyword transparent (which is equivalent to rgba(255, 255, 255, 0)).
Add a color stop to indicate where in the reflection you want the image to begin fading. I want the picture to begin fading around 40%, so I added an internal transparent color stop at 40%.
If you need a refresher on how gradients work, please check Chapter 4 of this mini-book.
Note that the reflected image is not calculated as a separate element for page layout purposes, so text and other content will flow right on top of your reflection.
Reflections are commonly applied to images, but they can be applied to any element, even video!
The most significant improvement to text in CSS is the @font mechanism described in Chapter 2 of this minibook. This technique allows you to define your own fonts and package them with your website. CSS3 has other text-formatting tricks available, too. The text-stroke and text-shadow rules allow you to make interesting transformations on text in your pages.
Both of these rules are used to decorate text, but they can impact readability, so you should use them carefully. They're more appropriate for larger text (like headlines) than the main content of your site.
With CSS3, you can specify a stroke color for your text. This defines an outline around the letter. You can specify the stroke color (using any of the standard CSS color values) as well as a stroke width (using the normal size attributes).
Figure 6-3 shows a page with stroked text.
The text-stroke rule applies this effect. You can see it used in the code:
<!DOCTYPE HTML>
<html lang = "en">
<head>
<title>textStroke.html</title>
<meta charset = "UTF-8" />
<style type = "text/css">
h2 {
color: yellow;
-webkit-text-stroke: 2px red;
font-size: 300%;
}
</style>
</head>
<body>
<h1>Text Stroke Demo</h1>
<h2>This text has a stroke</h2>
</body>
</html>
Currently no browsers support the text-stroke attribute directly, but WebKit-based browsers (Chrome and Safari) support the vendor-specific -webkit- version. A browser that does not support the rule will simply ignore it, so this should not be a significant part of your design until support is more complete.
Shadows are another common feature of modern web designs. Shadows add an element of depth to a page, but they can also enhance readability (if used properly) to lift a headline from the page. The text-shadow attribute was technically part of CSS2, but it has only recently been supported by major browsers. Figure 6-4 illustrates text-shadow in action:
<!DOCTYPE HTML>
<html lang = "en">
<head>
<title>textShadow.html</title>
<meta charset = "UTF-8" />
<style type = "text/css">
h2 {
font-size: 300%;
text-shadow: 5px 5px 2px #cccccc;
}
</style>
</head>
<body>
<h1>Text Shadow Demo</h1>
<h2>This text has a shadow</h2>
</body>
</html>
The text-shadow attribute has four parameters:
The size of the shadow is determined indirectly with a combination of offsets and blurs. You may have to experiment to get the shadow you're looking for. Shadow effects are best when they are subtle because they can affect readability. For Figure 6-4, I made the shadow darker than I would in a normal web page to ensure that the shadow is visible in the screen shot. Normally, I'd make the shadow even lighter to give an almost subconscious indication of depth.
A special case of text shadowing can be used to help text stand out against a background image. Apply a small shadow of a contrasting color. This technique is frequently used when you need to have text on a background because each letter produces its own high-contrast background. Again, be sure not to sacrifice readability for sake of design ethic.
All latest-model browsers support the text-shadow feature. No special prefixes are necessary.
One of the most consistent criticisms of early HTML was the limitations on how elements are displayed on the screen. An entire mini-book (Book III) is dedicated to screen layout, but CSS3 incorporates a significant new set of tools for modifying the position, size, and orientation of any element.
The transformation mechanism allows you to apply classic transformations (rotation, translation, or scale) on any element. The transition mechanism allows you to perform these changes over time. Together, these two techniques allow a relatively simple and powerful form of animation that once required sophisticated programming techniques or an external plug-in like Flash.
CSS3 includes the ability to apply geometric transformations onto any element. This provides a remarkable level of visual control not previously available to web developers.
The transform attribute allows you to apply a mathematical transformation to any div. When you apply transform to an element, you need to apply one or more of the following parameters to describe the type of transformation:
You can combine multiple parameters by listing them after the transform attribute separated by spaces.
To illustrate, imagine the following HTML snippet:
<div id = "box1">box 1</div><div id = "box2"> box 2</div><div id = "box3"> box 3</div><div id = "box4"> box 4</div><div id = "box5"> box 5</div>
The code shows five identical divs. For illustration purposes, all the divs share the same common CSS:
#box1, #box2, #box3, #box4, #box5{ width: 100px; height: 80px; border: 3px solid black; background-color: yellow; }
Apply variations of the transform attribute to each element to see how the transformations work.
#box2 { transform: translate(100px, 0px); } #box3 { transform: rotate(45deg); } #box4 { transform: scale(2) translate(100px, 0px); } #box5 { transform: skew(3); }
This code is illustrated in Figure 6-5.
Note that browser support is changing on this element. Chrome and Safari still expect the -webkit prefix, but Firefox and Opera support the non-prefixed version. IE 10 theoretically works with the standard version, but version 9 requires the -ms- prefix, and earlier versions of IE simply ignore transformations altogether. If you view the actual source code of the transform.html site, you'll see multiple versions of each rule to handle the various browsers:
#box2 {
transform: translate(100px, 0px);
-webkit-transform: translate(100px, 0px);
-ms-transform: translate(100px, 0px);
}
Eventually, common sense will break out and vendor-specific prefixes will no longer be necessary, but for the time being, it's safest to put them all in place. If you want to catch older versions of Firefox and Opera, you can also include these (-moz- and -o-) prefixes as well.
As browsers become more powerful, interesting new capabilities are emerging. One of the more exciting developments is the formation of 3D transformations. A 3D transform is similar to the traditional transformations, but it allows for a virtual third axis.
Ordinary, 2D animations utilize the 2D coordinate system, with an X axis going side-to-side and a Y axis traversing top-to-bottom. Even in 2D transformations, there is a tacit acknowledgment of a Z axis. The Z axis goes through the center of the object and points directly to the viewer's eyes and back into infinity behind the screen. 2D rotations are around this imaginary Z axis. You can determine which elements overlap other elements through the CSS z-index property, so although all screen elements are the same actual distance from the user, they appear to have some form of depth.
3D transformations have the same general operations as 2D (translate, rotate, and scale), but you can apply the transformation along one of the three axes: X, Y, or Z. This might seem confusing, so take a look at Figure 6-6 for some clarification:
In Figure 6-6, you see five boxes with nearly identical styles. Each box has a different 3D transformation applied:
Take a look at the code to see exactly what is happening here.
<!DOCTYPE HTML>
<html lang = "en">
<head>
<title>transform3D.html</title>
<meta charset = "UTF-8" />
<style type = "text/css">
body {
perspective: 1000;
-webkit-perspective: 1000;
}
#box1, #box2, #box3, #box4, #box5{
width: 100px;
height: 80px;
border: 3px solid black;
background-color: yellow;
}
#box2 {
transform: rotateX(45deg);
-webkit-transform: rotateX(45deg);
}
#box3 {
transform: rotateX(89deg);
-webkit-transform: rotateX(89deg);
}
#box4 {
transform: rotateX(180deg);
-webkit-transform: rotateX(180deg);
}
#box5 {
transform: rotate3D(1, 2, 0, 45deg);
-webkit-transform: rotate3D(1, -1, 0, 45deg);
}
</style>
</head>
<body>
<h1>3D Transform Demo</h1>
<div id = "box1">box 1</div>
<div id = "box1">box 2</div>
<div id = "box1">box 3</div>
<div id = "box1">box 4</div>
<div id = "box1">box 5</div>
</body>
</html>
The first new rule is perspective. Change the perspective of the parent element that will contain your transformed elements. This gives you the ability to determine how the elements appear to be displayed. The perspective indicates how close the camera appears to be to the elements. I applied a perspective of 1,000 to my example, which gives a decent illusion.
Boxes 2 through 4 all use the same transformation rule: rotateX(). This mechanism is much like the 2D rotate() function, but it rotates along the X axis. There are also rotateY() and rotateZ() functions, but rotateZ() is infrequently used because it's just like the 2D rotate() technique.
If you want to apply more than one rotation, you can use the rotate3d() function. This function takes four parameters. The first three are modifiers for the three axes, and the fourth is an angle. Looking at box 5, I've rotated 45 degrees in the X and Y axes.
CSS3 also supports the translateX, translateY(), and translateZ() functions. These mechanisms allow you to specify a translation along a specific axis. (They are not used frequently because the 2D translate() method encapsulates both translateX and translateY, and z-index is a well-established way to translate along the z axis.) The translate3d() function allows you to translate along multiple axes at the same time.
CSS3 includes scaleX, scaleY, and scaleZ functions, but again these are not always used because they act similar to the 2D scaling function. There is also a scale3d() function for use with multiple scales.
Support for the 3D transformations is growing but not complete. At the moment, the -webkit and no-prefix versions will support most browsers. The IE family of browsers has limited support for 3D transformations.
It's already possible to change CSS properties on the fly through pseudo-classes (like hover) or with JavaScript code. Prior to CSS3, all CSS state changes happened instantly. With the new transition attribute, you can cause transitions to happen over time.
Figure 6-7 demonstrates transitions, but as it involves movement, you really need to see this example in your browser.
Look at a simple h1 heading:
<h1>Transition Demo</h1>
The CSS code is mainly quite straightforward:
h1 { color: black font-size: 300%; transition:color 1s ease-in; }
h1:hover { color: red; }
Begin by ignoring the transition attribute. If you look at the rest of the code, it's easy to see what it does. In the normal state, the heading is black. In the hover state, the color is red. Typically, the heading turns red as soon as the mouse hovers over it, and will instantly turn black when the mouse leaves. However, when the transition attribute is added, the color change is not immediate, but takes a second. The color gradually changes from black to red and back.
Transitions are even more interesting when you pair them with transformations. Imagine a very simple div:
<div id = "box">Box 1</div>
Apply a little CSS3 magic and when the user hovers over the div, it rotates smoothly until it is upside-down. When the user leaves the div, it smoothly rotates back to its original position:
#box { transition: all 1s ease-in; height: 100px; width: 100px; border: 1px solid black; }
#box:hover { transform: rotate(180deg); }
The transform is defined in the: hover pseudo-class. The only new element is the transition specified in the class’ standard style.
The transition attribute takes several parameters:
If you prefer, you can use individual properties for the various parts of the animation, but most developer prefer the one-line shortcut (like the one used for borders).
Not all CSS attributes can be animated, but many can be. It may require some experimentation to determine which CSS attributes can be animated with the transition attribute.
Unfortunately, the stock transition attribute is not supported by any major browsers, but there are vendor-specific versions for Mozilla (-moz-), WebKit (-webkit-), and Opera (-o-). Your best bet until support is widespread is to include all vendor-specific versions in addition to the standard version.
The transform behavior is pretty cool, but CSS3 promises an even more exciting form of animation called the (wait for it) animation mechanism.
Figure 6-8 illustrates an animation of a box moving around the screen.
Of course, it doesn't make sense to view an animation in a book. You'll need to see this on the website.
Here's the basic strategy for building a CSS animation:
Animations are based on the notion of keyframes. Each keyframe specifies the state of an object, and the browser attempts to smoothly transition between keyframes.
The keyframe starts with a percentage, indicating where in the animation the keyframe will happen. The first keyframe should be 0% (the beginning of the animation) and the last should be 100% (the end of the animation). You can indicate as many intermediate keyframes as you want.
Place any styles you want modified in a little style sheet. At the indicated place in the timeline, an element following this animation will display the given style behavior. You can place any style information you want here.
The animation rule allows you to apply a keyframe to an element. You can reuse the same keyframes among many different elements if you want.
You can apply many of the same characteristics to an animation as you do a transition. There are a number of parameters, but the most commonly used elements are keyframe, time, and repeat.
Take a look at the code for animation.html to see it all in action:
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><title> animation.html</title>
<style type = "text/css"> @keyframes anim { 0% {left: 0px; top: 0px;} 25%
{left: 100px; top: 0px;} 50% {left: 100px; top: 100px;} 75% {left: 0px;
top: 100px;} 100% {left: 0px; top: 0px;} } @-webkit-keyframes anim { 0%
{left: 0px; top: 0px;} 25% {left: 100px; top: 0px;} 50% {left: 100px;
top: 100px;} 75% {left: 0px; top: 100px;} 100% {left: 0px; top: 0px;}
} @-moz-keyframes anim { 0% {left: 0px; top: 0px;} 25% {left: 100px;
top: 0px;} 50% {left: 100px; top: 100px;} 75% {left: 0px; top: 100px;}
100% {left: 0px; top: 0px;} } @-o-keyframes anim { 0% {left: 0px; top:
0px;} 25% {left: 100px; top: 0px;} 50% {left: 100px; top: 100px;} 75%
{left: 0px; top: 100px;} 100% {left: 0px; top: 0px;} } #box { position:
absolute; border: 1px solid black; -webkit-animation: anim 5s linear
infinite; -moz-animation: anim 5s linear infinite; -o-animation: anim
5s linear infinite; animation: anim 5s linear infinite; }
</style>
</head>
<body><div id = "box"> Moving box</div>
</body>
</html>
There are a number of things to note about this example:
Note there are many other parameters you can set, such as easing (described in the “Transition animation” section of this chapter) and delay. These can be set through the animation rule or with individual rules. For now, I tend to keep my animations as simple as possible, at least until the browsers can all manage animations without vendor prefixes.
You learn much more sophisticated animation techniques with JavaScript programming in Book IV.