CSS CHAPTER 3 2018-12-19T12:22:50+00:00

CSS CHAPTER 3

Topics:- (Basic list styling, Creating a basic vertical nav bar, Creating a simple horizontal nav bar, Creating a graphical nav bar, CSS image maps, Remote rollovers, Styling data tables, Simple form layout, Complicated form layout)

It is in our nature to try to organize the world around us. Scientists create lists of animals, plants, and chemical elements. Magazines create lists of the top 10 movies, the latest fashion trends, or the worstdressed celebrities. People write shopping lists, to-do lists, and lists to Santa. We just love making lists.Lists provide us with a way of grouping related elements and, by doing so, we give them meaning and structure. Most web pages contain some form of list, be it a list of the latest news stories, a list of links to your favorite web pages, or a list of links to other parts of your site. Identifying these items as lists and marking them up as such can help add structure to your HTML documents, providing useful hooks with which to apply your styles.

In this chapter you will learn about

Styling lists with CSS

Using background images as bullets

Creating vertical and horizontal nav bars

Using sliding doors tabbed navigation

Creating CSS image maps

Creating remote rollovers

Using definition lists

Creating attractive and accessible data tables

Creating simple and complicated form layouts

Styling various form elements

Providing accessible form feedback

Basic list styling

Basic list styling is very simple. Say you start with this simple to-do list:

<ul>

<li>Read emails</li>

<li>Write book</li>

<li>Go shopping</li>

<li>Cook dinner</li>

<li>Watch Scrubs</li>

</ul>

To add a custom bullet you could use the list-style-image property. However, this doesn’t give you much control over the position of your bullet image. Instead, it is more common to turn list bullets off and add your custom bullet as a background image on the list element. You can then use the background image positioning properties to accurately control the alignment of your custom bullet. Internet Explorer and Opera control list indentation using left margin, whereas Safari and Firefox choose to use left padding. As such, the first thing you will want to do is remove this indentation by zeroing down the margin and padding on the list. To remove the default bullet, you simply set the list style type to none:

ul {

margin: 0;

padding: 0;

list-style-type: none;

}

Adding a custom bullet is very straightforward. Adding padding to the left side of the list item creates the necessary space for your bullet. The bullet is then applied as a back-ground image on the list item. If the list item is going to span multiple lines, you will prob-ably want to position the bullet at or near the top of the list item. However, if you know the contents of the list items won’t span more than one line, you can vertically center the bullet by setting the vertical position to either middle or 50%:

li {

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

padding-left: 30px;

}

The resulting styled list can be seen in Figure 3-1.

Figure 3-1. Simple styled list with custom bullets

Creating a vertical nav bar

Combining the previous example with the link styling techniques you learned, you can create graphically rich vertical navigation bars complete with CSS rollovers, like the one in Figure 3-2.

Figure 3-2. Styled vertical nav bar

As always, you need to start with a good HTML framework:

<ul>

<li><a href=”home.htm”>Home</a></li>

<li><a href=”about.htm”>About</a></li>

<li><a href=”services.htm”>Our Services</a></li>

<li><a href=”work.htm”>Our Work</a></li>

<li><a href=”news.htm”>News</a></li>

<li><a href=”contact.htm”>Contact</a></li>

</ul>

The first thing you want to do is remove the default bullets and zero down the margin and padding:

ul {

margin: 0;

padding: 0;

list-style-type: none;

}

Rather than style the list items, you are going to be styling the enclosed anchors. To create a button-like hit area, you need to set the display property of the anchors to block, and then specify the anchor’s dimensions. In this example my navigation buttons are 200 pixels wide and 40 pixels high. The line height has also been set to 40 pixels in order to center the link text vertically. The last couple of rules are just stylistic, setting the color of the link text and turning off the underlines.

ul a {

display: block;

width: 200px;

height: 40px;

line-height: 40px;

color: #000;

text-decoration: none;

}

Using the Pixy rollover technique you learned about, the rollover graphic (Figure 3-3) is applied as a background image to the anchor link.

Figure 3-3. A single image composed of both the up and hover state images

The background image is aligned left in order to reveal the up state. The anchor text is given a 50-pixel indent so that it is not sitting directly over the arrow in the background image.

ul a {

display: block;
width: 200px;
height: 40px;
line-height: 40px;
color: #000;
text-decoration: none;
background: #94B8E9 url(images/pixy-rollover.gif) no-repeat ➥ left middle;
text-indent: 50px;

}

If you look at the rollover image in Figure 3-3, you will notice that it has a solid border all the way around the image. When these images are stacked vertically, the top and bottom borders will double up. However, you only want a single, 1-pixel black line between each nav bar item. To get around this problem, clip the top line off by aligning the background images to the bottom of the anchor and then reducing the height of the links by 1 pixel:

ul a {

display: block;
width: 200px;
height: 39px;
line-height: 39px;
color: #000;
text-decoration: none;
background: #94B8E9 url(images/pixy-rollover.gif) no-repeat ➥ left bottom;
text-indent: 50px;

}

The links now stack up nicely, with a single black line appearing between each one. However, the top black line on the first link is no longer showing. To put this back you need to reset the height of the first anchor to 40 pixels—the full height of the image. You can do this by applying a class of first to the first list item:

li.first a {

height: 40px;

line-height: 40px;

}

The list now looks like a stylish vertical navigation bar. To complete the effect, the last thing you need to do is apply the hover and selected states. To do this, you simply shift the background image on the anchor links to the right, uncovering the hover state graphic. This style is applied to the anchor links when the user hovers over them. It is also applied to any anchors that have a class of selected applied to their parent list item.

a:hover, .selected a {

background-position: right bottom;

color: #fff;

}

This technique should now work in all the major browsers except IE for Windows. Unfortunately, IE inexplicably adds extra space above and below the list items. To fix this bug, you need to set the display property on the list items to inline:

li {

display: inline: /* :KLUDGE: Removes large gaps in IE/Win */

}

And there you have it: a styled vertical nav bar, complete with rollovers.

Highlighting the current page in a nav bar

In the previous vertical nav bar example, we used a class to indicate the current page. For small sites with the navigation embedded in the page, you can simply add the class on a page-by-page basis. For large sites, there is a good chance that the navigation is being built dynamically, in which case the class can be added on the back end. However, for medium-sized sites, where the main navigation doesn’t change, it is common to include the navigation as an external file. In these situations, wouldn’t it be good if there were a way to highlight the page you are on, without having to dynamically add a class to the menu? Well, with CSS there is.

This concept works by adding an ID or a class name to the body element of each page, denoting which page or section the user is in. You then add a corresponding ID or class name to each item in your navigation list. The unique combination of body ID and list ID/class can be used to highlight your current section or page in the site nav.Take this HTML fragment as an example. The current page is the home page, as indicated by an ID of home on the body. Each list item in the main navigation is given a class name based on the name of the page the list item relates to:

<body id=”home”>

<ul id=”mainNav”>

<li class=”home”><a href=”#”>Home</a></li>

<li class=”about”><a href=”#”>About</a></li>

<li class=”news”><a href=”#”>News</a></li>

<li class=”products”><a href=”#”>Products</a></li>

