CSS CHAPTER 2 2018-12-19T12:20:53+00:00

CSS CHAPTER 2

Topics:- (Background image basics, Rounded-corner boxes, Drop shadows, Opacity, Image replacement, Simple link styling, Fun with underlines, Visited-link styles, Styling link targets, Highlighting different types of links, Creating links that look like buttons)

Now that you are all up to speed with the theory, let’s start putting this into practice. Today’s Web is a very visual medium. The humble image tag has allowed web designers to turn dull and uninspiring documents into graphically rich experiences. Graphic designers quickly seized on the image tag (originally intended as a way to add visual content to a website) as a way of visually embellishing a page. In fact, if it wasn’t for the invention of the image tag, the profession of web designer may never have evolved. Unfortunately, we’ve used the image tag to clutter our pages with purely presentational images. Luckily, CSS gives us the ability to display an image on a page without it being part of the markup. This is achieved by adding an image as a background to an existing element. Through a series of practical examples, this chapter will show you how background images can be used to create a variety of interesting and useful techniques.

In this chapter you will learn about

Fixed- and flexible-width rounded-corner boxes

The sliding doors technique

Mountaintop corners

CSS drop shadows

PNG transparency support for Internet Explorer 5.x and above

Image replacement

Ordering your link selectors based on the cascade

Creating stylized link underlines

Styling external links using attribute selectors

Making links behave like buttons

Creating visited-link styles

Creating pure CSS tooltips

Background image basics

Applying a background image is easy. Say you want your website to have a nice tiled background. You can simply apply the image as a background to the body element:

body {

background:url(pattern.gif);

}

The default browser behavior is to repeat background images horizontally and vertically so that the image tiles across the whole of the page. For more control you can choose whether your background image tiles vertically, horizontally, or not at all. Gradients are very fashionable at the moment so you may want to apply a vertical gradient to your page instead. To do this, create a tall but narrow gradient graphic. You can then apply this graphic to the body of the page and let it tile horizontally:

body {

background: #ccc url(gradient.gif) repeat-x;

}

Because the gradient has a fixed height, it will stop abruptly if the content of the page is longer than the height of the image. You could choose to create a really long image, possibly one that fades to a fixed color. However, it is always difficult to predict how long a page will become. Instead, simply add a background color as well. Background images always sit on the top of the background color, so when the image runs out the color will be displayed. If you choose a background color that is the same as the bottom of the gradient, the transition between image and background color will be seamless.

Tiling images can be useful in some situations. However, most of the time, you will want to add nontiled images to your page. For instance, say you want your web page to start with a large branding image. You could simply add the image directly into the page, and in many situations this would be the correct thing to do. Yet if the image contains no information and is purely presentational, you may want to separate the image from the rest of your content. You can do this by creating a hook for the image in your HTML and applying  the image using CSS. In the following example we have added an empty div to the markup and given it an ID of branding. You can then set the dimensions of the div to be the same as the branding image, apply it as a background, and tell it not to repeat.

#branding {

width: 700px;

height: 200px;

background:url(/images/branding.gif) no-repeat;

}

Lastly, it is possible to set the position of your background image. Say you want to add a bullet to every headline on your site, as shown in Figure 2-1. You could do something like this:

h1 {

padding-left: 30px;

background: url(/images/bullet.gif) no-repeat left center;

}

Figure 2-1. Creating a bullet using a background image

The last two keywords indicate the positioning of the image. In this case, the image will be positioned to the left of the element and vertically centered. As well as using keywords, you can set a background image’s position using units such as pixels or percentages. If you set a background position using pixels, the top-left corner of the image is positioned from the top-left corner of the element by the specified number of pixels. So if you were to specify a vertical and horizontal position of 20 pixels, the top-left corner of the image will appear 20 pixels from the top-left corner of the element. However, background positioning using percentages works slightly differently. Rather than positioning the top-left corner of the background image, percentage positioning uses a corresponding point on the image. So if you set a vertical and horizontal position of 20 percent, you are actually positioning a point 20 percent from the top left of the image, 20 percent from the top left of the parent element (see Figure 2-2).

Figure 2-2. When positioning background images using pixels, the top-left corner of the image is used. When positioning using percentages, the corresponding position on the image is used.

If you want to position the previous bullet example using percentages instead of keywords, setting the vertical position to 50 percent would vertically center the bullet image:

h1 {

padding-left: 30px;

background: url(/images/bullet.gif) no-repeat 0 50%;

}

The specification says that you are not supposed to mix units such as pixels or percentages with keywords. This seems like a nonsensical rule and one that many modern browsers deliberately ignore. However, mixing units and keywords fails to work on certain browsers and will most likely invalidate your page. As such, it is best not to mix units with keywords at this time. While background images are a simple concept to grasp, they form the basis of many advanced CSS techniques.

Rounded-corner boxes

One of the first criticisms leveled against CSS-based designs was that they were very square and boxy. To get around this, people started creating designs that incorporated more organic curved shapes. Rounded-corner boxes very quickly became one of the most soughtafter CSS techniques around. There are various ways of creating rounded-corner boxes. Each approach has its strengths and weaknesses, and the one you choose depends largely on your circumstances.

Fixed-width rounded-corner boxes

Fixed-width rounded-corner boxes are the easiest to create. They require only two images: one for the top of the box and one for the bottom. For example, say you want to create a box style like the one in Figure 2-3.

Figure 2-3. A simple rounded-corner box style

The markup for the box looks something like this:

<div class=”box1″>

<h2>Headline</h2>

<p>Content</p>

</div>

In your favorite graphics package you need to create two images like those in Figure 2-4: one for the top of the box and one for the bottom. 

Figure 2-4. The top and bottom curve graphics

You then apply the top image to the heading element and the bottom image to the bottom of the box div. Because this box style just has a solid fill, you can create the body of the box by adding a background color to the box div.

.box1 {

width: 418px;

background: #effce7 url(images/bottom.gif) norepeat left bottom;

}

.box1 h2 {

background: url(images/top.gif) no-repeat left top;

}

You will not want your content to butt up against the sides of the box, so you also need to add some padding to the elements inside the div:

.box1 h2 {

padding: 10px 20px 0 20px;

}

.box1 p {

padding: 0 20px 10px 20px;

}

This is great for a simple box with a solid color and no borders. But what if you want to create a fancier style, such as the one in Figure 2-5?

