Graphic Effects Sans Graphics - CSS3

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 borderradius:
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:

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.

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.

border-radius browser support

border-radius browser support

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

The borderradius property applied

The borderradius property applied

If you really must have rounded corners in IE 8 and earlier, you can use one of these scripts:
“PIE,” by Jason Johnston, reads the borderradius 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 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, is based off of curved-corner but also adds drop shadows in IE.

“DD_roundies,” by Drew Diller, 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.

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. 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.

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 . 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: By making the top border a different color, you can see that borders meet at corners at an angle.

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

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

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 above look like:

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 below):

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.

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:

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 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 . 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.

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

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:

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:

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:

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 below. 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 we’ve set the right border’s color to black temporarily just so we can see it in order to place it correctly .

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

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:

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

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 .

Absolute positioning places the triangle where we want it.

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 above. To fix this, add min-height: 42px; to the blockquote rule.

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

This creates a seamless appearance between the bubble and the tail parts of each speech bubble.

Each tail is now colored and placed correctly.

Each tail is now colored and placed correctly.

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. we 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. we think this look is especially ell-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.

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:

They all get us to the same exact color, just through different routes.
It’s a “you say toe-may-toe, we 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 . 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, 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, we recommend you use one of the online HSL color picker or converter tools (see the “Online color tools” sidebar).

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

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. We are a big fan of the Rainbow extension for Firefox. After you install the extension, you can tell it which syntax to use to display color values (Figure below). 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 , 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 we think you can handle all that typing.

In the options for the Rainbow extension, set the “Display color values in” option to “Hsl.”

In the options for the Rainbow extension, set the “Display color values in” option to “Hsl.”

FIGURE: Using Rainbow’s Inspector tool, you can click on a color to display and copy its color code.

FIGURE: Using Rainbow’s Inspector tool, you can click on a color to display and copy its color code.

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

We are in the minority here. Many more people use RGBA than HSLA, but we 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 we are not a big fan of taking that minute to parse it out while we are trolling through our style sheet trying to track down where some mysterious color is coming from. And even after we 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 equalthe 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 .

The 360 hue values in the HSL color syntax

The 360 hue values in the HSL color syntax

RGBA and HSLA browser support

RGBA and HSLA browser support

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.

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:

If you saveand 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:

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 .

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

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

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.

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.) we 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.

We 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 below). 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). We can’t give you any explanation for this—it’s just one of those weird IE bugs.

In this case, we 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, we don’t mind losing the speech bubble’s tail.

Before and after 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.

Before and after 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.

We could add the filter right inside the blockquote rule—non-IE browsers will just ignore it—but 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. Let’s use the html tag trick.

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

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:

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:

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. Still, we 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. We think we 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 lineargradient 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.

This sounds simple enough, but unfortunately, Firefox and Webkit (the only browsers that currently support gradients) differ on the syntax required to feed the browser this information; Firefox matches the official W3C syntax, and Webkit uses a very different (and more complicated) syntax that they developed first. Not only that, but even within each single syntax there are many variations on how you can specify the same gradient. It can get pretty confusing. To start off simply, let’s first apply a simple linear gradient to the speech bubbles to see a real example, before diving into the details of the full syntax.

Firefox’s syntax matches the official syntax being developed by the W3C and is generally easier to understand and use, so we’ll start with the gradient for Firefox.

First, add a linear gradient for Firefox in the background-image property of the blockquote rule, using the -moz-linear-gradient function:

This specifies a starting color (hsla(0,0%,100%,.6)), ending color (hsla(0,0%,100%,0)), and the position of the ending color (30px). Because we haven’t specified any starting point for the gradient or its angle, Firefox will simply use the default values, which makes the gradient start at the top of the box and run straight down. (If we did want to specify a starting point and/or angle, we’d do it at the start of the function. See “The lowdown on linear gradients” for the exact syntax.)

The starting color is white at 60 percent opacity, and the ending color is white at zero percent opacity (completely transparent). Laying semitransparent white over the background color creates a tint of whatever that background color is. In this case, it makes the gradient appear to be very light blue at the top and then fade away to nothing . We could have used an actual shade of light blue, but using semitransparent white in HSLA or RGBA is much more flexible. If we were to later change the color of the speech bubbles’ backgrounds to orange, for instance, we’d have to also change the light blue gradient to light orange. But since it’s white, it will always be a tint of whatever the background color is. Sticking with semitransparent white and black is the smartest way to create tints and shades of colors.