<li class=”services”><a href=”#”>Services</a></li>

</ul>

</body>

To highlight the current page you simply target the following combination of IDs and class names:

#home #mainNav .home a,

#about #mainNav .about a ,

#news #mainNav .news a,

#products #mainNav .products a,

#services #mainNav .services a {

background-position: right bottom;

color: #fff;

cursor: default;

}

When the user is on the home page, the nav item with a class of home will display the selected state, whereas on the news page, the nav item with the class of news will show the selected state. For added effect, I have changed to cursor style to show the default arrow cursor. That way, if you mouse over the selected link, your cursor will not change state and you won’t be tempted to click a link to a page you are already on.

Creating a horizontal nav bar

As well as using lists to create vertical nav bars, they can also be used to create horizontal ones. In this example, we are going to demonstrate how to create a horizontal navigation bar like the one in Figure 3-4.

Figure 3-4. Horizontal nav bar

As in the previous example, you start with a simple, unordered list:

<ul>

<li><a href=”#”>Home</a></li>

<li><a href=”#”>About</a></li>

<li><a href=”#”>News</a></li> 5 <li><a href=”#”>Products</a></li>

<li><a href=”#”>Services</a></li>

<li><a href=”#”>Clients</a></li>

<li><a href=”#”>Case Studies</a></li>

</ul>

You then zero down the padding and margins, as well as remove the default bullets. For this example we want our horizontal nav bar to be 720 pixels wide, and to have a repeating orange gradient as a background:

ul {

margin: 0;

padding: 0;

list-style: none;

width: 720px;

background: #FAA819 url(images/mainNavBg.gif) repeat-x;

}

The list is currently displayed vertically. To make it display horizontally, you can use one of two methods. You can either set the list items to display inline, or you can float them all left. Displaying the list items as inline is probably the simpler method. However, from experience we have found that it can produce buggy results; therefore,we tend to favor the floating method:

ul li {

float: left;

}

Remember that when an element is floated, it no longer takes up any space in the flow of the document. As such, the parent list effectively has no content and collapses down, hid-ing the list background. As you learned, there are two ways to make parent elements contain floated children. One method is to add a clearing element. Unfortunately this adds unnecessary markup to the page so should be avoided if possible.The other method is to float the parent element as well, and clear it further down the line, say, using the site footer. This is the method I normally use:

ul {

margin: 0;

padding: 0;

list-style: none;

width: 720px;

float: left;

background: #FAA819 url(images/mainNavBg.gif) repeat-x;

}

As in the vertical navigation bar example, the links in the horizontal nav bar are made to behave like buttons by setting their display property to block. If you wanted each button to be a fixed size, you could explicitly set its height and width. In this example, we want the width of each button to be based on the size of the anchor text. To do this, rather than setting a width, we have applied 2ems of padding to the left and right sides of each anchor link. As in the previous example, the link text is being vertically centered using line height. Lastly, the link underlines are turned off and the link color is changed to white:

ul a {

display: block;

padding: 0 2em;

line-height: 2.1em;

text-decoration: none;

color: #fff;

}

We want to create dividers between each link in the nav bar. This can be done by applying a divider graphic as a background image to the left of each anchor link:

ul a {

display: block;

padding: 0 2em;

line-height: 2.1em;

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

text-decoration: none;

color: #fff;

}

However, the first link in the nav bar will have an unwanted divider. Adding a class to the first list item and setting the background image to none can remove this:

ul .first a {

background: none;

}

Lastly, the rollover state in this example is simply a change in link color:

ul a:hover {

color: #333;

}

This nav bar works well on most modern browsers, but it doesn’t work as expected in IE 5.2 on the Mac. This is because IE 5.2 on the Mac doesn’t shrink-wrap the floated list items because the enclosed anchors have been set to display as block-level elements. To avoid this problem, we simply need to float the anchors as well:

ul a {

display: block;

float: left;

padding: 0 2em;

line-height: 2.1em;

background: url(images/divider.gif) repeat-y left top; 5

text-decoration: none;

color: #fff;

}

And there you have it: a well-styled horizontal nav bar with good, cross-browser support.

Simplified “sliding doors” tabbed navigation

You have learned about Douglas Bowman’s sliding doors technique, and how it could be used to create flexible, rounded-corner boxes. This technique can also be used to create flexible, expandable tabbed navigation. Using this method, tabs are created from one large image and one side image. As the text in the tabs expands, more of the large image is uncovered. The smaller image stays flush to the left, covering up the hard edge of the larger image and completing the effect (see Figure 3-5).

Figure 3-5. Example of the “sliding doors” technique

The images used to create the tabs in the following example can be seen in Figure 3-6. Both of these images are very large. This is to allow the font size to be increased by several hundred percent without the tabs appearing to break.

Figure 3-6. The two images that make up the tabs

The HTML for this example is exactly the same as in the previous, horizontal nav bar example:

<ul>

<li><a href=”#”>Home</a></li>

<li><a href=”#”>About</a></li>

<li><a href=”#”>News</a></li>

<li><a href=”#”>Products</a></li>

<li><a href=”#”>Services</a></li>

<li><a href=”#”>Clients</a></li>

<li><a href=”#”>Case Studies</a></li>

</ul>

As in the previous example, the margin and padding are zeroed, the list bullets are removed, and a width is set for the navigation bar. The tabbed navigation bar is also floated left in order to contain any enclosed floats:

ul {

margin: 0;

padding: 0;

list-style: none;

width: 720px;

float: left;

}

Like the previous example, the list elements are floated left to make them display hori-zontally rather than vertically. However, this time, the larger of the two images that make up the tab is applied as a background image to the list item. As this image forms the right side of the tab, it is positioned to the right:

ul li {

float: left;

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

}

As in the previous example, the anchors are set to display as block-level elements to make the whole area clickable. The width of each tab is again controlled by the width of the con-tents, and setting the line height similarly controls the height. To complete the tab effect, the left part of the tab is applied as a background on the anchor and aligned left. As the tab changes size, this image will always be aligned left, sitting over the top of the larger image and covering the hard left edge. Lastly, to make sure this technique works in IE 5.2 on the Mac, the anchors are floated as well.

li a {

display: block;

padding: 0 2em;

line-height: 2.5em; 5

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

text-decoration: none;

color: #fff;

float: left;

}

To create the rollover effect, you can simply change the link color:

ul a:hover {

color: #333;

}

The resulting tabbed navigation should look like Figure 3-7.

Figure 3-7. “Sliding doors” tabbed navigation at normal size

If you increase the text size in your browser, you should see that the tabs scale nicely, as demonstrated in Figure 3-8.

Figure 3-8. “Sliding doors” tabbed navigation after the text size has been scaled several times

This method provides an easy and hassle-free way to make attractive and accessible tabbed navigation bars.

CSS image maps

Image maps allow web developers to specify regions of an image to act as hotspots. Image maps were very popular several years ago, but they are much less common these days. This is partly due to the popularity of Flash, and partly due to the move toward simpler and less presentational markup. While image maps are still a perfectly valid part of HTML, they do mix presentation with content. However, it is possible to create simple image maps with a combination of lists, anchors, and some advanced CSS.