Figure 2-5. Example of a stylized rounded-corner box

You can actually use the same approach, but this time, instead of setting a background color on the box, you can set a repeating background image. For this to work you will need to apply the bottom curve image to another element. In this case, we used the last paragraph element in the box:

.box1 {

width: 424px;

background: url(images/bg-tile.gif) repeat-y;

}

.box1 h2 {

background: url(images/bg-top.gif) no-repeat left top;

padding-top: 20px;

}

.box1 .last {

background: url(images/bg-bottom.gif) no-repeat left bottom;

padding-bottom: 20px;

}

.box1 h2, .box1 p {

padding-left: 20px;

padding-right: 20px;

}

<div class=”box1″>

<h2>Headline</h2>

<p class=”last”>Content</p>

</div>

Figure 2-6 shows the resulting styled box. Because no height has been given to the box, it will expand vertically as the text size is increased.

Figure 2-6. Styled fixed-width box. The height of the box expands as the text size is increased.

Flexible rounded-corner box

The previous examples will all expand vertically if you increase your font size. However, they do not expand horizontally as the width of the box has to be the same as the width of the top and bottom images. If you want to create a flexible box, you will need to take a slightly different approach. Instead of the top and bottom curves consisting of a single image, they need to be made up of two overlapping images (see Figure 2-7).

Figure 2-7. Diagram showing how the top graphics expand to form a flexible rounded-corner box

As the box increases in size, more of the larger image will be revealed, thus creating the illusion that the box is expanding. This concept is sometimes referred as the sliding doors technique because one image slides over the other, hiding it from view. More images are required for this method to work, so you will have to add a couple of extra, nonsemantic elements to your markup.

<div class=”box1″>

<div class=”box-outer”>

<div class=”box-inner”>

<h2>Headline</h2>

<p>Content</p>

</div>

</div>

</div>

This method requires four images: the top two images make up the top curve, and the bottom two images make up the bottom curve and the body of the box (see Figure 2-8). As such, the bottom images need to be as tall as the maximum height of the box. We will name these images top-left.gif, top-right.gif, bottom-left.gif, and bottom-right.gif.

Figure 2-8. The images required to create the flexible rounded-corner box

First you apply the bottom-left.gif to the main box div and bottom-right.gif to the outer div. Next you apply top-left.gif to the inner div and finally top-right.gif to the heading. Lastly, it is a good idea to add some padding to space out the contents of the box a little.

.box1 {

width: 20em;

background: #effce7 url(images/bottom-left.gif) no-repeat left bottom;

}

.box-outer {

        background: url(images/bottom-right.gif) no-repeat right bottom;

        padding-bottom: 5%;

}

      .box-inner {

        background: url(images/top-left.gif) no-repeat left top;

}

      .box1 h2 {

        background: url(images/top-right.gif) no-repeat right top;

        padding-top: 5%;

}

      .box1 h2, .box p {

        padding-left: 5%;

        padding-right: 5%;

}

In this example we have set the width of the box in ems, so increasing the text size in your browser will cause the box to stretch (see Figure 2-9). You could, of course, set the width in percentages, and have the box expand or contract depending on the size of the browser window. This is one of the main principles behind elastic and flexible layouts.

Figure 2-9. Flexible rounded-corner boxes expand both horizontally and vertically as the text is resized.

The addition of a couple of extra nonsemantic elements is not ideal. If you only have a couple of boxes it is probably something you can live with. But if you are concerned you could always add the extra elements using JavaScript (and the DOM) instead. For more details on this topic, see the excellent article by Roger Johansson of 456 Berea Street at http://tinyurl.com/82y8l.

Mountaintop corners

Mountaintop corners are a simple yet very flexible concept, first coined by Dan Cederholm of www.simplebits.com, author of the best-selling friends of ED book Web Standards Solutions (friends of ED, 2004). Suppose you want to create a variety of different colored rounded-corner boxes. Using the previous methods you’d have to create different corner graphics for each color theme. This may be okay if you only had a couple of themes, but say you wanted to let your users create their own themes? You’d probably have to create the corner graphics dynamically on the server, which could get very complicated. Fortunately, there is another way. Instead of creating colored corner graphics, you can cre ate curved, bitmap corner masks (see Figure 2-10). The masked area maps to the back-ground color you are using while the actual corner area is transparent. When placed over a colored box, they give the impression that the box is curved (see Figure 2-11).

Figure 2-10. Bitmapped corner mask. The white mask will cover the background color, creating a simple curved effect.

As these corner masks need to be bitmapped, subtle curves work best. If you try to use a large curve, it will appear jagged and unsightly. The basic markup is similar to the previous method; it requires four elements to apply the four corner masks to:

<div class=”box1″>

<div class=”box-outer”>

<div class=”box-inner”>

<h2>Headline</h2>

<p>Content</p>

</div>

</div>

</div>

The CSS is also very similar:

.box1 {

width: 20em;

background: #effce7 url(images/bottom-left.gif) no-repeat left bottom;

}

          .box-outer {

            background: url(images/bottom-right.gif) no-repeat right bottom;

            padding-bottom: 5%;

}

          .box-inner {

            background: url(images/top-left.gif) no-repeat left top;

}

          .box1 h2 {

            background: url(images/top-right.gif) no-repeat right top;

            padding-top: 5%;

}

          .box1 h2, .box p {

            padding-left: 5%;

            padding-right: 5%;

}

Figure 2-11. Mountaintop corner box

The main difference, apart from using different images, is the addition of a background color on the main box div. If you want to change the color of the box, you can simply change the color value in the CSS without having to recreate any new graphics. This method is only suitable for creating very simple boxes; however, it provides a great deal of flexibility and can be used over and over again on different projects.

Drop shadows

Drop shadows are a popular and attractive design feature, adding depth and interest to an otherwise flat design. Most people use a graphics package like Photoshop to add drop shadows directly to an image. However, using the power of CSS it is possible to apply simple drop shadow effects without altering the underlying image.

There are various reasons you may want to do this. For instance, you may allow nontechnical people to administer your site who have no experience using Photoshop, or you may simply be uploading images from a location where you do not have access to Photoshop, such as an Internet cafe. By having a predefined drop shadow style, you can simply upload a regular image and have it displayed on your site with a drop shadow. One of the nicest benefits of using CSS is that it is nondestructive. If you decide that you want to remove the drop shadow effect later on, you can simply alter a couple of lines in your CSS files rather than having to reprocess all of your images.

