Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Web Design & Development > CSS

📄 Contents

  1. The Base Page
  2. Corralling Long Text
  3. Graphic Effects Sans Graphics
This chapter is from the book

Graphic Effects Sans Graphics

You can create very graphic-looking speech bubbles without using any actual graphics. Avoiding graphics has many benefits beyond just being able to amaze your designer friends. You benefit by saving all the time and effort spent creating, slicing, and optimizing graphics, and then redoing them when your client inevitably wants to make one small change. Your visitors benefit from the increase in page speed that comes from having less data to download and fewer HTTP requests to the server.

Rounding the Corners

Those sharp, rectangular-cornered comments don't look very bubble-y, do they? Let's round the corners to start getting more of a speech-bubble look.

Rounded corners are a simple, common visual effect that used to be surprisingly hard to create in an actual web page. Creating the rounded-corner images in a graphics program was time-consuming, as was creating the actual HTML and CSS. You'd often have to add a bunch of extra nested divs to place each corner image separately, since CSS 2.1 allows only one background image per box, and the CSS used to actually control the placement of the images could get complicated. The images, along with the bloated markup and CSS, bulked up the amount that each visitor had to download, slowing down page-loading speeds. Even if you used a script to dynamically create the rounded corners instead of manually creating and applying images, you were still adding to the number of files that users had to download and decreasing your pages' performance. All this trouble for some simple-looking little rounded corners!

In CSS3, creating rounded corners can be as simple as border-radius: 10px on a single div. No extra markup, no images, no JavaScript.

Of course, while CSS3 continues to be developed and gain browser support, it's a little more complicated in real-world usage. But it's still really, really easy.

In your page, modify the blockquote rule to match the following:

blockquote {
   margin: 0 0 0 112px;
   padding: 10px 15px 5px 15px;
   -moz-border-radius: 20px;
   -webkit-border-radius: 20px;
   border-radius: 20px;
   border-top: 1px solid #fff;
   background-color: #A6DADC;
   word-wrap: break-word;
}

The border-radius: 20px; declaration is the W3C standard syntax for rounded corners, specifying that all four corners should be rounded by 20 pixels. This syntax is currently supported by Opera, Chrome, Safari 5, and IE 9. Firefox and Safari 4 and earlier use the -moz-border-radius and -webkit-border-radius properties, respectively. As explained in Chapter 1, browser vendors use these browser-specific prefixes when the specification is still being worked out and they think it may change. The non-prefixed version of the property (in this case, plain border-radius) should always come last, so that when browsers do support the non-prefixed property, it overrides the earlier rules, which may use non-standard behavior from an older version of the spec.

Table 2.2. border-radius browser support

IE

Firefox

Opera

Safari

Chrome

Yes, 9+

Yes with -moz-

Yes

Yes, 5+; 4+ with -webkit-

Yes

With these three lines added, the corners are now rounded in all browsers except IE 8 and earlier (Figure 2.4). These versions of IE simply ignore the properties and keep the corners straight—no harm done. This is a great example of progressive enhancement, as explained in Chapter 1. Since this is a purely decorative effect, I see no harm in IE users missing it. If you do, read on.

Figure 2.4

Figure 2.4 The border-radius property applied

Workarounds for IE