For this example we are using a photograph of the Clear left gang posing for pictures on the Brighton seafront (see Figure 3-9). When we hover over each person, we want a rectangular box to appear. Clicking on this box will take me to that person’s website.

Figure 3-9. Rich, Jeremy, and me posing for pictures on the Brighton seafront

The first thing you need to do is add your image to the page, inside a named div:

<div id=”pic”>

<img src=”images/group-photo.jpg” width=”640″ height=”425″ alt=”Richard, Andy and Jeremy” />

</div>

Then, add a list of links to each person’s website after the image. Each list item needs to be given a class to identify the person in that list item. You can also give each link a title attribute containing the name of the person. That way, when the link is hovered over, a tooltip showing who the person is will be displayed on most browsers.

<div id=”pic”>

<img src=”images/group-photo.jpg” width=”640″ height=”425″ alt=”Richard, Andy and Jeremy” />

<ul>

<li class=”rich”>

<a href=”http://www.clagnut.com/” title=”Richard Rutter”>

Richard Rutter

</a>

</li>

<li class=”andy”>

<a href=”http://www.andybudd.com/” title=”Andy Budd”>

Andy Budd

</a>

</li>

<li class=”jeremy”>

<a href=”http://www.adactio.com/” title=”Jeremy Keith”>

Jeremy Keith

</a>

</li>

 </ul>

</div>

Set the width and height of the div so that it matches the dimensions of the image. Then set the position property of the div to relative. This last step is the key to this tech-nique as it allows the enclosed links to be positioned absolutely, in relation to the edges of the div, and hence the image.

#pic {

width: 640px;

height: 425px;

position: relative; /* The key to this technique */

}

You won’t want the list bullets to display, so remove them by setting the list-style property to none. For completeness you may as well zero down the list’s margin and padding as well:

#pic ul {

margin: 0;

padding: 0;

list-style: none;

}

The next thing to do is style the links. By positioning the anchor links absolutely, they will all be moved to the top-left corner of the containing div. They can then be positioned individually over the correct people, forming the hotspots. However, first you will need to set their widths and heights to create your desired hit area. The link text is still displayed; therefore, it is necessary to hide it off the screen by using a large, negative text indent:

#pic a {

position: absolute;

width: 100px;

height: 120px;

text-indent: -1000em;

}

The individual links can now be positioned over the relevant people:

#pic .rich a {

top: 15px;

left: 95px;

}

#pic .andy a {

top: 115px;

left: 280px;

}

#pic .jeremy a {

top: 250px;

left: 425px;

}

Lastly, to create the rollover effect, a solid white border is applied to the links when they are hovered over:

#pic a:hover {

border: 1px solid #fff;

}

And that is the basic technique finished. If you try rolling over one of the pictures, you should see something similar to Figure 3-10.

Figure 3-10. The CSS image map being rolled over

flickr-style image maps

If you have used the photo sharing service flickr, you may have come across a similar tech-nique used to annotate images (see Figure 3-11). When you roll over an annotated image, a double-bordered box will appear over the area containing each note. When you hover over one of these boxes, it will highlight and display the note. With a spot of tweaking, we can achieve the same thing using the previous technique.

Figure 3-11. Image notes on flickr

To create the double-border box you need to add a couple of extra spans inside each anchor link. The note will also need the addition of an extra span. Once the extra spans have been added, the amended list should look like this:

<ul>

<li class=”rich”>

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

<span class=”outer”>

<span class=”inner”>

<span class=”note”>Richard Rutter</span>

</span>

</span>

</a>

</li>

</ul>

The CSS starts off identical to the previous example, setting the dimensions of the wrapper div to those of the image, and the position property to relative. The list padding and margin are again zeroed down and the bullets removed:

#pic {

width: 640px;

height: 425px;

position: relative;

}

#pic ul {

margin: 0;

padding: 0;

list-style: none;

}

As before, the enclosed anchor links are positioned absolutely and given dimensions to form the hotspots. However, this time you don’t want to hide the content of the link—you want to display it. As such, rather than hiding it off screen, give the anchor text a color and remove its default underline. The highlight effect on rollover is going to be created by adding a yellow border when the anchor is hovered over. To avoid the anchor from shift-ing position slightly when hovered over, it is necessary to give the link a 1-pixel transpar-ent border:

#pic a {

position: absolute;

width: 100px;

height: 120px;

color: #000;

text-decoration: none;

border: 1px solid transparent;

}

As before, you will need to position the anchors over each person:

#pic .rich a {

top: 15px;

left: 95px;

}

#pic .andy a {

top: 115px;

left: 280px;

}

#pic .jeremy a {

top: 250px;

left: 425px;

}

To create the double-border effect, the outer and inner spans need to have their display properties set to block. They can then be given dimensions and colored borders. In this case, the outer span is being given a black border while the inner span is given a white border:

      #pic a .outer {

        display: block;

        width: 98px;

        height: 118px;

        border: 1px solid #000;

}

      #pic a .inner {

        display: block;

        width: 96px;

        height: 116px;

        border: 1px solid #fff;

}

You can then apply the rollover effect to the anchor link. This is done by changing the anchor’s border color from transparent to yellow on hover:

      #pic a:hover {

        border-color: #d4d82d;

}

To display the note when the hotspot is rolled over, you first need to position the contents of the note span beneath the hotspot. To do this, set the position of the note span to absolute, and give it a negative bottom position. To pretty up the notes, set a width, some padding, and a background color, then center the text:

      #pic a .note {

        position: absolute;

        bottom: -3em;

        width: 9em;

        padding: 0.2em 0.5em;

        background-color:#ffc;

        text-align: center;

}

If you check the page in the browser, it should look something like Figure 3-12.

Figure 3-12. The flickr style rollovers are starting to take shape.

As you can see, the effect is starting to take shape. The notes look OK, but it would be nice if they were centered horizontally below the hotspot, rather than flush to the left. You can do this by positioning the left edge of the note span at the midpoint of the hotspot. Next, move the note span left, half the width of the note, using negative margins. The hotspot in this example is 100 pixels wide, so I have set the left position of the note to be 50 pixels. The notes are 10ems wide, including the padding, so setting a negative left margin of 5ems will horizontally center the note beneath the hotspot.

#pic a .note {

position: absolute;

bottom: -3em;

width: 9em;

padding: 0.2em 0.5em;

background-color:#ffc;

text-align: center;

left: 50px;

margin-left: -5em;

}

With the notes now centered, it’s time to work on their interactivity. The notes should be hidden by default and only displayed when the hotspot is hovered over. To do this you could set the display property to none and then change it to block when the anchor link is hovered over. However, this would prevent some screen readers from accessing the con-tents of the note. Instead we are going to hide the text off the left side of the screen, and reposition it on hover:

#pic a .note {

position: absolute;

bottom: -3em;

width: 9em;

padding: 0.2em 0.5em;

background-color:#ffc;

text-align: center;

left: -30000px;

margin-left: -5em;

}

      #pic a:hover .note {

        left: 50px;

}

We are almost there now. Just one more tweak is required to finish the technique. Rather than continuously display the hotspots’ double borders, it would be nice if the borders only displayed when the image was rolled over. That way, people can enjoy the image normally, unfettered by the hotspots. However when the image is hovered, the hotspots appear, letting the visitor know more information is available to be discovered. You can do this by removing the borders from the outer and inner spans and putting them back when the image is hovered over:

#pic:hover a .outer {

border: 1px solid #000;

}

#pic:hover a .inner {

border: 1px solid #fff;

}

Unfortunately, as you have already learned, IE 6 only supports hovering on anchor links. To get around this problem, it is also a good idea to display the borders when the hotspots are hovered over directly:

#pic:hover a .outer, #pic a:hover .outer {

border: 1px solid #000;

}

#pic:hover a .inner, #pic a:hover .inner {

border: 1px solid #fff;

}

And there you have it: a flickr-style, advanced CSS image map (see Figure 3-13).

Figure 3-13. The finished product

Remote rollovers

A remote rollover is a hover event that triggers a display change somewhere else on the page. This is accomplished by nesting one or more elements inside an anchor link. Then, using absolute positioning, you can position the nested elements individually. Despite being displayed in different places, they are both contained within the same parent anchor, so will both react to the same hover event. As such, when you hover over one ele-ment, it can affect the style of another element.

In this example, you are going to build on the basic CSS image map technique by placing a list of links below the image. When the links are hovered over, the image hotspots will be outlined. Conversely, when you hover over the hot areas on the picture, the text links will highlight.The HTML for this example is similar to that of the basic CSS image map example. However, you will need two additional spans: one wrapped around the link text, and one empty span to act as the hotspot. This will allow you to position the link text beneath the image and the hotspots over the respective people.

<div id=”pic”>
<img src=”images/group-photo.jpg” width=”640″ height=”425″
alt=”Richard, Andy and Jeremy” />
<ul>
<li class=”rich”>

<a href=”http://www.clagnut.com/” title=”Richard Rutter”>

<span class=”hotspot”></span>
<span class=”link”>&raquo; Richard Rutter</span>
</a>
</li>
<li class=”andy”>
<a href=”http://www.andybudd.com/” title=”Andy Budd”> <span class=”hotspot”></span>
<span class=”link”>&raquo; Andy Budd</span>
</a>
</li>
<li class=”jeremy”>
<a href=”http://www.adactio.com/” title=”Jeremy Keith”> <span class=”hotspot”></span>
<span class=”link”>&raquo; Jeremy Keith</span>
</a></li>
</ul>
</div>

The basic list styling is the same as the image map example:

      #pic {

        width: 640px;

        height: 425px;

        position: relative;

}

      #pic ul {

        margin: 0;

        padding: 0;

        list-style: none;

}

The first thing you need to do is set the position property of the hotspots to absolute, and then specify their dimensions. In this example each hotspot is the same size, but you could set different sizes on each one if you wanted. Just as in the previous technique, this will position all of the anchors at the top-left corner of the image. You can then position each hotspot over the relevant person in the image, using the top and left positioning properties.

#pic a .hotspot {

width: 100px;

height: 120px;

position: absolute;

}

#pic .rich a .hotspot {

top: 15px;

left: 95px;

}

#pic .andy a .hotspot {

top: 115px;

left: 280px;

}

#pic .jeremy a .hotspot {

top: 250px;

left: 425px;

}

Similarly, the spans containing the link text are also positioned absolutely and are given a width of 15ems. They too are positioned in relation to the enclosing list, in this case visu-ally below the list using negative bottom positions:

#pic a .link {

position: absolute;

width: 15em;

}

#pic .rich a .link {

bottom: -2em;

left: 0;

}

#pic .andy a .link {

bottom: -3.2em;

left: 0;

}

#pic .jeremy a .link {

bottom: -4.4em;

left: 0;

}

The hotspots should now be in the correct place, as should the text links.

To create the rollover effect on the hotspot when either the hotspot or the text is hovered, you need to apply a border to the hotspot span, when the parent anchor is hovered over:

#pic a:hover .hotspot {

border: 1px solid #fff;

}

Similarly, to change the color of the text when either the text or the hotspot span is hovered over, you need to change the style on the span when the parent anchor is hovered over:

#pic a:hover .link {

color: #0066FF;

}

If you test this example, it works perfectly in Safari and Firefox (see Figure 3-14). If you hover over a person’s name, the link text changes color, and a box appears over that per-son in the picture. The same happens if you hover over the person in the image.

Figure 3-14. Remote rollover demonstration. When the link text at the bottom of the image is rolled over, an outline appears over the associated person in the image.

Unfortunately, this example doesn’t quite work on IE on Windows. It would seem that IE/Win has problems targeting nested elements inside an anchor link, using the :hover dynamic pseudo-class. However, there is a simple, if somewhat odd, workaround. Adding the following rule on the anchors hover state seems to fix the confusion in IE and allow it to honor nested hover state rules:

#pic a:hover {

border: none;

}

While the styling of this example is quite simple, you are really only limited by your imagination. One of the best examples of this technique in the wild can be seen at http://dbowman.com/photos, the personal photo gallery of the technique’s creator, Douglas Bowman (see Figure 3-15).

Figure 3-15. When you roll over the slide graphics on Douglas Bowman’s photo gallery site, a translucent “next photo” graphic appears over the image.

A short note about definition lists

Throughout this chapter we have discussed how unordered lists (and by extension, ordered lists) can be used to create a variety of effects. However, there is a third, often overlooked list type that has been gaining more attention of late: the definition list. A definition list consists of two core components: a definition term <dt> and one or more definition descriptions <dd>.

<dl>

<dt>Apple</dt>

<dd>Red, yellow or green fruit</dd>

<dd>Computer company</dd>

<dt>Bananna</dt>

<dd>Curved yellow fruit</dd>

</dl>

As the name suggests, the primary purpose of a definition list is to mark up definitions. However, the (X)HTML specification is rather vague and suggests definition lists could be used for other applications like product properties or conversations. This stretches the concept of definitions somewhat, but still makes a certain amount of sense in the context of (X)HTML’s history as a simple text formatting language.Many web standards pioneers seized on the fact that definition lists could be used to structurally group a series of related elements and started to use them to create every-thing from product listing and image galleries, to form and even page layouts. While these techniques are undoubtedly clever, we believe they stretch the implied meaning of definition lists beyond their natural breaking point.

One of the arguments for using definition lists in this fashion is that no other (X)HTML ele-ment allows for this type of association. However, this isn’t strictly true as the purpose of the div element is to group a document up into logical sections. More worryingly, this is exactly the same type of argument used when justifying tables for layout. This raises con-cerns that definition lists are starting to be used inappropriately.If you would like to learn more about definition list styling, check out some of these resources:

▪️Max Design on definition lists: http://tinyurl.com/8e9fn

▪️E-commerce definition lists: http://tinyurl.com/9sn54

▪️Form layout with definition lists: http://tinyurl.com/7ef7q

▪️Manipulating definition lists for fun and profit: http://tinyurl.com/8g3ll

Styling Forms and Data Tables

As more and more interactivity is called for on the Web, forms are becoming an increasingly important part of modern web applications. Forms allow users to interact with systems, enabling them to do everything from registering feedback to booking complicated travel itineraries. As such, forms can be as simple as an e-mail address and a message field, or they can be hugely complex, spanning multiple pages. Form layout has traditionally been done using tables; however, in this chapter, you will learn that even complicated forms can be laid out using CSS.