Easy CSS drop shadows

This very simple drop shadow method was first described by Dunstan Orchard of www.1976design.com. It works by applying a large drop shadow graphic to the background of a wrapper div. The drop shadow is then revealed by offsetting the image using negative margins. The first thing you need to do is create the drop shadow graphic. Create a new Photoshop file, the dimensions of which are as large as the maximum size of your image. We created a file that’s 800 pixels by 800 pixels just to be on the safe side. Unlock the background layer and fill it with the color you want your shadow to sit on. In my case I simply kept the background layer white. Create a new layer and fill it with white. Now move this layer up and left by 4 or 5 pixels and then apply a 4- or 5-pixel-wide drop shadow to this layer. Save this image for web and call it shadow.gif (see Figure 2-12).

Figure 2-12. The 800800 shadow.gif zoomed in so you can see the 5-pixel drop shadow

The markup for this technique is very simple:

<div class=”img-wrapper”><img src=”dunstan.jpg” width=”300″ height=”300″ alt=”Dunstan Orchard” /></div>

It is important to keep the code on one line and not separate the div and the image using whitespace. IE 5.5 has a whitespace bug that will cause a gap between the image and the drop shadow if your code is on separate lines.

To create the effect, you first need to apply your shadow graphic to the background of the wrapper div. Because divs are block-level elements, they stretch horizontally, taking up all the available space. In this situation we want the div to wrap around the image. You can do this by explicitly setting a width for the wrapper div, but doing so reduces the usefulness of this technique. Instead, you can float the div, causing it to “shrink-wrap” on modern browsers, with one exception: IE 5.x on the Mac. You may want to hide these styles

from IE 5.x on the Mac.

.img-wrapper {

background: url(images/shadow.gif) no-repeat bottom right;

clear: right;

float: left;

}

To reveal the shadow image and create the drop shadow effect (see Figure2-13), you need to offset the image using negative margins:

.img-wrapper img {

margin: -5px 5px 5px -5px;

}

Figure 2-13. Image with drop shadow applied

You can create a good, fake photo border effect by giving the image a border and some padding (see Figure 2-14):

.img-wrapper img {

background-color: #fff;

border: 1px solid #a9a9a9;

padding: 4px;

margin: -5px 5px 5px -5px;

}

Figure 2-14. The final result

This works for most modern, standards-compliant browsers. However, we need to add in a couple of simple rules to get it working correctly in IE 6:

.img-wrapper {

background: url(images/shadow.gif) no-repeat bottom right;

clear: right;

float: left;

position: relative;

}

.img-wrapper img {

background-color: #fff;

border: 1px solid #a9a9a9;

padding: 4px;

display: block;

margin: -5px 5px 5px -5px;

position: relative;

}

The drop shadow effect now works in IE 6. The padding on the image does not show up in IE 5.x, but this is a relatively minor, presentational issue and one you can safely ignore.

Drop shadows a la Clagnut

Richard Rutter of www.Clagnut.com came up with a similar method for creating drop shadows. Instead of using negative margins, his technique uses relative positioning to offset the image:

.img-wrapper {
            background: url(images/shadow.gif) no-repeat bottom right;
            float:left;
            line-height:0;
}

.img-wrapper img {

background:#fff; padding:4px;
border:1px solid #a9a9a9; position:relative; left:-5px;

top:-5px;

}

The padding on the image still does not display in IE 5.x, but in general browser support for this method is good.

Fuzzy shadows

The preceding methods provide a simple way to create a drop shadow effect. However, the one major criticism is the drop shadow’s hard edge. If we were creating the effect in a graphics package like Photoshop the edges would fade into the background, creating a much more natural look. You can see a comparison of these two effects in Figure 2-15.

Figure 2-15. Some people don’t like the hard edge the preceding techniques create, preferring a more photorealistic technique.

Luckily you can re-create this effect with the clever use of PNGs, masking, and the addition of a nonsemantic div. This method works by creating a PNG with alpha transparency to mask the edges of the drop shadow graphic. First you need to make the masking PNG. Create a new Photoshop file that’s 800 pixels by 800 pixels. Delete the contents of the background layer and then make a 5-pixel-wide selection at the right edge of the screen. Fill this with a gradient from white to transparent. Make a 5-pixel-high selection at the top of the page and again, fill this with your gradient. You should end up with a white, fuzzy border along the top and left of your document, as shown in Figure 2-16. Now save this as a 24-bit PNG and name the file mask.png.

Figure 2-16. The transparent edges of this PNG will mask the corners of the shadow graphic, creating nice soft corners.

Unfortunately, older versions of IE do not support PNG alpha transparency. To deal with these browsers, you need to create an alternative graphic. In this case we have created a simple GIF mask that has a solid white 5-pixel left and top fill.

The markup for this technique looks like this:

 <div class="img-wrapper">
       <div>
       <img src="dunstan.jpg" width="300" height="300" alt="Dunstan" />
       </div>
</div>

To create this effect, you first need to apply the shadow graphic to the img-wrapper div, aligning it to the bottom right:

 .img-wrapper {
        background: url(images/shadow.gif) no-repeat right bottom;
        float: left;
}

Next you apply the masking image to the top right of the inner div. This lays the mask image over the top of the shadow image, masking the hard left and top edges, and creating a nice soft edge. At the moment both of these background images are covered by the 3 main image. To create the offset you simply apply some padding to the bottom and right of the inner div:

.img-wrapper div {
        background: url(images/mask.png) no-repeat left top !important;
        background: url(images/mask.gif) no-repeat left top;
        padding: 0 5px 5px 0;
}

You will notice that we have applied both the PNG and the GIF to this rule. This is to accommodate both newer browsers that support PNG alpha transparency, as well as versions of IE that do not. Using a hack called the !important hack, the PNG will be displayed by more modern browsers, while IE users will be presented with the GIF. IE 5.2 on the Mac doesn’t “shrink-wrap” floated elements if they contain a block-level element. To get around this problem, we can simply float the second div as well as the first:

.img-wrapper div {

background: url(images/mask.png) no-repeat left top !important;

background: url(images/mask.gif) no-repeat left top;

padding: 0 5px 5px 0;

float: left; /* :KLUDGE: Fixes problem in IE5.2/Mac */

}

Lastly, we add the border effect to the image element:

 .img-wrapper img {
        background-color: #fff;
        border: 1px solid #a9a9a9;
        padding: 4px;
}