If you really must have rounded corners in IE 8 and earlier, you can use one of these scripts:

  • "PIE," by Jason Johnston (http://css3pie.com), reads the border-radius properties that are already present in your CSS and makes them work in IE 6 and later. It also adds several other CSS3 effects to IE.
  • "curved-corner," by Remiz Rahnas (http://code.google.com/p/curved-corner), also reads the border-radius properties out of your CSS, but works only when all four corners have the same border-radius.
  • "IE-CSS3," by Nick Fetchak (http://fetchak.com/ie-css3), is based off of curved-corner but also adds drop shadows in IE.
  • "DD_roundies," by Drew Diller (http://dillerdesign.com/experiment/DD_roundies), lets you round corners individually, but it doesn't read the values from your CSS; you have to manually set the IE values separately.

Besides these IE-specific scripts, there are a number of rounded-corner scripts and image-based techniques out there that were developed before the border-radius property gained support, so you could always go back to one of these older techniques for IE. You can choose between dozens of options at www.smileycat.com/miaow/archives/000044.php and http://css-discuss.incutio.com/wiki/Rounded_Corners.

If you do use a script or images for IE, make sure to hide them from other browsers by placing the script references or IE styles within conditional comments, or by using Modernizr, both of which are explained in Chapter 1. That way, only IE users get the performance hit of using an old-school rounded-corner method, and non-IE users get the faster, pure CSS version. You'll have to decide if the extra work and performance hit is worth having IE users see rounded instead of straight corners.

Adding the Bubble's Tail

With rounded corners, each comment box now looks more like a bubble, but a speech bubble isn't complete without a pointer or arrow, commonly called a "tail," pointing to the speaker. We can add that tail without using any graphics. In fact, we can add it without using any CSS3—the technique only uses properties and selectors from CSS 2.

Creating Triangles out of Borders

All we need to create a tail is a triangle, and you can create triangles with pure CSS by using regular old borders. When two borders of a box meet at a corner, the browser draws their meeting point at an angle (Figure 2.5). If you reduce that box's width and height to zero, and give every border a thick width and a different color, you'll end up with the appearance of four triangles pushed together, each pointing in a different direction (Figure 2.6).

Figure 2.5

Figure 2.5 By making the top border a different color, you can see that borders meet at corners at an angle.

Figure 2.6

Figure 2.6 When a box has no width or height, each border creates the appearance of a triangle.

Here's what the HTML and CSS used to create Figure 2.6 look like:

<div class="triangles"></div>

.triangles {
   border-color: red green blue orange;
   border-style: solid;
   border-width: 20px;
   width: 0;
   height: 0;
}

What would happen if you made the top, left, and bottom borders transparent instead of colored? Only the right border would show, leaving the appearance of a left-pointing triangle (Figure 2.7):

<div class="triangle-left"></div>

.triangle-left {
   border-color: transparent green transparent transparent;
   border-style: solid;
   border-width: 20px;
   width: 0;
   height: 0;
}
Figure 2.7

Figure 2.7 Making all but one of the borders transparent creates the appearance of a single triangle.

So, to sum that up, all you need to do to create a triangle using CSS is give an element zero width and height, give it thick borders, and make all but one of those borders transparent. You can vary the angle of the triangle by making the widths of the borders different on different sides.

Generating the Tail

Now that you know how to make an image-free triangle, let's add a left-pointing triangle to the left side of each comment, pointing to the commenter's avatar. To do this, we could nest a span or div inside each comment, and then transform this element into our triangle, but let's leave the HTML pristine and use CSS-generated content to make the element we need appear.

Generated content is a CSS 2.1 technique where you place content into your CSS to have it appear in your HTML. It's useful for adding things that you don't want to manually hard-code into the HTML, like numbers before headings or icons after links. It shouldn't be used for essential content that would be missed if the user couldn't access the CSS file.

To create generated content, you need to specify where the content is to be inserted, using either the ::before or ::after pseudo-elements (also written as :before and :after), and specify what content to insert, using the content property.

For instance, to insert the word "Figure" before every image caption on your page, you could use the following CSS:

.caption:before {
   content: "Figure: ";
}

This CSS would turn the HTML <p class="caption">Isn't my cat cute?</p> into this text when seen on the page:

Figure: Isn't my cat cute?

In the case of the speech-bubble tail we want to generate, all we want to see are the borders of the generated content, not the content itself. So, let's generate a piece of invisible content: a non-breaking space.

The HTML entity for a non-breaking space is &nbsp;, but you can't use HTML entities within the content property. Instead, you need to use the hexadecimal part of the character's Unicode code point (or reference). That may sound really confusing and difficult and science-y, but don't be scared—there are lots of handy charts online that allow you to look up this kind of stuff.

For instance, at www.digitalmediaminute.com/reference/entity you can see 252 little boxes, each showing one of the allowed entities in (X)HTML. In the "Filter entities by keyword" box, type "non-breaking space." 251 of the boxes will disappear, leaving you with one box showing &nbsp;, the HTML entity name. Position your cursor over the box (Figure 2.8). Two other codes will appear: its numerical code (in this case, &#160;) and its Unicode code (u00A0). You just want the hexadecimal part of the Unicode code, which is the part after the "u." Copy the text "00A0" onto your clipboard.

Figure 2.8

Figure 2.8 Use the XHTML Character Entity Reference to look up the Unicode code points of various entities.

Now we're almost there; but even though we now have the Unicode code we need, we can't put it straight into the content property, like so:

blockquote:after {
   content:"00A0";
}

If we did this, the browser would quite logically make the text "00A0" show up, instead of the non-breaking space. To tell the browser that we're putting in a special character code, we need to escape the code. If you're a programmer, you'll be familiar with this term, but for the rest of us, all it means is that you have to put a backslash in front of the code. This alerts the browser that what follows the slash is not to be taken as literal text, but is instead a code for something else.

With the backslash, we finally have all the correct characters and punctuation needed to insert a simple non-breaking space:

blockquote:after {
   content:"\00A0";
}

Once you do this, the page will look exactly the same; the non-breaking space is invisible, of course. Let's add the borders around it to make it show up. We also need to set its width and height to zero and make it display as a block element so we can move it around to place the tail against the side of the speech bubble:

blockquote:after {
   content: "\00a0";
   display: block;
   width: 0;
   height: 0;
   border-width: 10px 20px 10px 0;
   border-style: solid;
   border-color: transparent #000 transparent transparent;
}

If we had made all four borders the same width, we'd end up with a rather fat triangle, like the one shown in Figure 2.7. To make the triangle a little longer and thinner, we've set the top and bottom borders to only 10 pixels, and the left border is nonexistent at zero pixels. The right border—the one we use to create the appearance of a left-pointing triangle—is a nice, wide 20 pixels. All the borders except the right one are transparent; here I've set the right border's color to black temporarily just so we can see it in order to place it correctly (Figure 2.9).

Figure 2.9

Figure 2.9 The black right border creates the appearance of a left-pointing triangle.

The triangle is currently placed right after the blockquote's content—not the right spot for a speech bubble's tail. You can correct this by moving it with absolute positioning. First, add position: relative; to the blockquote rule; this establishes it as the reference point for the absolute element's positioning:

blockquote {
   position: relative;
   margin: 0 0 0 112px;
   padding: 10px 15px 5px 15px;
   -moz-border-radius: 20px;
   -webkit-border-radius: 20px;
   border-radius: 20px;
   border-top: 1px solid #fff;
   background-color: #A6DADC;
   word-wrap: break-word;
}

Then, add the absolute positioning to the generated content, along with top and left values:

blockquote:after {
   content: "\00a0";
   display: block;
   position: absolute;
   top: 20px;
   left: -20px;
   width: 0;
   height: 0;
   border-width: 10px 20px 10px 0;
   border-style: solid;
   border-color: transparent #000 transparent transparent;
}

You can set the top value to whatever you want; just make sure it's equal to or greater than the border-radius value so it lands on the straight edge of the box, below the corner curve. The left value should be a negative value in order to pull the triangle to the left, and it should match the width of the triangle. In this case, the width of the triangle is 20 pixels, because that's the width of the right border, so we're using a left value of –20px. This places the triangle right up against the left edge of the comment box (Figure 2.10).

Figure 2.10

Figure 2.10 Absolute positioning places the triangle where we want it.

It's possible that a comment might be so short that the tail hangs off the bottom, as seen in the second comment in Figure 2.10. To fix this, add min-height: 42px; to the blockquote rule.

blockquote {
   position: relative;
   min-height: 42px;
   margin: 0 0 0 112px;
   padding: 10px 15px 5px 15px;
   -moz-border-radius: 20px;
   -webkit-border-radius: 20px;
   border-radius: 20px;
   border-top: 1px solid #fff;
   background-color: #A6DADC;
   word-wrap: break-word;
}

Now that the triangle isn't layered over the blockquote, we can change its color to match the blockquote:

blockquote:after {
   content: "\00a0";
   display: block;
   position: absolute;
   top: 20px;
   left: -20px;
   width: 0;
   height: 0;
   border-1width: 10px 20px 10px 0;
   border-style: solid;
   border-color: transparent #A6DADC transparent
                 transparent;
}

This creates a seamless appearance between the bubble and the tail parts of each speech bubble (Figure 2.11).

Figure 2.11

Figure 2.11 Each tail is now colored and placed correctly.

Workarounds for IE

Our tail shows up fine in IE 8 and later versions, but IE 7 and earlier versions don't support generated content, so they don't see the tail. I think this is fine in this case, as there's no reason users of those browsers would see the plain rectangles and think, "Hey wait a second! Why isn't there a little triangle sticking out of each comment block?"

To add tails in IE 7 and earlier, you'd need to manually add another element to the HTML of each comment, such as an empty span, and turn this element into the triangle.

Semitransparent Backgrounds with RGBA or HSLA

There's nothing more that we have to do to create the appearance of a speech bubble—we've got the rounded corners and the tail—but it would be nice to add a little more depth and visual richness with some extra graphic details.

One great way to add depth is to make backgrounds semitransparent (also called alpha transparency). By letting a little bit of the page background show through, you create more of a layered appearance, as if the semitransparent element is floating over the background. I think this look is especially well-suited to speech bubbles, because, well, they're bubbles—light and airy.

Before CSS3, you could create semitransparent backgrounds using an alpha-transparent PNG as a tiling background image. Using a background image has the disadvantage of adding another hit to your server, making pages load a little slower for your users. Performance is impacted even more if you need to support IE 6, since it needs a script to be able to understand alpha-transparent PNGs. Plus, you can't use a background image on a border, so you wouldn't be able to make the speech bubble's tail semitransparent. It would look pretty weird for the body of the bubble to be semitransparent and the tail to be totally opaque.

CSS3's RGBA and HSLA Syntax

Luckily, in CSS3 we have both RGBA and HSLA to turn to. Both are methods for specifying a color and its level of transparency at the same time. RGBA stands for red-green-blue-alpha (for alpha transparency) and HSLA stands for hue-saturation-lightness-alpha.

We could specify the shade of blue that we're using as the speech bubble's background using any of these syntaxes:

  • Hexadecimal: #A6DADC
  • RGB: 166, 218, 220
  • RGBA: 166, 218, 220, 1
  • HSL: 182, 44%, 76%
  • HSLA: 182, 44%, 76%, 1

They all get us to the same exact color, just through different routes. It's a "you say toe-may-toe, I say toe-mah-toe" sort of thing.

In the RGBA syntax, the first three values are the amounts of red, green, and blue, either from 0–255 or 0%–100%. (You'll most often see the 0–255 values, not the percentages.) In the HSLA syntax, the first three values are the hue value, from 0 to 360; the percentage level of saturation; and the percentage level of lightness. In both RGBA and HSLA, the fourth value is the opacity level, from 0 (completely transparent) to 1 (completely opaque).

You can use most graphic editors to determine the correct red, green, and blue values needed to create your chosen color. Use the color picker to choose a color, and in the color dialog box or picker window, most graphic editors will tell you that color's hexadecimal code as well as RGB values (Figure 2.12). Finding HSL values can be a little trickier, as not all image-editing software uses HSL; for instance, Photoshop uses HSB (also called HSV), which is similar, but not quite the same. If you're on a Mac running Snow Leopard, check out the free app Colors by Matt Patenaude (http://mattpatenaude.com), which lets you pick colors from anywhere on your screen and can display values in HSLA as well as other syntaxes. If you're not on a Mac, I recommend you use one of the online HSL color picker or converter tools (see the "Online color tools" sidebar).

Figure 2.12

Figure 2.12 Photoshop's Color Picker dialog box shows the equivalent RGB values for the chosen hex color.

Some browser-based color pickers make finding HSL or RGB values even easier and faster. I'm a big fan of the Rainbow extension for Firefox (https://addons.mozilla.org/en-US/firefox/addon/14328). After you install the extension, you can tell it which syntax to use to display color values (Figure 2.13). Then, when you use its Inspector tool to choose colors from a web page, it gives you the option to automatically copy those values to your clipboard (Figure 2.14), and you can then easily paste them into your CSS. Note that, as of this writing, the extension doesn't include the "A" part of either RGBA or HSLA, so you'll have to add that part in by hand. But I think you can handle all that typing.

Figure 2.13

Figure 2.13 In the options for the Rainbow extension, set the "Display color values in" option to "Hsl."

Figure 2.14

Figure 2.14 Using Rainbow's Inspector tool, you can click on a color to display and copy its color code.

RGBA versus HSLA

The main reason I recommend the Rainbow Firefox extension over some other color picker extensions is that many others don't include HSL values, while Rainbow does, and I prefer HSLA over RGBA.

I'm in the minority here. Many more people use RGBA than HSLA, but I think that's mainly because most people haven't heard of HSLA. It's a shame, because the majority of people who use HSLA find it more intuitive.

With RGB and RGBA values, it's hard to tell at a glance what the color is going to be. If you take a minute to study a whole RGB or RGBA value, such as rgb(166,218,220), you can get a fair idea of the resulting color, based on which of the three component color values (red, green, or blue) are highest. But I'm not a big fan of taking that minute to parse it out while I'm trolling through my style sheet trying to track down where some mysterious color is coming from. And even after I determine that an RGB value is producing a greenish-blue hue, for instance, it's hard to tell how muted or dark that greenish-blue is by looking at only its red, green, and blue values.

Another problem with RGB and RGBA is that if you want to tweak a color—make it a little darker or brighter or greener—you have to guess at how to change each of the values to get to the hue you want. In web design, it's common to use multiple shades of the same hue in different places in the page, such as a brightened version of a color on the current tab in a nav bar. But with RGB, different shades of the same hue don't necessarily have very similar color values. For instance, a just slightly darker version of the shade of blue we've been working with would have an RGB value of 155, 209, 211 instead of the original 166, 218, 220. All three numbers have to change to produce a very slight shift in darkness.

With HSL and HSLA, you don't have to add amounts of red, green, and blue to get a specific hue, but instead set that hue as one specific number. All you have to do is remember that both 0 and 360 equal the same shade of pure red. As you increase the hue value from 0, you simply move through the rainbow from red to purple and then back around to red again, as if you were going around a color wheel (Figure 2.15).

Figure 2.15

Figure 2.15 The 360 hue values in the HSL color syntax

Table 2.3. RGBA and HSLA browser support

IE

Firefox

Opera

Safari

Chrome

Yes, 9+

Yes

Yes

Yes

Yes

Once you have the hue you want, you can then adjust its saturation if you want it duller or brighter, or adjust its lightness if you want it darker or lighter. It's easy to get multiple shades of the same color, or to tweak the color's hue just a little bit in one direction. Once you've worked with HSLA for a while and are more familiar with what each hue value computes out to, it's easier to tell at a glance what color you're going to get when you're glancing through the HSLA values in your style sheets.

The bottom line is this: RGBA and HSLA both have the same browser support and produce the same colors. I'm using HSLA throughout this book because it's more intuitive to me, but if you find RGBA easier, it's perfectly fine to use it instead.

Creating Semitransparent Speech Bubbles

Now that we've gotten all that syntax out of the way, we can switch the speech bubbles' background color from hexadecimal to HSLA notation and make them semitransparent.

The speech bubbles' background color is currently set to #A6DADC. We can figure out the HSLA equivalent using the Rainbow extension. Just open your speech-bubble page in Firefox, and use the Rainbow Inspector to click on the speech bubble background color. It will show you that the HSL value is hsl(182, 44%, 76%). Copy this value, go back to your code editor, and paste it over the current hexadecimal background color:

blockquote {
   position: relative;
   min-height: 40px;
   margin: 0 0 0 112px;
   padding: 10px 15px 5px 15px;
   -moz-border-radius: 20px;
   -webkit-border-radius: 20px;
   border-radius: 20px;
   border-top: 1px solid #fff;
   background-color: hsl(182,44%,76%);
   word-wrap: break-word;
}

If you save and refresh the page after this change, it will look exactly the same. You haven't changed the color yet—just changed the syntax for specifying it.

Now we'll modify this new syntax to make the speech bubbles semitransparent. Change background-color: hsl(182,44%,76%); to background-color: hsla(182, 44%,76%,.5);. Make sure to add the "a" of "hsla"!

You also want to change the tail to match. Copy and paste the HSLA value over the hexadecimal value in the border-color declaration:

blockquote:after {
   content: "\00a0";
   display: block;
   position: absolute;
   top: 20px;
   left: -20px;
   width: 0;
   height: 0;
   border-width: 10px 20px 10px 0;
   border-style: solid;
   border-color: transparent hsla(182,44%,76%,.5)
                 transparent transparent;
}

Save and refresh the page in your browser. You can now see the page background pattern showing through the speech bubbles slightly, as well as each commenter's avatar showing through the little bit of the tail that overlaps each picture (Figure 2.16).

Figure 2.16

Figure 2.16 Each speech bubble's background is the same shade of blue, but now semitransparent.

Workarounds for IE

You have a few options for working around the lack of HSLA/RGBA support in IE 8 and earlier.

  • Provide a replacement solid background color (in hexadecimal, RGB, or HSL syntax). If you declare the solid background color before the HSLA/RGBA version, using the background shorthand property on either both the colors or just the HSLA/RGBA one, IE 8 and earlier will use it and correctly ignore the HSLA/RGBA one. But if you use the background-color property instead of background to declare the HSLA/RGBA color, IE 7 and 6 won't use the solid color; they try to apply the HSLA/RGBA color and can't, so they display no color at all. In some pages, where the text is still readable even without a background color behind it, this would be acceptable. In those cases where it's not, and where you can't use the background shorthand property, you would need to feed IE 7 and earlier the solid background color in a rule that only IE can read. See Chapter 1 for your IE-feeding options.
  • Tile a tiny semitransparent PNG image as the background image. This has the advantage over the first option of actually making the background semitransparent, instead of opaque. It works in IE 8 and 7, but not IE 6 and earlier, since those versions don't support alpha-transparent PNGs. To work around this, you could use IE's AlphaImageLoader filter (or one of the many IE transparency scripts that makes use of the filter), feed IE 6 a solid background color, or feed IE 6 a GIF or PNG8 image. But all of this is a lot of extra work and could have a big impact on the performance of your pages—the AlphaImageLoader filter is horribly slow and an image is another HTTP request. (Plus, in our case, we couldn't use it on the speech bubbles' tails, since they are just borders and don't have background images.) I don't recommend using a PNG background image unless you don't need to worry about IE 6 and thus won't be providing any workarounds for its lack of alpha-transparent PNG support.
  • Use IE's Gradient filter, which works since version 5.5, and allows semitransparent colors (using its own proprietary syntax, of course). Just set both the starting and ending colors to the same color so you don't create the appearance of a gradient.

I recommend either the first or third option. The third more closely resembles the appearance we're going for, since the background will be semitransparent instead of solid. However, it's worth noting that the Gradient filter can do strange things to the anti-aliasing of the element's text and make it look a little uneven (peek ahead at Figure 2.17). You'll have to decide if the less pretty text is worth the more pretty background. Also, adding the filter will make the generated content tail disappear in IE 8 (it never appeared in 7 and 6 to begin with). I can't give you any explanation for this—it's just one of those weird IE bugs.

Figure 2.17

Figure 2.17 Before (top) and after (bottom) the Gradient filter is applied in IE 8. With the filter, the background color is semitransparent, but the anti-aliasing of the text is now a little uneven-looking.

In this case, I say let's go for the semitransparent background using the filter. Since we don't have rounded corners in IE to create the speech-bubble appearance, I don't mind losing the speech bubble's tail.

We could add the filter right inside the blockquote rule—non-IE browsers will just ignore it—but as discussed in Chapter 1, it's always nice to keep hacks and workaround separate from the standard rules. To keep the filters separate, we should either create a separate IE sheet, or use the conditional comments html tag trick described in Chapter 1. Let's use the html tag trick.

Go to the opening html tag of the page, and change it to the following HTML:

<!--[if lt IE 7]><html lang="en" class="ie6"><![endif]-->
<!--[if IE 7]><html lang="en" class="ie7"><![endif]-->
<!--[if IE 8]><html lang="en" class="ie8"><![endif]-->
<!--[if IE 9]><html lang="en" class="ie9"><![endif]-->
<!--[if gt IE 9]><html lang="en"><![endif]-->
<!--[if !IE]>--><html lang="en"><!--<![endif]-->

Now we can create one rule for IE 5.5, 6 and 7, and another rule for IE 8, since its filter syntax is a little different than that used in earlier versions of IE. Add the IE 7 and earlier rule first:

.ie6 blockquote, .ie7 blockquote {
   background: none;
   filter: progid:DXImageTransform.Microsoft.gradient
      (startColorstr=#99A6DADC, endColorstr=#99A6DADC);
   zoom: 1;
}

The Gradient filter simply declares a starting and ending color, both the same. The color values look strange, though, don't they? They're not your standard six-digit hexadecimal codes. The first two digits are the alpha transparency value. You can use any hexadecimal value between 00 and FF, with 00 being transparent and FF being opaque. The last six digits are the standard hexadecimal code for a color. So, the color #99A6DADC sets the alpha transparency to 99, the hexadecimal equivalent of the .6 level of transparency we're using in HSLA, and the color to A6DADC, the same blue we've been using all along.

In addition to applying the filter, this IE 7 and earlier rule removes the background color, which would override the filter. Also, IE 6 and earlier need to have hasLayout triggered on the blockquotes to make the filter work, which zoom: 1; accomplishes.

IE 8 doesn't need the background color removed, as it correctly ignores the HSLA background color on the main blockquote rule. It also doesn't need hasLayout triggered. But, it does have a slightly different syntax for filter properties. Add the following rule for IE 8:

.ie8 blockquote {
   -ms-filter: "progid:DXImageTransform.Microsoft.gradient
   (startColorstr=#99A6DADC, endColorstr=#99A6DADC)";
}

The differences in the filter syntax are that it's called -ms-filter instead of filter, and the value of the -ms-filter property is put in quotation marks. This syntax is more in line with the CSS specifications and how other browsers designate their proprietary properties.

Image-free Gradients

We can enhance the speech bubbles' backgrounds even further by giving each a subtle gradient to make them appear more rounded and three-dimensional. CSS3 allows you to create gradients without images, speeding up your development time and decreasing page-loading times, just as our image-free rounded corners can do. CSS-generated gradients also have the advantage of being able to scale with their containers in ways that image gradients can't, making them more versatile.

Unfortunately, CSS3 gradients are still very much in development at the time of this writing; their syntax is laid out only in a W3C editor's draft, not a more finalized working draft or candidate recommendation. Thus, be aware that the syntax for gradients is more likely to change than most of the CSS I'll describe in this book. Still, I think it's fine to add CSS that is a little experimental if you're using it in a very limited manner; non-supporting browsers won't be harmed by its lack, and supporting browsers won't be harmed if the syntax later changes. The (unlikely) worst-case scenario is that the syntax will totally change, making the gradients fail to appear in all browsers. I think I can live with this.

You can create both linear (straight) gradients and radial (circular or elliptical) gradients; we're just going to focus on linear gradients here. There is no gradient property; you specify a gradient using the linear-gradient or radial-gradient function as the value for any property that allows an image value, such as background-image and list-style image (though Firefox currently supports it only on background-image). When you specify a linear gradient, you tell the browser its starting point, angle, and starting and ending colors. You can also add extra colors in between the starting and ending colors and specify the exact position of each color along the line of the gradient.

Peachpit Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from Peachpit and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about Peachpit products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites; develop new products and services; conduct educational research; and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email ask@peachpit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by Adobe Press. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.peachpit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020