A gradient over the background makes the speech bubbles look more three-dimensional.

A gradient over the background makes the speech bubbles look more three-dimensional.

Right after he ending color value, there’s a space and then a value of 30px. This tells Firefox that you want it to place the ending color 30 pixels down the gradient. The gradient will run from the top of the box down 30 pixels, and then the ending color of the gradient will fill the rest of the vertical space. Since the ending color is completely transparent, it creates the appearance that the gradient covers only the top 30 pixels of the speech bubble.

That’s all you need to create the gradient in Firefox. Normally, we would tell you to copy and paste the background-image declaration and remove the -moz- bit from the second declaration to add the non-browser-specific version at the end. But in this case, the official syntax is still so early in its development that we think it’s best to leave it off and wait for it to become more finalized. We’ll stick with just the Firefox syntax, and add the Webkit syntax now.

For Webkit-based browsers, add another background-image declaration to the blockquote rule, this time containing the -webkit-gradient function:

As you can see, the Webkit syntax is very different—and more complicated.

Gradients browser support

Gradients browser support

First, you specify the type of gradient—linear or radial—within the -webkit-gradient function itself, instead of having separate lineargradient and radial-gradient functions.

Next, you specify the horizontal and vertical positions of the starting point (here, 0 0), followed by the horizontal and vertical positions of the ending point (here, 0 30). You can do this using keywords (such as top and left), percentages, or pixels, but strangely, Webkit requires you to leave off the “px” if you want to use pixels. So, in this case, we’re telling Webkit that we want the gradient to start at a point zero pixels across and zero pixels down the box (the top left corner) and end at zero pixels across and 30 pixels down the box. This makes the gradient run from the top to 30 pixels down the box, and then fill the rest of the box with the ending color, just like in Firefox.

After the starting and ending points, we have the starting color and the ending color. Just like with Firefox, you can use whatever color syntax you wish, but note that you must include from and to before each color.

The result of this -webkit-gradient CSS should look the same as Figure below.

The CSS syntax differences between Firefox and Webkit can be hard to remember. Luckily, you don’t have to memorize them if you don’t want to. There are some great gradient-generator tools online that allow you to use a visual editor to create the gradient, and then they write the corresponding CSS you need to use. Just copy and paste!

The CSS we’ve used so far works only in Safari, Chrome, and Firefox 3.6 and later, making gradients one of the less-supported features of CSS3. However, it’s one of the easiest features to provide workarounds for non-supporting browsers.(If you even choose to provide a workaround, that is—letting non-supporting browsers see the solid background color is an acceptable fallback in most cases.)

Picture it. The most obvious workaround for non-supporting browsers is to just go back to the good old-fashioned way of creating gradients: create an actual image gradient as an alpha-transparent PNG, set it as the background image on the blockquote, and tile it horizontally. Just make sure to declare this image before the two background- image declarations that contain the -moz-linear-gradient and -webkit-gradient functions. This allows browsers that do support gradients to override the first background-image property that uses an image with the later background-image property that creates a CSS3 gradient.

Of course, creating and using an image negates the efficiency benefits of using CSS3 to generate gradients for you. Firefox 3.6 won’t load the image that it doesn’t need, but Safari and Chrome will, even though they use the CSS3 gradient and never show the image. So, you keep the performance advantage of CSS3 gradients in Firefox 3.6, but lose it in Safari. Granted, you still get the other advantages of CSS3 gradients over image gradients, but the performance benefit is one of the most important.

Because of this performance hit in Webkit-based browsers, we recommend you either forgo the background image fallback, letting non-supporting browsers just miss out on the gradient, or hide the background image fallback from gradient-supporting browsers by using Modernizr. Of course, if you’re going to go to all the trouble of creating and applying a gradient image, you may decide it’s best to just use the image for all browsers and not use CSS3 gradients at all. There’s no right answer here, but our recommendation is to either use CSS3 gradients exclusively, or don’t use them at all and stick with images.

Use a script. For IE 6 through 8, you can use PIE. For other browsers, check out Weston Ruter’s css-gradients-via-canvas script. It works in browsers that support the HTML5 canvas element, so it makes gradients possible in Firefox 2 and 3 as well as Opera 9.64 and later. It doesn’t work in IE, but you could use it in combination with IE’s Gradient filter. Which leads us nicely to the next workaround…

Change color values for a different effect. We’re already using IE’s Gradient filter to create single-color semitransparent backgrounds on the blockquotes. We can modify the starting color values to be a lighter shade of blue to simulate the CSS3 gradient that we’re using.