Bringing all these steps together, the complete CSS looks like this:

    .img-wrapper {
        background: url(images/shadow.gif) no-repeat right bottom;
        float: left;
}
      .img-wrapper div {
        background: url(images/mask.png) no-repeat left top !important;
        background: url(images/mask.gif) no-repeat left top;
        padding: 0 5px 5px 0;
        float: left; /* :KLUDGE: Fixes problem in IE5.2/Mac */
}
      .img-wrapper img {
        background-color: #fff;
        border: 1px solid #a9a9a9;
        padding: 4px;
}

And the final effect should look like Figure 2-17.

Figure 2-17. The final effect

If you wanted, you could leave this effect here, serving up a PNG to good browsers and a GIF to everything else. Unfortunately, as we all know, Internet Explorer has a pretty big market share, so very few people would actually get to see your fuzzy drop shadow. Luckily, IE 5.5 and above has some proprietary CSS that forces PNG transparency:

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader (src=’images/mask.png’, sizingMethod=’crop’);

You could add this code to the existing CSS file and hide it from good browsers using an IE-specific hack. However, it would invalidate your CSS file. Also, you should try to avoid using hacks unless absolutely necessary. Instead, it makes more sense to put your rule in a separate CSS file and then hide it from everything other than IE. To do this, create a new CSS file called ie55.css and add the following code:

.img-wrapper div {

   filter:progid:DXImageTransform.Microsoft.AlphaImageLoader

   (src=’img/shadow2.png’, sizingMethod=’crop’);

   background: none;

}

The first rule uses IE’s proprietary AlphaImageLoader filter to display the PNG with alpha transparency in IE 5.5 and above. The original background image will still be displayed, so the second rule simply hides the original background image. Internet Explorer has another piece of proprietary code called a conditional comment that will let you serve up a particular stylesheet to specific versions of IE. In this case, you only want IE 5.5 and higher to see the new stylesheet, so you can place the following code in the head of the page:

<!–[if gte ie 5.5000]>

<link rel=”stylesheet” type=”text/css” href=”ie55.css”/>

<![endif]–>

And that is it. All modern browsers as well as IE 5.5 and above will display a nice, faded-corner drop shadow. Everything else will be presented with a hard-corner drop shadow. The concept of creating a basic page that works in all browsers, and then adding advanced styling or functionality for more modern browsers, is known as progressive enhancement. Conversely, ensuring that a page’s style or functionality doesn’t cause adverse effects in older browsers is known as graceful degradation. These are two very important concepts in standards based design.

Onion skinned drop shadows

The last drop shadow method we are going to demonstrate uses a very similar technique to the rounded-corner box methods covered earlier. However, instead of using a mask to cover the ends of the shadow, you create two end shadow GIFs and lay them over the top of the hard ends of the main shadow graphic. To achieve this, you will need to add two extra nonsemantic divs to your markup to act as hooks for these images.cThe basic HTML will look like this:

<div class=”img-wrapper”>

<div class=”img-outer”>

<div class=”img-inner”>

<img src=”images/dunstan.jpg” width=”300″ height=”300″ alt=”Dunstan” />

</div>

</div>

</div>

As before, you apply the main shadow image as a background of the main div:

.img-wrapper {

background:url(images/shadow.gif) no-repeat right bottom; float: left;

}

And as before, you float the div so that it shrink-wraps.Now you can apply the bottom-left corner to the bottom left of the outer div and the top-right corner to the top right of the inner div. The addition of some bottom and left padding to the inner div creates the drop effect. To make sure that the main image wrapper shrink-wraps in IE 5.2 on the Mac, you also need to float both these divs:

 .img-outer {
                           background:url(images/bottom-left2.gif) no-repeat left bottom;
                           float: left; /* :KLUDGE: Fixes problem in IE5.2/Mac */
}
                         .img-inner {
                           background:url(images/top-right2.gif) no-repeat top right;
                           padding: 0 5px 5px 0;
                           float: left; /* :KLUDGE: Fixes problem in IE5.2/Mac */
}

And lastly, as before, you can add a border and some padding to the image to create a nice photo-style frame:

.img-wrapper img {
                           background-color: #fff;
                           border: 1px solid #a9a9a9;
                           padding: 4px;
                           display: block;
}

The final CSS looks like this:

                         .img-wrapper {
                           background:url(images/shadow.gif) no-repeat right bottom;
                           float: left;
}
   .img-outer {
            background:url(images/bottom-left2.gif) no-repeat left bottom;
            float: left; /* :KLUDGE: Fixes problem in IE5.2/Mac */
}
          .img-inner {
            background:url(images/top-right2.gif) no-repeat top right;
            padding: 0 5px 5px 0;
            float: left; /* :KLUDGE: Fixes problem in IE5.2/Mac */
}
          .img-wrapper img {
            background-color: #fff;
            border: 1px solid #a9a9a9;
            padding: 4px;
            display: block;
}

This method is very simple to understand and creates drop shadows that work on a wide range of browsers. The downside is the addition of two extra, nonsemantic divs. These are needed because CSS does not currently allow you to apply multiple background images to an element. CSS 3 will provide us with this ability in the future, so the use of multiple elements is just a transitional approach, and it should be quite easy to strip this extra markup out of your documents in the future. If you are concerned with the purity of your markup, you could always add these extra elements using JavaScript or generated content.

Image replacement

HTML text is great. Search engines can read it, you can copy and paste it, and it enlarges if you increase the text size in your browser. It is therefore a good idea to use HTML text instead of text as images wherever possible. Unfortunately, web designers have only a limited selection of fonts to play with. Also, while you can control your typography to a certain extent using CSS, some things just are not possible with live text. Because of this, there are occasions, usually for branding reasons, when you will want to use images of text instead. Rather than embed these images directly in the page, CSS authors came up with the idea of image replacement. Essentially you add your text to the document as normal, and then, using CSS, you hide the text and display a background image in its place. That way, search engines still have the HTML text to find, and the text will be available if you disable CSS.

This seemed like a great idea for a while, until various flaws emerged. Some of the more popular methods are inaccessible to screen readers, and most do not work with images turned off but CSS turned on. As a result, many CSS authors have stopped using image replacement methods and have reverted to using plain text. While we advocate avoiding image replacement where possible, we still believe there can be situations where it is appropriate, such as when you need to use a particular font because of corporate branding guidelines. To do this, you should have a good grasp of the various techniques available and understand their limitations.