Tables are slowly regaining their rightful position purely as a way of displaying tabular data, rather than a means of laying out pages. As well as needing to capture user data, web applications increasingly need to display this data in a usable and an easy-to-understand format. Form and data table design have been relatively neglected in favor of higher-profile areas of design. However, good information and interaction design can make or break a modern web application.

Styling data tables

Many developers realize the pitfalls of table-based design and avoid using layout tables wherever possible. A small group of individuals have gone a step further and attempted to ditch tables altogether, recreating things like calendar layouts in pure CSS. Well-meaning as this strategy is, calendars, by their nature, are table-based content. After all, they’re basically just rows of weeks and columns of days. As such, there is still a place for the use of tables on the Web. Even relatively simple data tables can be hard to read if they contain more than a few rows and columns. Without separation between data cells, information blurs together, resulting in a jumbled and confusing layout (see Figure 3-16).

Figure 3-16. Compact data tables can be very confusing at first glance

Conversely, tables with a lot of whitespace can also be very difficult to read, as columns and cells start to lose their visual association with each other. This is particularly problematic when you’re trying to follow rows of information on tables with very large column spacing, such as the one in Figure 3-17. If you are not careful, it is easy to accidentally stray into the wrong row when moving between columns. This is most noticeable in the middle of the table where the hard edge of the top and bottom of the table provide less of a visual anchor.

Figure 3-17. Widely spaced tables can also be difficult to immediately comprehend

By contrast, a few minutes spent designing your data tables can greatly improve their comprehension and the speed at which information can be retrieved. For instance, the dates in Figure 3-18 have been given breathing room with a small amount of vertical and horizontal padding. They have also been highlighted with a subtle beveled effect, making them look clickable. The main column headings have been distinguished from the data through subtly different background colors, the use of a bottom border, and typographic treatment. The result is an easy-to-use calendar widget.

Figure 3-18. Stylized data table

Table-specific elements

If data tables can be difficult for sighted users, imagine how complicated and frustrating they must be for people using assistive technologies such as screen readers. Fortunately, the HTML specification includes a number of elements and attributes intended to increase the accessibility of data tables for these devices. Not all of these elements are currently supported by screen readers, but it is definitely good practice to use them where possible.

Summary and caption

The first of these elements is a table caption, which basically acts as a heading for the table. Although this is not a required element, it is always a good idea to use a caption wherever possible. In this example, we are  using the caption to show users which month they are looking at. Another useful addition is a table summary. The summary attribute can be applied to the table tag and is used to describe the content of the table. Much like an image’s alt text, the summary should effectively summarize the data in the table, and a well-written summary may alleviate the need to read the contents of the table.

<table class=”cal” summary=”A calendar style date picker”>

<caption>

<a href=”cal.php?month=dec08″ rel=”prev”>&lt;</a> January 2008

<a href=”cal.php?month=feb09″ rel=”next”>&gt;</a>

</caption>

</table>

thead, tbody, and tfoot

Using thead, tfoot, and tbody allows you to break tables up into logical sections. For instance, you can place all of your column headings inside the thead element, providing you with a means of separately styling that particular area. If you choose to use a thead or tfoot element, you must use at least one tbody element. You can only use one thead and tfoot element in a table, but you can use multiple tbody elements to help break complicated tables into more manageable chunks.Row and column headings should be marked up as th rather than td, although if something is both a heading and data it should be left as a td. Table headings can be given a scope attribute of row or col to define whether they are row or column headings. They can also be given a value of rowgroup or colgroup if they relate to more than one row or column.

<thead>

<tr>

<th scope=”col”>Sun</th>

<th scope=”col”>Mon</th>

<th scope=”col”>Tue</th>

<th scope=”col”>Wed</th>

<th scope=”col”>Tur</th>

<th scope=”col”>Fri</th>

<th scope=”col”>Sat</th>

</tr>

</thead>

col and colgroups

While the tr element allows developers to apply styles to whole rows, it is much more difficult to apply a style to an entire column. To get around this problem, the W3C introduced the colgroup and col elements. A Colgroup is used to define and group one or more columns using the col element. Unfortunately, not many browsers support the styling of col and colgroup elements.

<colgroup>

<col id=”sun” />

<col id=”mon” />

<col id=”tue” />

<col id=”wed” />

<col id=”thur” />

<col id=”fri” />

<col id=”sat” />

</colgroup>

Data table markup

Putting all of these HTML elements and attributes together, you can create the basic outline for the calendar table shown in Figure 3-18.

<table class=”cal” summary=”A calendar style date picker”> <caption>

<a href=”#” rel=”prev”>&lt;</a> January 2008 <a href=”#”

rel=”next”>&gt;</a>

</caption>

<colgroup>

<col id=”sun” />

<col id=”mon” />

<col id=”tue” />

<col id=”wed” />

<col id=”thur” />

<col id=”fri” />

<col id=”sat” />

</colgroup>

<thead>

<tr>

<th scope=”col”>Sun</th>

<th scope=”col”>Mon</th>

<th scope=”col”>Tue</th>

<th scope=”col”>Wed</th>

<th scope=”col”>Tur</th>

<th scope=”col”>Fri</th>

<th scope=”col”>Sat</th>

</tr>

</thead>

<tbody>

<tr>

<td class=”null”>30</td>

td class=”null”>31</td>

<td><a href=”#”>1</a></td>

<td><a href=”#”>2</a></td>

<td><a href=”#”>3</a></td>

<td><a href=”#”>4</a></td>

<td><a href=”#”>5</a></td>

</tr>

<tr>

<td><a href=”#”>6</a></td>

<td><a href=”#”>7</a></td>

<td class=”selected”><a href=”#”>8</a></td>

<td><a href=”#”>9</a></td>

<td><a href=”#”>10</a></td>

<td><a href=”#”>11</a></td>

<td><a href=”#”>12</a></td>

</tr>

</tbody>

</table>

Styling the table

The CSS specification has two table border models: separate and collapsed. In the separate model, borders are placed around individual cells, whereas in the collapsed model, cells share borders. Most browsers default to the separate model, but the collapsed model is usually of more use. As such, one of the first things you would normally do is set the border-collapse property of your table to collapse. However, for the purposes of this demonstration, we want to keep the double borders in order to create a beveled effect. As such, we start by setting the border-collapse property to separate. Then, for stylistic reasons, we are going to center all the text in the table and remove the default padding and margin.

table.cal {

border-collapse: seperate;

border-spacing: 0;

text-align: center;

color: #333;

}

.cal th, .cal td {

margin: 0;

padding: 0;

}

CSS has a border-spacing property that allows you to control the spacing between cells. Unfortunately, IE 7 and below do not understand this property, so you need to fall back on the old but reliable cellspacing attribute. This attribute is, strictly speaking, presentational in nature. However, it is still valid HTML and is the only means of controlling cell spacing in IE 6 and 7.

<table cellspacing=”0″ class=”cal” summary=”A calendar style date picker”>

Adding the visual style