In both IE rules, change the starting color in the Gradient filter from

By default, IE gradients run from top to bottom, so the resulting gradients in IE look reasonably similar to the ones in Firefox and Webkit based browsers . We can’t control the placement of the color stops in IE like we can with CSS3 gradients, but the filter works well for simple, two-color, linear gradients. It works only in IE 8 and earlier, though; IE 9 doesn’t support Microsoft filters. Thus, no gradient shows in IE 9, but at least IE 9 shows the semitransparent background color.

IE’s Gradient filter can simulate simple CSS3 gradients (shown here in IE 8).

IE’s Gradient filter can simulate simple CSS3 gradients (shown here in IE 8).

Note that if you have a fallback background image declared for other browsers, IE will let it override the Gradient filter. The IE 7 and earlier rule already removes any background that might be present, but the IE 8 rule doesn’t. Remember to add background: none; to the IE 8 rule if you add a background image to the main blockquote rule (because you’re adding a gradient image fallback, for instance).

Image-free Drop Shadows
In our continuing quest for three-dimensionality, we can add a drop shadow behind each speech bubble. Once again, we’ll do it without images.

Drop shadows on boxes are created in CSS3 using the box-shadow property. In the property, you set the shadow’s horizontal and vertical offsets from the box, its color, and you can optionally set blur radius as well as spread radius.

Add the following three lines of CSS to the blockquote rule:

Just as with border-radius, all three lines accomplish the same thing, but are read by different browsers; the non-prefixed box-shadow property will work only in IE 9 and Opera at the time of this writing.

The first value in each property, 1px, is the horizontal offset from the box, and it tells the browser to move the shadow one pixel to the right of the box’s edge. The second value, 1px, is the vertical offset, moving the shadow one pixel down. You can use negative values to move the shadow to the left and up instead.

The third value, 2px, is the blur radius, which specifies over how many pixels the shadow should stretch. A larger value makes the shadow blurrier and softer; a value of zero would make it completely sharp-edged.

The fourth value is the color—in this case, black at 30 percent opacity.
You can use any syntax for declaring the color in box-shadow, but HSLA or RGBA—the only syntaxes that can make a color semitransparent— are your best bets. Semitransparency is very handy for drop shadows, since you want to be able to see the background of whatever is behind the shadow peeking through a bit. If you made the shadow solid light gray, for instance, and then changed the page’s background to dark navy blue, you’d end up with a light gray shadow on top of a navy blue background. What you really want is an even darker navy blue shadow, as that’s how a shadow on something navy blue would look in real life. Using HSLA or RGBA for your drop shadows, and keeping the colors either black (for a shadow) or white (for a glow effect) allows you to switch the background color or image under the drop shadow and not have to make a corresponding change to the color of the shadow itself. It will appear to adjust its color to whatever is beneath it.

With box-shadow added to the blockquote rule, save the page, and check it out in an up-to-date browser to see the subtle greenish-gray shadow to the right and bottom of each speech bubble .

The box-shadow property adds a shadow beneath each speech bubble.

The box-shadow property adds a shadow beneath each speech bubble.

You’ll notice that the shadow pays attention to the border-radius and is also rounded to match the corners.

Our drop shadow does add that extra little hint of three-dimensionality, but we can increase that 3D appearance by making the speech bubbles appear to move forward a bit when each is hovered over. The farther away the speech bubble is from the background, the larger its shadow should appear. You increase the offset of the shadow on hover by adding this rule:

The negative top and left values are what actually shift the speech bubble and create the appearance of movement, but increasing the shadow as well—from 1 pixel offset to 3 pixels offset—makes the movement look more realistic . Increasing the shadow also makes it appear more like the speech bubble is moving away from the background and closer to the user, instead of just farther up the page.

The larger shadow on hovered speech bubbles makes them appear to jump out at you a bit.

The larger shadow on hovered speech bubbles makes them appear to jump out at you a bit.

TABLE: box-shadow browser support

TABLE: box-shadow browser support

The box-shadow property is not supported by IE 8 and earlier, but as with gradients, you can use IE’s filters to fake it. The DropShadow and Shadow filters are specifically designed to create drop shadows, and Glow works if you want an even glow around all sides of the box. Unfortunately, these filters don’t offer as many customization options for the drop shadow as you have with CSS3 box-shadow, as Chris Casciano demonstrates and explains in his article “CSS3 Box Shadow in Internet Explorer [Blur-Shadow]”. We don’t think any of these filters will create the particular effect we want in this case.