Fahrner Image Replacement (FIR)

Created by Todd Fahrner, FIR is the original, and probably the most popular, image replacement technique. I am going to explain this method because of its historical significance and because it is one of the easiest methods to understand. However, this method has some serious accessibility implications, which I will come to in a moment, and should thus be avoided.

The basic concept is very simple. You wrap the text you want to replace in a span tag:

<h2>

       <span>Hello World</span>

</h2>

You then apply your replacement image as a background image to the heading element:

 h2 {
            background:url(hello_world.gif) no-repeat;
            width: 150px;
            height: 35px;
}

and hide the contents of the span by settings its display value to none:

span {

    display: none;

}

This method works like a charm, but it is this last rule that causes problems. Many of the most popular screen readers ignore elements that have their display value set to none or hidden. Therefore, they will completely ignore this text, causing a huge accessibility problem. So a technique intended to improve the accessibility of a site actually has the opposite effect. For this reason it is best not to use this technique.

Phark

Mike Rundle of www.phark.net invented a screenreader-friendly image replacement technique that has the added benefit of dropping the extra, nonsemantic div:

<h2>

    Hello World

</h2>

Instead of using the display property to hide the text, the Phark method applies a very large, negative text indentation to the headline:

 h2 {
            text-indent: -5000px;
            background:url(hello_world.gif) no-repeat;
            width: 150px;
            height:35px;
}

This method works well and solves the screenreader issue. However, as with the FIR method, this method does not work when images are turned off but CSS is turned on. This is an edge case and probably only applicable to people on very slow connections or those using their cell phones as a modem. There is an argument that site visitors do have the ability to turn images on and they just choose not to. However, it is worth bearing in mind that certain people may not see the replaced text so it is best to avoid using this method for crucial information or navigation.

Gilder/Levin method

This method, created jointly by Tom Gilder and Levin Alexander, is probably the most robust method available. It works well with screenreaders and allows the text to show up when images are off but CSS is on. It does this by layering an image over the text rather than hiding the text. That way, when images are turned off, you simply see the underlying text. To use this technique, you need to add an additional, empty span inside the element you wish to replace:

<h2>

    <span></span>Hello World

</h2>

You then set the dimensions of the element to equal the dimensions of your image, and set the position of the element to relative:

  h2 {
            width: 150px;
            height: 35px;
            position: relative;
}

This sets up a new positioning context for the enclosed span element, allowing you to position it absolutely over the text. When you set the dimensions to be 100 percent of the parent element, and apply your replacement image as a background on the span, the replaced text will be completely covered by the image:

          h2 span {
            background: url(hello_world.gif) no-repeat;
            position: absolute;
            width: 100%;
            height: 100%;
}

When using this technique, you have to use an image with a solid background; otherwise the text will show through. The downside of this technique is the addition of a nonsemantic span.

Inman Flash Replacement (IFR) and Scalable Inman Flash Replacement (sIFR)

One of the main problems image replacement tries to solve is the lack of fonts available on most computers. Rather than swap the text out with images of text, Mike Davidson and Shaun Inman took an altogether more inventive approach. Flash allows you to embed fonts into a SWF file, so instead of swapping the text out for an image, they decided to swap the text out and replace it with a Flash file. The swapping is done using JavaScript by looping through the document and grabbing any text within a particular element or with a particular class name. The JavaScript then swaps the text for a small Flash file. The really clever part comes next. Rather than creating a separate Flash file for each chunk of text, this technique places the swapped text back into a single, duplicated Flash file. Thus, all you need to do to trigger your image replacement is add a class, and the combination of Flash and JavaScript will do the rest. Another benefit is that the text in Flash files can be made selectable, meaning that it can be copied and pasted with ease.

Shaun Inman released his Flash image replacement method and dubbed it “Inman Flash Replacement,” or IFR for short. IFR is a very lightweight method. Details about this method, including the source code, can be found at www.shauninman.com/plete/2004/ 04/ifr-revisited-and-revised. Mike Davidson built extensively on this method, creating the Scalable Inman Flash Replacement (sIFR) method. This method extends IFR by allowing things such as multiline text replacement and text resizing.

To use sIFR on your site, you first need to download the latest version from www.mikeindustries.com/sifr. Installing sIFR on your site is fairly simple, although it’s worth reading through the documentation first. The first thing you need to do is open the Flash file, embed the font you want to use, and export the movie. For sIFR to work properly, you next need to apply the enclosed print and screen styles, or create your own. Now add the sifr.js JavaScript file to every page you want sIFR to work on. This file is highly configurable and allows you to specify which elements to replace, the text color, padding, case, and a variety of other stylistic elements. Once you are done, upload all the files to your server and watch your tired old fonts be replaced with dynamic Flash content. The main problem with these techniques involves load times. The pages have to load fully before JavaScript can replace the text. Consequently, there is usually a brief flicker before all the text has been replaced with the Flash equivalent (see Figure 2-18).

Figure 2-18. Notice how the headlines at fortymedia.com only display once the page has loaded. This is a sure sign that sIFR is being used on this site.

Although it is not a huge problem, it is noticeable and can give the impression that the page is loading slowly. Also, some pages can feel a little sluggish if there is a lot of Flash replacement going on. It’s a good idea to keep any replacement to a minimum and limit this technique to main headlines only.

STYLING LINKS

The humble anchor link is the foundation of the World Wide Web. It is the mechanism that allows web pages to interconnect and people to explore and navigate. The default styling for anchor links is fairly uninspiring, but with a little sprinkling of CSS you can do some amazing things.

Simple link styling

The easiest way to style a link is to use the anchor type selector. For instance, this rule will make all anchors red:

a {color: red;}

However, anchors can act as internal references as well as external links, so using a type selector is not always ideal. Take this situation, for example. The first anchor contains a fragment identifier, and when the user clicks that anchor, the page will jump to the second named anchor:

<p><a href=”#mainContent”>Skip to main content</a></p>

 …

<h1><a name=”mainContent”>Welcome</a></h1>

While you probably only want the link to be styled red, the contents of the headline will be styled red also. To avoid this, CSS has two special selectors called link pseudo-class selectors. The :link pseudo-class selector is used to target links that have not been visited, and the :visited pseudo-class selector is used to target visited links. So in this example all unvisited links will be blue and all visited links will be green:

a:link {color: blue;}   /* Makes unvisited links blue */

a:visited {color: green;}   /* Makes visited links green */

The other two selectors you can use for styling links are the :hover and :active dynamic pseudo-class selectors. The :hover dynamic pseudo-class selector is used to target elements when they are hovered over, and the :active dynamic pseudo-class selector targets elements when they are activated. In the case of links, activation occurs when the link is clicked. So in this example, links will turn red when hovered over or clicked:

a:hover, a:active { color: red;}

One of the first things most people learn to use these selectors for is turning off the underline for links, and then turning them back on when they are hovered over or clicked. This can be done by setting the text-decoration property to none for unvisited and visited links, and to underline for hovered or active links:

a:link, a:visited {text-decoration: none;}

a:hover, a:active {text-decoration: underline;}

In the previous example the order of the selectors is very important. If the order is reversed, the hover and active styles won’t work:

a:hover, a:active {text-decoration: underline;}

a:link, a:visited {text-decoration: none;}

The reason for this is the cascade. You learned that when two rules have the same specificity, the last rule to be defined wins out. In this situation, both rules have the same specificity so the :link and :visited styles will override the :hover and :active styles. To make sure this doesn’t happen, it’s a good idea to apply your link styles in the following order:

a:link, a:visited, a:hover, a:active

An easy way to remember this order is the phonetic LoVe:HAte, where L stands for link, V stands for visited, H stands for hover, and A stands for active.

Fun with underlines

From a usability and accessibility standpoint, it is important that your links are distinguishable by some means other than color. The reason for this is that many people with visual impairments find it difficult to distinguish between poorly contrasting colors, especially at small text sizes. For instance, people with color blindness cannot distinguish between certain color combinations with similar levels of brightness or saturation. Because of this, links are underlined by default.

Designers tend to dislike link underlines as they add too much weight and visual clutter to a page. If you decide to remove link underlines, you could choose to make links bold instead. That way your page will look less cluttered, but the links will still stand out:

  a:link, a:visited {
            text-decoration: none;
            font-weight: bold;
}

You can then reapply the underlines when the links are hovered over or activated, reinforcing their interactive status:

a:hover, a:active {

       text-decoration: underline;

}

However, it is possible to create a low impact underline using borders instead. In the following example, the default underline is removed and replaced with a less obtrusive dotted line. When the link is hovered over or clicked, this line turns solid to provide the user with visual feedback that something has happened:

  a:link, a:visited {
            text-decoration: none;
            border-bottom: 1px dotted #000;
}
  a:hover, a:active {
            border-bottom-style: solid;

}

Fancy link underlines

You can create some very interesting effects by using images to create your link underlines. For instance, we have created a very simple underline graphic comprised of diagonal lines (Figure 2-21).

Figure 2-21. Simple underline graphic

You can then apply this image to your links using the following code:

  a:link, a:visited {
            color:#666;
            text-decoration: none;
            background: url(images/underline1.gif) repeat-x left bottom;
}

You can see the resulting styled link in Figure 2-22.

Figure 2-22. Custom link underline

You do not have to stop with link and visited styles. In this example,we have created an animated GIF for the hover and active states, which we apply using the following CSS:

a:hover, a:active {

   background-image: url(images/underline1-hover.gif);

}

When you hover over or click the link, the diagonal lines appear to scroll from left to right, creating an interesting pulsing or poling effect. Not all browsers support background image animations, but those that do not will usually display the first frame of the animation, ensuring that the effect degrades nicely in older browsers.

Remember to use animation carefully as it can cause accessibility problems for some users. If in doubt, always remember to check the Web Content Accessibility Guidelines (WCAG 1.0) at www.w3.org/TR/WAI-WEBCONTENT/.

Highlighting different types of link

On many sites it is difficult to tell if a link points to another page on that site or to a different site altogether. We have all clicked a link expecting it to go to another page in the current site, only to be whisked away somewhere different and unexpected. To combat this problem, many sites will open external links in a new window. However, this is not a good idea as it is taking control away from the user and potentially littering their desktops  with unwanted windows. The best solution is to indicate external links somehow, and let the user decide whether they want to leave the site, open the link in a new window, or more probably these days, in a new tab. You can do this by adding a small icon next to any external links. Sites like wikipedia.com already do this and an icon convention for offsite links has started to appear: a box with an arrow (Figure 2-23).

Figure 2-23. External link icon

The easiest way to do this is to add a class to any external links, and then apply the icon as a background image. In this example I have created space for the icon by giving the link a small amount of right padding, and then applied the icon as a background image at the top right of the link (see Figure 2-24).

.external {

background: url(images/externalLink.gif) no-repeat right top;

padding-right: 10px;

}

Figure 2-24. External link styling

Although this method works, it is not a particularly smart or elegant way of doing things, as you have to manually add your class to each external link. What if there was a way to get CSS to determine whether something was an external link for you? Well, in fact there is: using attribute selectors. As you learned, attribute selectors allow you to target an element based on the existence or value of an attribute. CSS 3 extends the ability with substring matching attribute selectors. As the name suggests, these selectors allow you to target an element by matching part of the attribute’s value to your chosen text. CSS 3 is not an official specification yet, so using these advanced selectors will probably invalidate your code. However, a number of standards-compliant browsers such as Firefox and Safari already support these CSS 3 selectors, so the chance of them being dropped from the final spec is pretty slim.

This technique works by first targeting any links that start with the text http: using the [att^=val] attribute selector:

a[href^=”http:”] {

background: url(images/externalLink.gif) no-repeat right top;

padding-right: 10px;

}

This should highlight all external links. However, it will also pick up internal links using absolute rather than relative URLs. To avoid this, you need to reset any links to your own site by removing the external link icon. This is done by matching links that point to your domain name, removing the external link icon, and resetting the right padding (see Figure 2-25).

a[href^=”http://www.yoursite.com”], a[href^=”http://yoursite.com”] { background-image: none;

padding-right: 0;

}

Figure 2-25. A page showing external links styled differently from internal ones

Most standards  compliant browsers support this technique, but older browsers such as IE 6 and below will simply ignore it.If you like, you could extend this technique to highlight email links as well. In this example adding a small email icon to all mailto links:

a[href^=”mailto:”] {

background: url(images/email.png) no-repeat right top;

padding-right: 10px;

}