The groundwork has been set, so it is now time to start adding the visual style. To make the table caption look a little more like a regular heading, you can increase the font size and make it bold. You can also give the caption some breathing room by applying vertical padding.

.cal caption {

font-size:1.25em;

padding-top: 0.692em;

padding-bottom: 0.692em;

background-color: #d4dde6;

}

To position the previous and next links on either side of the current month, give them some horizontal margin and then float them left and right respectively. You can then give them a more prominent hit area by applying some padding. To style these links, we’ve decided to use the attribute selector to target their rel attributes. However, if you wanted to support older browsers, you could add a class to each link instead. Once you’ve positioned these links, you can style them any way you like. In this example,we simply going to change the links’ background color when a user hovers over them.

.cal caption [rel=”prev”] {

float: left;

margin-left: 0.2em;

}

.cal caption [rel=”next”] {

float: right;

margin-right: 0.2em;

}

.cal caption a:link,

.cal caption a:visited {

text-decoration: none;

color: #333;

padding: 0 0.2em;

}

.cal caption a:hover,

.cal caption a:active,

.cal caption a:focus {

background-color: #6d8ab7;

}

To distinguish the initial row of table headings, we are  going to give them a slightly lighter background than the rest of the table, along with a subtle underline. We also going to make the text slightly smaller than the rest of the form.

.cal thead th {

background-color: #d4dde6;

border-bottom: 1px solid #a9bacb;

font-size:0.875em;

}

By default, we want the text in the body of the table to be grayed out, indicating that it can’t be selected. You’ll notice that we have also given the text a subtle text shadow.

.cal tbody {

color: #a4a4a4;

text-shadow: 1px 1px 1px white;

background-color: #d0d9e2;

}

To give the table cells a beveled effect, you need to set slightly different colors on each side; lighter colors on the top and left, darker ones on the bottom and right. You then need to style the anchor links. In this case, we  setting them all to block and applying padding to create a button like hit area. We are also going to embolden the fonts and give them a slightly darker background.

.cal tbody td {

border-top: 1px solid #e0e0e1;

border-right: 1px solid #9f9fa1;

border-bottom: 1px solid #acacad;

border-left: 1px solid #dfdfe0;

}

.cal tbody a {

display: block;

text-decoration: none;

color: #333;

background-color: #c0c8d2;

font-weight: bold;

padding: 0.385em 0.692em 0.308em 0.692em;

}

Last we are going to set a hover state for the anchor links. Previously selected dates will also inherit this style through the inclusion of a selected class. In this case, we are going to make the links turn white on a blue background and give them a subtle text shadow.

.cal tbody a:hover,

.cal tbody a:focus,

.cal tbody a:active,

.cal tbody .selected a:link,

.cal tbody .selected a:visited,

.cal tbody .selected a:hover,

.cal tbody .selected a:focus,

.cal tbody .selected a:active {

background-color: #6d8ab7;

color: white;

text-shadow: 1px 1px 2px #22456b;

}

You’ll notice that the dates still retain their beveled appearance when hovered over. If you want give the appearance that the dates have been depressed, change the color of the cell borders so the top and left borders are darker, while the bottom and right borders are lighter. Be aware that, because this style is using a hover pseudo selector on a nonanchor element, it won’t display in IE 6. If you need this technique to work in IE 6, you’ll want to add borders to the links instead.

.cal tbody td:hover,

.cal tbody td.selected {

border-top: 1px solid #2a3647;

border-right: 1px solid #465977;

border-bottom: 1px solid #576e92;

border-left: 1px solid #466080;

}

And there you have it, a beautifully styled calendar picker similar to the one in Figure 3-18.

Simple form layout

Short and relatively simple forms are easiest to fill in when the form labels appear vertically above their associated form elements. Users can simply move down the form step by step, reading each label and completing the following form element. This method works best on short forms collecting relatively simple and predictable information such as contact details (see Figure 3-19).

Figure 3-19. Simple form layout

Useful form elements

HTML provides a number of useful elements that can help add structure and meaning to a form. The first one of these is the fieldset element. A Fieldset is used for grouping related blocks of information. In Figure 3-19, two fieldsets are being used: one for the contact details and one for the comments. Most user agents apply a thin border around fieldsets, which can be turned off by setting the border property to noneTo identify the purpose of each fieldset, you can use a legend element. Legends act a little like a fieldset’s heading, usually appearing vertically centered with the top of the fieldset and indented a little to the right. Unfortunately, legends are notoriously difficult to style because of the inconsistent way browsers place them. Some browsers, like Firefox and Safari, use padding to create a small indent. However, other browsers, such as Opera and IE, have large default indents that are not controllable using padding, margins, or even positioning. As such, if you choose to use legends, you will have to accept a certain amount of variation between browsers.

Form labels

The label element is an extremely important one, as it can help add structure and increase the usability and accessibility of your forms. As the name suggests, this element is used to add a meaningful and descriptive label to each form element. In many browsers, clicking the label element will cause the associated form element to gain focus. The real benefit of using labels is to increase form usability for people using assistive devices. If a form uses labels, screen readers will correctly associate a form element with its label. Without labels, the screen reader will have to “guess” which text relates to which form element, sometimes getting it wrong. Screen reader users can also bring up a list of all the labels in a form, allowing users to audibly scan through the form in much the same way as you would visually scan through them.Associating a label with a form control is very easy and can be done in one of two ways: either implicitly by nesting the form element inside the label element:

<label>email <input name=”email” type=”text”/><label>

or explicitly by setting the for attribute of the label equal to the id name of the associated form element:

<label for=”email”>email<label>

<input name=”email” id=”email” type=”text”/>

You will notice that this input, and all the form controls in this chapter, contain both a name and an id attribute. The id attribute is required to create the association between the form input and the label, while the name is required so that the form data can be sent back to the server. The id and name don’t have to be the same, although I prefer to keep them identical when possible, for the sake of consistency. Labels associated with form controls using the for attribute don’t need to be near those controls in the source code; they could be in a completely different part of the document. However, from a structural point of view, separating form controls from their labels isn’t wise and should be avoided wherever possible.

The basic layout

Using these three structural elements, you can start laying out your form by marking up the contents of the first fieldset. The unstyled form is shown in Figure 3-20.

<fieldset>

<legend>Your Contact Details</legend>

<div>

<label for=”author”>Name:</label>

<input name=”author” id=”author” type=”text” />

</div>

<div>

<label for=”email”>Email Address:</label>

<input name=”email” id=”email” type=”text” />

</div>

<div>

<label for=”url”>Web Address:</label>

<input name=”url” id=”url” type=”text” />

</div>

</fieldset>

Figure 3-20. Unstyled form

First, you will need to set the general styles for the fieldset and legend elements. The fieldsets must be vertically separated using margins, and the contents can be given breathing space using padding. To highlight the fieldsets, you can give them a light background with a slightly darker, 1-pixel border. Try not to make the background too dark, though, as this can add too much visual weight to the form, making it more difficult to comprehend. Making the legends bold can also help break up the information and make it easier to digest.

fieldset {

margin: 1em 0;

padding: 1em;

border : 1px solid #ccc;

background: #f8f8f8;

}

legend {

font-weight: bold;

}