Also in this article, Chris shows a clever technique using IE’s Blur filter instead of DropShadow, Shadow, or Glow to create a more realisticlooking drop shadow, but the technique requires making a copy of the box in the HTML, and then blurring this copy. The extra HTML elements required in these tutorials are an acceptable compromise when you really must have a drop shadow in IE, but in the case of our speech bubbles, we don’t think the extra work and extra file size that would result from all those extra divs is worth the small visual gain. So we’re not going to walk through the steps to implement the Blur filter solution here; we’ll be satisfied with no drop shadows in IE.

Image-free Text Shadows
Why should the boxes get to have all the fun—shouldn’t text be able to have drop shadows too? Happily for us, CSS3 has a property named text-shadow that does just that.

The text-shadow property can give you a nice accessibility and usability benefit. With the graphic effects we’ve already looked at in this chapter, the CSS3 equivalent just replaces a decorative image, such as replacing a GIF of a curved corner with a CSS-generated curved corner—kind of trading an image for a faux-image. The text-shadow property, on the other hand, allows you to replace an image of text with real text. For instance, you may have a headline that you want to have a shadow behind it. Before text-shadow, you might create an image of that headline and its shadow and display that image in your page. The user has no control over text in an image to make it more readable for him or herself by scaling it, changing its color, changing the font, and any number of other things you can do to real text. Using text-shadow on real text gives control back to the user.

Using real text with text-shadow applied can also improve readability by creating more contrast between the text and its background. Have you ever watched a movie with closed captioning? The captions probably had a small shadow or outline around them to make the text stand out more on a variety of background colors. Slight drop shadows behind text in web pages can give the same readability boost.

Other advantages of real text: it’s searchable, it can be selected to copy and paste, and it’s more quickly and easily editable by you or your client than an image or Flash movie would be.

Of course, like many web techniques, text-shadow can backfire and decrease usability if not used well. We are certainly not saying you should go out and add drop shadows to all your text; there are many cases where it would impede readability. You also always need to make sure that the text is still readable if the shadow isn’t there. But text-shadow is another tool in your arsenal that you can choose to use when appropriate.
So, text-shadow sounds great—how do you apply it?


Let’s add a text-shadow on hover to highlight the chosen comment just a bit. Add the following line to the blockquote:hover rule:
text-shadow: 1px 1px 1px hsla(0,0%,100%,.7);

The syntax is almost exactly the same as the syntax for box-shadow.
(The only difference is that you can’t set spread radius or inset on text-shadow.) We have a horizontal offset, vertical offset, optional blur radius, and color. In this case, there’s no need to add any browser specific prefixes; Firefox, Safari, Chrome, and Opera all support the standard text-shadow property. Figure below shows the subtle shadow that appears behind the text of a blockquote that’s being hovered over.

A white shadow appears to the right and bottom of the text in the speech bubble that the user has her mouse over.

A white shadow appears to the right and bottom of the text in the speech bubble that the user has her mouse over.

Another nice place to add a shadow behind text is the commenter’s name and date of comment. These two pieces of text are pretty small and are sitting on top of a patterned background. A very slight, sharp edged text shadow would give it a subtle outline to make it stand out more and be a little easier to read.

Add the following line to the existing. comment-meta rule:
text-shadow: 1px 1px 0 hsla(0,0%,100%,.7);

The effect this produces is very subtle, but it needs to be. A thick outline around such small text would look strange and probably make it harder to read. But the slight text shadow we’re using adds just a little bit of contrast to make the text just a little bit more readable .

FIGURE: The sharp-edged shadow on the commenter’s name and date makes the text stand out a bit more compared to the non-shadowed text.

TABLE: text-shadow browser support

text-shadow browser support

The DropShadow, Shadow, or Glow filters for IE that we mentioned earlier can actually create shadows behind text too, not just boxes. To get a text shadow instead of a box shadow, you write the filter in the exact same way, but make sure there is no background color or background image on the element. If it has a background, IE will apply the shadow to the box; if it doesn’t have a background, it will apply the shadow to the content.

Unfortunately, when any of these filters are applied to text, they make that text very jagged. It’s similar to the unevenness of the text that showed up when we applied the gradient filter in IE (see Figures below), but more extreme. In the case of our speech bubbles, we think it really impairs the readability, and the whole point of adding textshadow here was to enhance readability. So, we won’t be adding IE filters to any text here.

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd Protection Status

CSS3 Topics