You could even highlight nonstandard protocols such as the AIM instant messaging protocol, with a little AIM buddy icon (see Figure 2-26):

   a[href^="aim:"] {
            background: url(images/im.png) no-repeat right top;
            padding-right: 10px;
           }
          <a href="aim:goim?screenname=andybudd">instant message</a>

Figure 2-26. Email and instant message link styles

Highlighting downloadable documents and feeds

Another common frustration is clicking on a link thinking it is going to take you to a page, only for it to start downloading a PDF or Microsoft Word document. Luckily, CSS can help us distinguish these types of links as well. This is done using the [att$=val] attribute selector, which targets attributes that end in a particular value, such as .pdf or .doc:

 a[href$=".pdf"] {
            background: url(images/pdfLink.gif) no-repeat right top;
            padding-right: 10px;
}
 a[href$=".doc"] {
            background: url(images/wordLink.gif) no-repeat right top;
            padding-right: 10px;

}

So in a similar way to the previous examples, you can highlight links to word documents or PDFs with their own separate icon, warning people that they are downloads rather than links to another page. Lastly, many people have RSS feeds on their website. The idea is for people to copy these links into their feed readers. However, inadvertently clicking one of these links may take you to a page of seemingly meaningless data. To avoid possible confusion, you could highlight RSS feeds using a similar method, with your own RSS icon:

a[href$=”.rss”], a[href$=”.rdf”] {

background: url(images/feedLink.gif) no-repeat right top;

padding-right: 10px;

}

All these techniques can help to improve the user experience on your site. By warning users about offsite links or downloadable documents, you let them know exactly what to expect when they click a link, and avoid unnecessary backtracking and frustration.

Unfortunately, IE 6 and below doesn’t support the attribute selector. Luckily, you can create a similar effect by adding a class to each element using JavaScript and the DOM. One of the best ways to do this is with Simon Willison’s excellent getElementBySelector function; you can find more details at http://tinyurl.com/dmao4.

Creating buttons and rollovers

Anchors are inline elements, which means they only activate when you click on the content of the link. However, there are instances when you want to create more of a button-like effect with a larger clickable area. You can do this by setting the display property of the anchor to block, and then changing the width, height, and other properties to create the style and hit area you want.

a{

display: block;
width: 6em; /* dimensions needed for IE5.x/Win */ padding: 0.2em;
line-height: 1.4;
background-color: #94B8E9;
border: 1px solid black;
color: #000;
text-decoration: none;
text-align: center;

}

The resulting link should now look like Figure 2-27.

Figure 2-27. Link styled like a button

With the link now displaying as a block-level element, clicking anywhere in the block will activate the link.If you look at the CSS, you’ll see that the width has been explicitly set in ems. By their nature, block-level elements expand to fill the available width, so if the width of their parent elements were greater than the required width of the link, you would need to apply the desired width to the link. This would likely be the case if you wanted to use such a styled link in the main content area of your page. However, if your styled links were going in a sidebar, for example, you would probably just set the width of the sidebar, and not worry about the width of the links.

Unfortunately, IE 5.x on Windows has a bug whereby, if no width or height is defined, only the link text becomes active, even though the display property has been set to block. In the previous example I control the height of the button using line-height, so an explicit width is necessary to make the whole area clickable in IE 5.x for Windows. You may wonder why we are using line-height to control the height of the button instead of height. Well, this is actually a handy little trick for centering the text in the button vertically. If you were to set a height, you would probably have to use padding to push the text down and fake vertical centering. However, text is always vertically centered in a line box, so by using line-height instead, the text will always sit in the middle of the box. There is one downside, though. If the text in your button wraps onto two lines, the button will be twice as tall as you want it to be. The only way to avoid this is to size your buttons and text in such a way that the text won’t wrap, or at least won’t wrap until your text size has been increased beyond a reasonable amount.

Simple rollovers

In the bad old days, people used large and overly complicated JavaScript functions to create rollover effects. Thankfully, using the :hover pseudo-class allows us to create rollover effects without the need of JavaScript. You can extend the previous example to include a very simple rollover effect simply by setting the background and text color of the link when hovered over (Figure 2-28):

a:hover {

background-color: #369;

color: #fff;

}

Figure 2-28. Hover style showing active area

Rollovers with images

Changing background colors works well for simple buttons, but for more complicated buttons it is best to use background images. For the next example we have created two button images, one for the up state and one for the hover state (see Figure 2-29). If you wanted, you could also add an active state, which would be triggered using the :active dynamic pseudo-class.

Figure 2-29. Images for the normal and hover button states

The code for this example is similar to the preceding example. The main difference is that background images are being used instead of background colors.

a:link, a:visited {

display: block;

width: 200px;

height: 40px;

line-height: 40px;

color: #000;

text-decoration: none;

background: #94B8E9 url(images/button.gif) no-repeat left top;

text-indent: 50px;

}

a:hover {

background: #369 url(images/button_over.gif) no-repeat left top;

color: #fff;

}

This example uses fixed-width and -height buttons, which is why we have set explicit pixel dimensions in the CSS. However, there is nothing to stop you from creating oversized but-ton graphics, or using a combination of background colors and images to create a fluid or an elastic button.

Pixy-style rollovers

The main drawback with the multiple image method is a slight delay as browsers load the hover image for the first time. This can cause an undesirable flickering effect and make your buttons feel a little unresponsive. It is possible to preload the hover images by applying them as a background to the parent element. However, there is another way. Instead of swapping in multiple background images, use a single image and switch its background position instead. Using a single image has the added benefit of reducing the number of server requests as well as allowing you to keep all your button states in one place. This method is known as the Pixy method after the nickname of its creatorBegin by creating your combined button image (see Figure 2-30). In this case I am only using an up state and an over state, but you could also have an active and a visited state if you desired.

Figure 2-30. Both button states as a single image

The code is almost identical to the previous example. However, this time you align the rollover image to the left for the normal link state, and then shift it to the right for the hover state.

a:link, a:visited {

display: block;

width: 200px;

height: 40px;

line-height: 40px;

color: #000;

text-decoration: none;

background: #94B8E9 url(images/pixy-rollover.gif) no-repeat left top;

text-indent: 50px;

}

a:hover {

background-color: #369;

background-position: right top;

color: #fff;

}

Unfortunately, IE on Windows still makes a round-trip to the server to request a new image, even though all you are doing is changing the alignment of the image. This causes a slight flicker, which can be a little annoying. To avoid the flicker you need to apply the rollover state to the link’s parent element, for example, its containing paragraph.