Positioning the labels so they appear vertically above the form elements is actually very simple. A label is an inline element by default. However, setting its display property to block will cause it to generate its own block box, forcing the input elements onto the line below. The width of text input boxes varies from browser to browser, so for consistency, you should explicitly set the width of your text input boxes. In this example, we are using ems to create a more scalable form layout.

label {

display: block;

cursor: pointer;

}

input {

width: 20em;

}

Changing the cursor style of the label to pointer is a good idea here, as it shows that the labels can be interacted with.

Other elements

This layout works equally well for other form elements such as text areas:

<fieldset>

<legend>Comments</legend>

<div>

<label for=”text”>Message: </label>

<textarea name=”text” id=”text”>

</textarea>

</div>

</fieldset>

The dimensions of text areas also vary across browsers, so it is a good idea to explicitly set their width and height as well. In this instance, we  setting a width of 100 percent so it is effectively defined by its parent element. Setting widths in this way is a good idea, as it makes your layouts more flexible and independent.

textarea {

width: 100%;

height: 10em;

}

Unlike text areas and text inputs, radio buttons and check boxes need to be handled differently. Rather than having their labels above them, these elements usually have their labels to the right of them. When stacked vertically, all the elements are left aligned, creating a nice solid vertical and making them easier to select (see Figure 3-21).

Figure 3-21. Radio button layout

Earlier in this example, the width of the text boxes was defined by applying a width to the input element. However, the input element covers other form widgets such as check boxes, radio buttons, and submit buttons, as well as the more common text input box. As such, by setting the input element to be 20 ems wide, all of the input elements will be 20 ems.One way around this problem is to use the attribute selector to target particular types of form element. So instead of setting all the inputs to 20 ems, you could specifically target text inputs:

input[type=”text”] {

width: 20em;

}

Unfortunately, the attribute selector is only supported on more modern browsers and does not work in IE 6 and below. Until the attribute selector is more widely supported, the best way to distinguish between input elements is to give them a class.For instance, you could give radio buttons a class name of radio:

<fieldset>

<legend>Remember Me</legend>

<div>

<label for=”remember-yes”><input id=”remember-yes” class=”radio” name=”remember” type=”radio” value=”yes” />Yes</label>

</div>

<div>

<label for=”remember-no”><input id=”remember-no” class=”radio”

name=”remember” type=”radio” value=”no” checked=”checked” />No</label>

</div>

</fieldset>

You could then override the previously set input width by setting the width of radio buttons to auto. The same can be done for check boxes and submit buttons:

input.radio, input.checkbox, input.submit {

width: auto;

}

Notice how it wrapped the labels around the form elements on this occasion. If you remember, previously set all the labels in this form to behave as block level elements, forcing their associated form controls onto a separate line. Obviously, we don’t want this to happen with radio button labels, so wrapping the labels around the form controls prevents this.The last thing you need to do is add a little bit of right margin to the radio buttons, in order to provide so spacing between the labels.

#remember-me .radio {

margin-right: 1em;

}

Embellishments

The layout is now complete, but you can incorporate a few nice additions for more advanced browsers. For instance, you could help users easily anchor themselves to the form field they are filling in by changing the element’s background color when it receives focus:

Input[type=”text”]:focus, textarea:focus {

background: #ffc;

}

You can also harmonize the look of the text field and text area elements by giving them custom borders. This is particularly useful for Firefox, which renders the bottom and right borders on these elements as white, causing them to lose definition when on a white background (see Figure 3-22).

Figure 3-22. The bottom and right borders of text inputs and text areas in Firefox are white, causing them to lose definition on white backgrounds

In this example, an attribute selector is used to target the text inputs as this style is mostly for the benefit of Firefox, which understands this selector.

input[type=”text”], textarea {

border-top: 2px solid #999;

border-left: 2px solid #999;

border-bottom: 1px solid #ccc;

border-right: 1px solid #ccc;

}

In this example, we’re not using any password fields. However, if you were creating a generic form style for your entire site, you would need to include [type=”password”] in the previous two examples as well.

Required fields

Many forms contain fields that must be filled in. You can indicate these required fields by placing styled text, or an asterisk, next to them. Because this information is emphasizing the field’s required status, the most appropriate element for this information is an em or strong element:

<div>

<label for=”author”>Name:<em class=”required”>(required)</em>/label>

<input name=”author” id=”author” type=”text” />

</div>

You can then style this information however you want. In this example  reducing the font size and making the text red:

.required {

font-size: 0.75em;

color:#760000;

}

And there you have it: a simple yet attractive-looking form layout using pure CSS.

Complicated form layout

For longer and more complicated forms, vertical space starts to become an issue, as does the ease of scanning. To improve scanning and reduce the amount of vertical space used, it makes sense to position the labels and form elements horizontally, rather than vertically above one another. Creating a form such as the one in Figure 3-23 is actually very simple and uses almost exactly the same code as the previous example.

Figure 3-23. Horizontal form alignment

The only difference between this and the previous example is that, instead of setting the label to be a block-level element, you float the labels left instead. You also need to give the label a width so that all of the form elements line up nicely:

label {

float: left;

width: 10em;

cursor: pointer;

}

If the form labels are likely to wrap onto multiple lines, it would be a sensible idea to clear the container divs as well. This will prevent them from interfering with the next set of labels and ruining your carefully crafted layout.

form div {

clear: left;

}

Forms are rarely as simple as the one in Figure 3-23, and you will often need to create exceptions to your basic form styling rules to handle things such as multiple form widgets on a single line or columns of check boxes or radio buttons (see Figure 3-24). The next couple of sections will explain how to handle these types of exceptions.

Figure 3-24. More complicated form layouts

Accessible date input

As you learned in the previous examples, form labels are important for the accessibility of your forms. However, there are situations when you may not want to display a label for every element. For instance, in Figure3-24 you can see a group of form elements for collecting date information. In this situation, visually displaying each label would be overkill, as it would split the date of birth up into three separate entities rather than being perceived as a single entity. However, while you may not want to display the labels, it is still important that the labels appear in the source code and are available to screen readers.

<div>

<label for=”dateOfBirth”>Date of Birth:</label>

<input name=”dateOfBirth” id=”dateOfBirth” type=”text” /> <label id=”monthOfBirthLabel” for=”monthOfBirth”>

Month of Birth:</label>

<select name=”monthOfBirth” id=”monthOfBirth”> <option value=”1″>January</option>

<option value=”2″>February</option>

<option value=”3″>March</option>

</select>

<label id=”yearOfBirthLabel” for=”yearOfBirth”>Year of Birth:</label> <input name=”yearOfBirth” id=”yearOfBirth” type=”text” />

</div>

To create this layout, you first need to hide the “month of birth” and “year of birth” labels. Setting the labels’ display property to none would stop the labels from displaying, but it would also prevent many screen readers from accessing them. Instead, you can position the labels off screen using a large negative text indent. In the generic form style we created earlier, labels have been given a set width. To prevent the labels from affecting the layout, the width needs to be zeroed down for these labels as well:

#monthOfBirthLabel, #yearOfBirthLabel {

text-indent: -1000em;

width: 0;

}

The various form controls can then be sized individually and given margins to control their horizontal spacing:

input#dateOfBirth {

width: 3em;

margin-right: 0.5em;

}

select#monthOfBirth {

width: 10em;

margin-right: 0.5em;

}

input#yearOfBirth {

width: 5em;

}

Multicolumn check boxes

Creating a two-column layout for large groups of check boxes or radio buttons is a little more involved. Labels only work for individual elements, not groups of elements. Ideally, we would wrap the whole group in a fieldset and use the legend to act like a label for the group. Unfortunately, due to the inconsistent way browsers handle the positioning of legends, this is not currently a practical solution. So until the browsers offer more consistent support, the best option is to use a heading element instead.

To create the column effect, the check boxes are split into two sets, and each set is wrapped in a div with a class of col. These elements are then grouped together by wrapping them in a fieldset with a descriptive ID:

<fieldset id=”favoriteColor”>

<h2>Favorite Color:</h2>

<div class=”col”>

<div>

<label><input class=”checkbox” id=”red” name=”red” type=”checkbox” value=”red” />red</label>

</div>

</div>

<div class=”col”>

<div>

<label><input class=”checkbox” id=”orange” name=”orange” type=”checkbox” value=”orange” />orange</label>

</div>

</div>

</fieldset>

Because a generic fieldset style has already been created, the first thing you need to do is override those styles, zeroing down the padding and margin, removing the borders and setting the background color to be transparent:

fieldset#favoriteColor {

margin: 0;

padding: 0;

border: none;

background: transparent;

}

The heading is going to act like a label, so it needs to be floated left and given a width of 10 ems like the other labels. The headline also needs to look like a label, so the font weight needs to be set to normal, and the font size needs to be reduced.

#favoriteColor h2 {

width: 10em;

float: left;

font-size: 1em;

font-weight: normal;

}

The two-column layout can then be created by giving the divs a width and floating them left. However, as all of the divs in this form have been cleared by default, we need to override that declaration by using clear:none.

#favoriteColor .col {

width: 8em;

float: left;

clear: none;

}

All the labels in this form have been floated left and set to be 10 ems wide. However, the labels for the check boxes do not need to be floated, so we should override that declaration here.

#favoriteColor label {

float: none;

}

And there you have a relatively complex form layout. The basic form style takes care of the general layout, and exceptions can be handled on an individual basis by overriding these styles.

Submit buttons

Forms are a great way of adding interactivity to your site and for posting data back to the server. In order to activate the form, you therefore need some kind of button control. Normally, people use an input element with the type value set to submit. Input buttons are the most common way of submitting data to the server, but they are not without problems, not least the fact that you can’t target them with just an element selector. You could target them with an attribute selector, but this isn’t supported by older version of Internet Explorer, so your only option is to target them directly with an ID or class selector. So instead of using an input element, why not use the button element?

The button element has been gaining in popularity of late but is still relatively unknown and underutilized. This is a shame as button elements give you a great deal of flexibility. For a start, you can wrap button tags around an image and that image becomes your control (see Figure 3-25).

<div>

<button type=”submit”>

<img src=”/img/button.png” alt=”Book Now” />

</button>

</div>

Figure 3-25. Button element using a button image

As buttons have some default styling, you will want to turn this off.

button {

border: none;

background: none;

cursor: pointer;

}

Many operating systems, like OS X, prevent authors from changing the style of their input buttons, preferring to keep consistency throughout the operating system. However, the button element doesn’t suffer from these constraints. As such, it is possible to create fairly advanced button styles purely using CSS. For instance, say you started with this simple submit button.

<p>

<button type=”submit”>Book Now »</button>

</p>

You could start by giving the button some explicit dimensions and a colored border. You could then round the corners off using border-radius and apply a nice text shadow. Last, you could apply a gradient background, either by using an image or possibly even using Webkit-specific gradients. The result would look something like Figure 3-26.

button.two {

width: 200px;

height: 50px;

border: 1px solid #989898;

-moz-border-radius: 6px;

-webkit-border-radius: 6px;

border-radius: 6px;

background: url(/img/button-bg.png) #c5e063 bottom left repeat-x;

-moz-box-shadow: 2px 2px 2px #ccc;

-webkit-box-shadow: 2px 2px 2px #ccc;

box-shadow: 2px 2px 2px #ccc;

color: #fff;

font-size: 26px;

font-weight: bold;

text-shadow: 1px 1px 1px #666;

}

Figure 3-26. Button element using pure CSS

The main limitation with button elements is the way IE 6 and, to a lesser extent, IE 7 handle their submission. Rather than submitting the contents of the value attribute, as other browsers do, IE 6 and IE 7 submit the contents of the element. Furthermore, if you have multiple buttons on a page, IE 6 will submit the contents of all the buttons, rather than just the one that was clicked. As such, if you wanted to use more than one button per page, you need to make sure that they all have the same function, as you won’t be able to tell which one had been activated in older version of Internet Explorer.

Form feedback

Forms will usually require some type of feedback message to highlight fields that have been missed or incorrectly filled in. This is usually done by adding an error message next to the appropriate field (see Figure 3-27).

Figure 3-27. Example of form feedback

To produce this effect, you could wrap your feedback text in a em and place it after the text input in the source code. However, for everything to line up correctly, both the em and the preceding input would need to be floated. This will have an effect on the behavior of the enclosing paragraph, which in turn will have an effect on the whole layout. Furthermore, many screen readers will ignore text between form elements, unless they are enclosed in a label. To avoid these problems, the best approach is to include the error message text inside the form label, and then position it using CSS:

<div>

<label for=”email”>Email Address:

<em class=”feedback”>Incorrect email address. Please try again.

</em>

</label>

<input name=”email” id=”email” type=”text” />

</div>

To position the feedback em, you first need to set the position of all of the paragraphs in the form to relative, thereby setting up a new positioning context. You can then position the feedback em absolutely, so it appears to the right of the text input. We know that the labels are 10 ems wide and the text boxes are 20 ems wide, so we can set the left position of the feedback span to be 30 ems.

form div {

position: relative;

}

form .feedback {

position: absolute;

left: 30em;

right :0;

top: 0.5em;

}

Rather annoyingly, IE 6 and below incorrectly set the width of the feedback em to be the minimum width possible. To get around this problem, you need to set an explicit width for this browser. 

form .feedback{

width: 10em;

}

You can then apply whatever styling you want to your feedback messages. In this case, we have made the text bold red and have applied a warning image to the left side of the message:

form div {

position: relative;

}

.feedback {

position: absolute;

left: 30em;

right :0;

top: 0.5em;

font-weight: bold;

color: #760000;

padding-left: 18px;

background: url(/img/error.png) no-repeat left top;

}

You could also use this technique to provide positive feedback or advice on how to fill out particular parts of the form.

Summary

In this chapter you have learned how flexible lists can be. You learned how to create vertical and horizontal navigation bars, including accessible tabbed navigation. Finally, you learned how to use positioning to create pure CSS image maps and remote rollovers.

In this chapter, you have learned how different form layouts can work in different situations. You can now lay out complicated forms using CSS, without harming a single table in the process. You have learned how tables should be used—for data rather than layout—and have learned that data table design can be fun.

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.