p {

background: #94B8E9 url(images/pixy-rollover.gif)

no-repeat right top;

}

The image will still disappear for an instant while it is being reloaded. However, during this time, the same image will be revealed underneath, hiding the flicker.

Visited-link styles

Designers and developers often forget about the visited-link style and end up styling visited links the same as unvisited ones. However, a separate visited-link style can help orientate users, showing them which pages or sites they have already visited and avoiding unnecessary backtracking. Visited-link styles can add clutter to the main content area of your site, so use them wisely. However, they come into their own when used in sidebars or subnavigation. You can create a very simple visited-link style by adding a check box to every visited link:

a:visited {

padding-right: 20px;

background: url(check.gif) right middle;

}

Taking this a step further, say you had a list of links in your sidebar to external sites:

<ul>
<li><a href=”http://www.andybudd.com/”>Andy Budd’s Blogography</a></li>

<li><a href=”http://allthatmalarkey.co.uk/”>Stuff and Nonsense</a></li>

<li><a href=”http://www.hicksdesign.co.uk/”>Hicks Design</a></li>

<li><a href=”http://www.clagnut.com/”>Clagnut</a></li>

<li><a href=”http://www.htmldog.com/”>HTML Dog</a></li>

<li><a href=”http://adactio.com/journal/”>Adactio</a></li>

<li><a href=”http://www.allinthehead.com/”>All In The Head</a></li>

<li><a href=”http://www.markboulton.co.uk/”>Mark Boulton</a></li>

<li><a href=”http://www.ian-lloyd.com/”>Ian Lloyd</a></li>

</ul>

Using the Pixy rollover method you learned about earlier, you could create a single image for the unvisited and visited states (see Figure 2-31). If you wanted, you could add hover and active states as well.

Figure 2-31. Unvisited- and visited-link graphics in a single image

You would then apply your background image much in the same way as before.  The most important thing to note is the background image styling on the anchor and the visited state.

ul {

list-style:none;

}

li {

margin: 5px 0;

}

li a {

display: block;

width: 300px;

height: 30px;

line-height: 30px;

color: #000;

text-decoration: none;

background: #94B8E9 url(images/visited.gif) no-repeat left top;

text-indent: 10px;

}

li a:visited {

            background-position: right top;

}

You can see the resulting links list in Figure 2-32. Each site you have visited will show up as a check next to the site name, providing valuable feedback that you’ve already been there. 

Figure 2-32. External ink list showing visited sites with a check

Pure CSS tooltips

Tooltips are the little yellow text boxes that pop up in some browsers when you hover over elements with title tags. Several developers have created their own custom, stylized tooltips using a combination of JavaScript and CSS. However, it is possible to create pure CSS tooltips by using CSS positioning techniques. This technique requires a modern, standards-compliant browser like Firefox to work properly. As such, it is not a technique you would add to your day-to-day arsenal. However, it does demonstrate the power of advanced CSS and gives you a hint of what will be possible when CSS is better supported. As with all of the examples, you need to start with well-structured and meaningful (X)HTML:

<p>

<a href=”http://www.andybudd.com/” class=”tooltip”> Andy Budd<span> (This website rocks) </span></a>

is a web developer based in Brighton England.

</p>

We have given the link a class of tooltip to differentiate it from other links. Inside the link we have added the text we wish to display as the link text, followed by the tooltip text enclosed in a span. We have wrapped my tooltip text in brackets so that the sentence still makes sense with styles turned off. The first thing you need to do is set the position property of the anchor to relative. This allows you to position the contents of the span absolutely, relative to the position of its parent anchor. You do not want the tooltip text to display initially, so you should set its display property to none:

a.tooltip {

position: relative;

}

a.tooltip span {

display: none;

}

When the anchor is hovered over, you want the contents of the span to appear. This is done by setting the display property of the span to block, but only when the link is hovered over. If you were to test the code now, hovering over the link would simply make the span text appear next to the link. To position the contents of the span below and to the right of the anchor, you need to set the position property of the span to absolute and position it 1em from the top of the anchor and 2ems from the left.

Remember, an absolutely positioned element is positioned in relation to its nearest positioned ancestor, or failing that, the root element. In this example, we have positioned the anchor, so the span is positioned in relation to that.

a.tooltip:hover span {

display: block;

position: absolute;

top: 1em;

left: 2em;

}

And that’s the bulk of the technique. All that is left is to add some styling to make the span look more like a tooltip. You can do this by giving the span some padding, a border, and a background color:

a.tooltip:hover span {

            display:block;

            position:absolute;

            top:1em;

left:2em;

            padding: 0.2em 0.6em;

            border:1px solid #996633;

            background-color:#FFFF66;

            color:#000;

}

Previewing the technique in Firefox, it should look something like Figure 2-33.

Figure 2-33. Pure CSS tooltip

Unfortunately, this technique does not work properly in IE 5.x on Windows as it stands. It would seem that IE has problems styling elements inside anchor links using a dynamic pseudo-class. However, there is a fix:

a.tooltip:hover {

font-size: 100%; /* Fixes bug in IE5.x/Win */

}

Setting the font size as 100% on the hovered anchor somehow triggers Internet Explorer on Windows into correctly styling the contained span. 

Summary

In this chapter you have learned how background images can be applied to elements to produce a variety of interesting techniques, such as flexible rounded-corner boxes and pure CSS drop shadows. You have seen how to force PNG support in Internet Explorer along with several methods of image replacement.In this chapter you have learned how to style links in a variety of ways. You now know how to style links depending on the site or file they link to, and you can make links behave like buttons and create rollover effects using colors or images. You can even create advanced effects such as pure CSS tooltips.

This Is A Custom Widget

This Sliding Bar can be switched on or off in theme options, and can take any widget you throw at it or even fill it with your custom HTML Code. Its perfect for grabbing the attention of your viewers. Choose between 1, 2, 3 or 4 columns, set the background color, widget divider color, activate transparency, a top border or fully disable it on desktop and mobile.

This Is A Custom Widget

This Sliding Bar can be switched on or off in theme options, and can take any widget you throw at it or even fill it with your custom HTML Code. Its perfect for grabbing the attention of your viewers. Choose between 1, 2, 3 or 4 columns, set the background color, widget divider color, activate transparency, a top border or fully disable it on desktop and mobile.