Some sheep, grazing.
3. Edit the thumbnails. For each thumbnail, add some caption text, as shown following. Ensure that
there’s a comma between the two swapPhoto values you now have.
Next, a style sheet is created (named javascript-overrides.css for this example), with a rule that targets
the relevant div and sets display to none.
#hiddenDiv {
display: none;
}
Finally, amendments are made to the JavaScript file, adding some lines that attach the new JavaScript
document to the web page:
var cssNode = document.createElement('link');
cssNode.setAttribute('rel', 'stylesheet');
cssNode.setAttribute('type', 'text/css');
cssNode.setAttribute('href', 'javascript-overrides.css');
document.getElementsByTagName('head')[0].appendChild(cssNode);
The results of this are the following:
If a user has JavaScript enabled, javascript-overrides.css is loaded, applying the display
value of none to the togglable div.
If a user has JavaScript disabled, javascript-overrides.css is not loaded, meaning the
togglable div contents are visible.
188
www.freepdf-books.com
Using Links and Creating Navigation
See the collapsible-div-accessible folder within the chapter 5 folder for reference files.
Modularizing the collapsible content script
Although the previous script works perfectly well for a single div, it’s awkward if you want to use several
divs over the course of a page. That’s how the old Images from Iceland site works, and I had to keep track
of id names and values while constructing it. However, it is possible to make a toggler strip more modular,
although this relies on keeping document structure very strict as far as the collapsible sections go. The files
for this section are in the collapsible-div-modular folder within the chapter 5 folder.
The JavaScript is similar to that in the previous example.
function toggle(toggler) {
if(document.getElementById) {
targetElement = toggler.parentNode.nextSibling;
if(targetElement.className == undefined) {
targetElement = toggler.parentNode.nextSibling.nextSibling;
}
}
}
if (targetElement.style.display == "block") {
targetElement.style.display = "none";
}
else {
targetElement.style.display = "block";
}
The main change is that instead of targeting a div with a specific id value, the script targets an element in
relation to the one being used as a toggler, by way of the parentNode/nextSibling JavaScript properties.
If you look at the HTML document, you’ll see that the parent of the anchor element is the p element. What
the next sibling element is depends on the browser—Internet Explorer just looks for the next element in the
document (div), but other browsers count whitespace as the next sibling.
Toggle div 1!
Initially hidden content (div 1) goes here.
It would be possible to get around this by stripping whitespace. However, a line in the JavaScript makes
this unnecessary.
if(document.getElementById) {
targetElement = toggler.parentNode.nextSibling;
if(targetElement.className == undefined) {
targetElement = toggler.parentNode.nextSibling.nextSibling;
}
189
www.freepdf-books.com
Chapter 5
The first line of the previous code block sets the target to the next sibling of the parent element of the link.
In Internet Explorer this works, but other browsers find only whitespace. Therefore, the second line
essentially says, “If you find whitespace (undefined), then set the target to the next sibling on.” It’s a bit of
a workaround, but it’s only one line of JavaScript.
The JavaScript also includes the method used in the preceding “Enhancing accessibility for collapsible
content” section to make the togglable sections initially invisible in JavaScript-enabled browsers only. Note
that the related CSS is slightly different from that shown in the previous section—instead of hidden content
being in a div with an id value of hiddenDiv, it’s now in multiple divs, all of which have a class value of
expandable. Therefore, the selector in the CSS rule has been updated accordingly:
.expandable {
display: none;
}
This system enables you to use as many collapsible divs as you like on the page, and you don’t have to
set id values—the toggling is essentially automated. However, as mentioned earlier, you must ensure that
your structure remains the same for each area that can be toggled; otherwise, the script won’t find the
correct element to make visible or invisible when the links are clicked.
How to find targets for collapsible content scripts
If you want to change your document structure when using the script from the previous section in this
chapter, you need to find the parent/sibling path, in Internet Explorer and in other browsers. If you have a
good grasp of JavaScript, this should be simple; however, if you don’t—or you just want to sanity-check
your values—it’s simple to find out what an element’s parent is, what it’s next sibling is, and various
combinations thereof.
First, give your clickable element a unique id value:
Toggle div 1!
Elsewhere within the web page, add the following script:
Before .nodeName, add whatever combination of .parentNode and .nextSibling you like—here’s an
example:
190
www.freepdf-books.com
Using Links and Creating Navigation
When you load the web page in a browser, an alert message will be displayed. This will detail what the
target element is, based on the path defined in the previous code block.
In this section, you’ve seen a bare-bones, unstyled version of how to work with collapsible content. Later in
the chapter, this method will be used to create collapsible sections for a navigation bar.
Creating navigation bars
The chapter has so far largely concentrated on inline navigation, so we’ll now turn our attention to
navigation bars. Before getting immersed in the technology, you need to decide what names you’re going
to use for your navigation bar’s items. When designing the basic structure of the site, content should be
grouped into categories, and this is often defined by what the user can do with it. It therefore follows that
navigation bar links tend to be one of the following:
Action-based (buy now, contact us, read our history)
Site audience–based (end users, resellers, employees)
Topic-based (news, services, contact details)
Whenever possible, keep to one of the preceding categories rather than mixing topics and actions. This
sits easier with readers. Navigation links should also be succinct, to the point, and appropriate to the brand
and tone of the website.
In this section, we’ll cover using lists for navigation, styling list-based navigation bars, working with inline
lists, and creating graphical navigation bars with rollover graphics.
Using lists for navigation bars
Think back to what we’ve covered to this point about semantic markup. Of the HTML elements that exist,
which is the most appropriate for a navigation bar? If you said, “a table,” go to the back of the class. Using
191
www.freepdf-books.com
Chapter 5
tables for navigation bars might be a rapid way of getting them up and running, but it’s not structurally
sound. When looked at objectively, navigation bars are essentially a list of links to various pages on the
website. It therefore follows that HTML lists are a logical choice to mark up navigation bars.
When creating the initial pass of the website, just create the list as it is, along with all the associated
pages, and let people play around with the bare-bones site. This enables users to get a feel for its
structure, without getting distracted by content, colors, and design. However, sooner or later, you’re going
to want to make that list look a little fancier.
Much of the remainder of this chapter is concerned with CSS and how it can be used to style lists. From a
plain HTML list, you can rapidly create exciting visual designs—and ones that are easy to update, both in
terms of content and design. After all, adding another navigation link is usually just a matter of adding
another list item.
The nav element
HTLM5 has introduced a new element that provides a semantic way for grouping together links used for
major navigation. As you saw previously in this chapter the nav element was used for skip links. Since
these links are for accessibility this is considered major navigation. Some other areas of your site that can
be considered major navigation and should therefore use the nav element include main navigation,
pagination links, breadcrumbs, and a table of contents.
Using HTML lists and CSS to create a button-like vertical navigation bar
Required files- basic.html and CSS-default.css from the basic-boilerplates folder.
What you’ll learn How to create a vertically aligned navigation bar and how to style it with CSS to create a
3D-like effect for each of the list items.
Completed files
The vertical-navigation-bar folder in the chapter 5 folder
1. Create the list structure. Add the following code block to create the structure of the navigation bar.
By using nested lists, you can provide the navigation bar with a hierarchical structure (and you
can style each level in CSS). In this example, the list has two levels. (Refer to Chapter 3 for an
overview of correctly formatting lists.) This list is nested within a div with an id value of
navigation, which we’ll later take advantage of by using contextual selectors. (For this example,
dummy href values of # are being used, but in a live site, always check that your links lead
somewhere!)
link to a page
link to a page
two
link
link
link
link
to
to
to
to
a
a
a
a
page
page
page
page
three
link
link
link
link
to
to
to
to
a
a
a
a
page
page
page
page
2. Add some padding to the body element, so page content doesn’t hug the browser window edges.
Also, add the background-color pair shown following:
body {
font: 62.5%/1.5 Verdana, Arial, Helvetica, sans-serif;
padding: 20px;
background-color: #aaaaaa;
}
3. Style the list. Add the following rule to remove the default bullet points from
unordered lists within the navigation div, define a width for the lists, and also
set the default font style.
nav ul {
list-style-type: none;
width: 140px;
font: 1.2em/1 Arial, Helvetica, sans-serif;
}
4. Set an override for nested lists. As you can see from the previous image, the nested links have
much larger text. This is because font sizes in ems are inherited, and therefore the font size
within the nested lists ends up at 1.2ems multiplied by 1.2ems. By adding the following rule, the
font size of nested lists is reset to 1em, making nested lists look the same as top-level lists.
nav ul ul {
font-size: 1em;
}
193
www.freepdf-books.com
Chapter 5
5. Style the buttons. Use a contextual selector to style links within the navigation container (that is,
the links within this list). These styles initially affect the entire list, but you’ll later override them for
level-two links. Therefore, the styles you’re working on now are intended only for level-one links
(which are for sections or categories). This first set of property/value pairs turns off the default link
underline, sets the list items to uppercase, and defines the font weight as bold.
nav a:link, nav a:visited {
text-decoration: none;
text-transform: uppercase;
font-weight: bold;
}
6. Set button display and padding. Still within the same rule, set the buttons to display as block,
thereby making the entire container an active link (rather than just the link text). Add some
padding so the links don’t hug the edge of the container.
nav a:link, nav a:visited {
text-decoration: none;
text-transform: uppercase;
font-weight: bold;
display: block;
padding: 3px 12px 3px 8px;
}
7. Define colors and borders. Define the button background and foreground colors, setting the
former to gray and the latter to white. Then add borders to create a 3D effect. Borders can be
styled individually. By setting the left and top borders to a lighter shade than the background and
setting the right and bottom borders to a darker shade, a 3D effect is achieved. (Don’t use black
and white, because it will make the result is too harsh.)
nav a:link, nav a:visited {
text-decoration: none;
text-transform: uppercase;
font-weight: bold;
display: block;
padding: 3px 12px 3px 8px;
background-color: #666666;
color: #ffffff;
border-top: 1px solid #dddddd;
border-right: 1px solid #333333;
border-bottom: 1px solid #333333;
border-left: 1px solid #dddddd;
}
8. Define other link states. The hover state is defined by just changing the
background color, making it slightly lighter.
nav a:hover {
background-color: #777777;
}
194
www.freepdf-books.com
Using Links and Creating Navigation
The active state enables you to build on the 3D effect: the padding settings are changed to move the text
up and left by 1 pixel, the background and foreground colors are made slightly darker, and the border
colors are reversed.
nav a:active {
padding: 2px 13px 4px 7px;
background-color: #444444;
color: #eeeeee;
border-top: 1px solid #333333;
border-right: 1px solid #dddddd;
border-bottom: 1px solid #dddddd;
border-left: 1px solid #333333;
}
9. Style nested list item links. The selector #navigation li li a enables you to style links within a
list item that are themselves within a list item (which happen to be in the navigation container). In
other words, you can create a declaration for level-two links. These need to be differentiated from
the section links, which is the reason for the following rule setting them to lowercase and normal
font weight (instead of bold). The padding settings indent these links more than the section links,
and the background and foreground colors are different, being very dark gray (almost black) on
light gray rather than white on a darker gray.
nav li li a:link, nav li li a:visited {
text-decoration: none;
text-transform: lowercase;
font-weight: normal;
padding: 3px 3px 3px 17px;
background-color: #999999;
color: #111111;
}
10. Style nested item hover and active states. This is done in the same way as per the section links,
changing colors as appropriate and again reversing the border colors on the active state.
nav li li a:hover {
background-color: #aaaaaa;
}
nav li li a:active {
padding: 2px 4px 4px 16px;
background-color: #888888;
color: #000000;
border-top: 1px solid #333333;
border-right: 1px solid #dddddd;
border-bottom: 1px solid #dddddd;
border-left: 1px solid #333333;
}
The navigation bar is now complete, and as you can see from the following images (which depict, from left
to right, the default, hover, and active states), the buttons have a tactile feel to them. Should this not be
to your liking, it’s easy to change the look of the navigation bar because everything is styled in CSS. To
expand on this design, you could introduce background images for each state, thereby making the
195
www.freepdf-books.com
Chapter 5
navigation bar even more graphical. However, because you didn’t simply chop up a GIF, you can easily
add and remove items from the navigation bar, just by amending the list created in step 1. Any added
items will be styled automatically by the style sheet rules.
Creating a vertical navigation bar with collapsible sections
Required files
What you’ll learn
collapsible
Completed files
The files from vertical-navigation-bar in the chapter 5 folder
How to take the navigation bar created in the previous exercise and make its sections
vertical-navigation-bar-collapsible in the chapter 5 folder
1. Set up the JavaScript. Create a new JavaScript document and attach it to the HTML file via a
script element in the head of the document. (In the example files, this document has been
named vertical-navigation-bar.js.) First, add the JavaScript lines first shown in the
“Enhancing accessibility for collapsible content” section:
var cssNode = document.createElement('link');
cssNode.setAttribute('rel', 'stylesheet');
cssNode.setAttribute('type', 'text/css');
cssNode.setAttribute('href', 'javascript-overrides.css');
document.getElementsByTagName('head')[0].appendChild(cssNode);
Next, add the toggler script shown in the “Modularizing the collapsible content script” section, but amend
the target element as shown:
function toggle(toggler) {
if(document.getElementById) {
targetElement = toggler.nextSibling;
196
www.freepdf-books.com
Using Links and Creating Navigation
if(targetElement.className == undefined) {
targetElement = toggler.nextSibling.nextSibling;
}
if (targetElement.style.display == "block")
{
targetElement.style.display = "none";
}
else
{
targetElement.style.display = "block";
}
}
}
Note that if you wanted to toggle different kinds of elements on your page, the two
scripts shown so far in this chapter would clash. Therefore, you would need to create
two different functions, with different names; for example, you could change all instances
of toggle(toggler) in this exercise to toggleNav(toggler).
2. Amend the list. To each top-level navigation link, add the onclick attribute, as shown following.
And to each second-level list that you initially want to be invisible, add the class attribute shown.
For any list you want to be visible, instead add style="display: block;".
Section one
a style sheet. Create and save the style sheet document javascriptoverrides.css, and add the following rule to initially hide any lists with the collapsibleList class
value in JavaScript-enabled browsers.
3. Add
#navigation ul.collapsibleList {
display: none;
}
The following images show the results (which depict, from left to right, the default, hover, and active
states).
197
www.freepdf-books.com
Chapter 5
Working with inline lists
By default, list items are displayed in a vertical fashion, one under the other. However, this behavior can
be overridden in CSS, enabling you to create inline lists. This is handy for website navigation, since many
navigation bars are horizontally oriented. Some designers mark up horizontal navigation up by using
strings of links separated by vertical bars or spaces:
A link |
A link |
A link
However, a horizontal navigation bar is still a list of links, and so semantically should be marked up in the
same way as the vertical navigation bar in the previous exercise. In this section, you’ll find out how to work
with inline lists, discovering how to create breadcrumb navigation, CSS-only “tabbed” navigation, and
various graphical navigation bars, complete with rollover effects—all without relying on JavaScript.
Creating breadcrumb navigation
Required files
basic.html and CSS-default.css from the basic-boilerplates folder, along
with double-arrow.gif from navigation-images within the chapter 5 folder
What you’ll learn How to create breadcrumb navigation by using a list styled in CSS. Breadcrumb
links show the path you’ve taken to the current document
Completed files
The breadcrumb-navigation folder in the chapter 5 folder
1. Add the list. In the HTML document, add the following code for the breadcrumbs. Note that the
last item signifies the current page—this is why it’s not a link.
198
www.freepdf-books.com
Using Links and Creating Navigation
2. Add some body padding. Add a padding value to the existing body rule.
body {
font: 62.5%/1.5 Verdana, Arial, Helvetica, sans-serif;
padding: 20px;
}
3. Style the list by adding the following rule. The font-size setting specifies the font size for the list
items, and the margin-bottom setting adds a margin under the list.
#breadcrumbs ul {
font-size: 1.2em;
margin-bottom: 1em;
}
4. Add the following rule to style the list items. By setting display to inline, list items are stacked
horizontally. The background value sets double-arrow.gif as the background to each list item
(ensure it’s in the same directory as the CSS document, or modify the path accordingly); the
positioning values ensure the background is set at 0 horizontally and 50% vertically, thereby
vertically centering it at the left—at least once no-repeat is set, which stops the background tiling.
Finally, the padding value sets padding at the right of each list item to 10px, ensuring items don’t
touch the subsequent background image; the left padding value of 15px provides room for the
background image, ensuring the list item text doesn’t sit on top of it.
#breadcrumbs ul li {
display: inline;
background: url(double-arrow.gif) 0 50% no-repeat;
padding: 0 10px 0 15px;
}
Note that when list items are displayed inline, the default bullet points are not displayed.
This is one reason why the bullets in this example are background images, although we
also wanted something more visually relevant, right-facing arrows showing the path
direction.
5. Remove the first bullet. As the trail is leading from the first item, it shouldn’t have a bullet. This
can be dealt with via a simple, standards-compliant rule that removes the background from only
the list item that is the first child of the unordered list (that is, the first list item in the list):
#breadcrumbs ul li:first-child {
background: none;
}
199
www.freepdf-books.com
Chapter 5
Creating a simple horizontal navigation bar
Required files
What you’ll learn
styled using CSS.
Completed files
The graphical-navigation-starting-point folder from the chapter 5 folder
How to create a good-looking navigation bar, entirely based on HTML text and
The simple-horizontal-navigation-bar folder in the chapter 5 folder
1. Examine the web page. The web page for this exercise—graphical-navigation.
html—is designed for flexibility when it comes to styling elements on the page, making it easy to
change elements without touching the markup (this page is used with a few modifications in
subsequent exercises, too).
The page’s contents are placed within a wrapper div, within which are the masthead and content divs. The
latter contains some paragraphs, and the former includes a navContainer div, which houses a nav
element, which in turn houses the unordered list shown in the following code block. (This nesting of divs
isn’t required for all sites—often you can get away with a single nav el ement around the navigation list;
however, having an additional wrapper or two is often useful for more complex layouts.)
The list is an unordered list. The main difference from previous lists is the inclusion of an id value for each
list item. For horizontal lists, especially those that will be highly styled, this is worth doing, because it
enables you to work all manner of CSS trickery later, which can benefit the web page. (In fact, some of the
techniques can be applied to vertical lists, too.)
2. Edit the body and p rules. This design is going to have a classic feel, so in the CSS file, edit the
body rule to amend the font set, add a light gray background, and amend the p rule to change the
font size.
body {
font: 62.5%/1.5 Georgia, "Times New Roman", Times, serif;
background: #dddddd;
}
p {
font-size: 1.3em;
margin-bottom: 1em;
}
3. Style the structural divs. First, add a rule to style the wrapper div, as shown in the following code
block. This sets a fixed width for the div, centers it horizontally, and applies borders on all edges
except the top one. The background value provides a white background for the page’s content.
200
www.freepdf-books.com
Using Links and Creating Navigation
(Note that there’s plenty of explanation about page layout in Chapter 7.) For the content area, add
some horizontal padding by adding the #content rule shown in the following code block.
#wrapper {
width: 700px;
margin: 0 auto;
border-right: 1px solid #898989;
border-bottom: 1px solid #898989;
border-left: 1px solid #898989;
background: #ffffff;
}
#content {
padding: 0 15px;
}
4. Style the navigation container by adding the following rule to style the navContainer div. In this
rule, the font style for the navigation bar’s links is set, and the text-align value centers the
content horizontally. The padding value applies some padding at the top and bottom of the
navContainer div, ensuring its content doesn’t hug its edges—in design, the space is often as
important as the content, so don’t cram things in.
#navContainer {
font: 1.1em/1 Georgia, "Times New Roman", Times, serif;
background: #d7d7d7;
text-align: center;
padding: 7px 0px;
border-top: 1px solid #898989;
border-bottom: 1px solid #898989;
margin-bottom: 10px;
}
5. Style the list items. Now that the structure is styled, it’s time to get cracking on the list. First, add a
rule to remove the default bullets from the unordered list within the navigation div.
#navigation ul {
list-style: none;
}
Next, set the list items to display inline, as with the breadcrumbs. Add some horizontal padding, and also,
as shown, add a border to each item’s right edge, which will act as a visual separator, making each link
more distinct.
201
www.freepdf-books.com
Chapter 5
#navigation li {
display: inline;
padding: 0px 9px;
border-right: 1px solid #aaaaaa;
}
If you test the page at this point, you’ll see that all the links have a right-edge border—not a terrible
crime—but from a design standpoint, the one at the far right shouldn’t have one (after all, separators are
needed only between pairs of links). Luckily, because of the id values applied to the list items earlier, each
one can be individually styled, which also means an override can be applied to a specific link. In this case,
add the following rule, which removes the border from the list item with an id value of
contactDetailsPageLink:
#navigation #contactDetailsPageLink {
border-right: none;
}
6. The last thing to do is style the links. The following rules set the link text to uppercase, removing
the default underline and coloring them black by default. The links are then gray on the visited
state, have an underline on the hover state, and are red on the active state.
#navigation a:link, #navigation a:visited {
text-transform: uppercase;
text-decoration: none;
}
#navigation a:link {
color: #000000;
}
#navigation a:visited {
color: #222222;
}
#navigation a:hover {
text-decoration: underline;
}
#navigation a:active {
color: #ff0000;
}
202
www.freepdf-books.com
Using Links and Creating Navigation
Note: In this example, the color of the navigation links—which have no underline—is the
same as the body copy. While this would be a very bad idea for inline links, it’s fine for
the navigation links, because they’re obviously distinct from the text elsewhere on the
page, due to the background color and horizontal line that separates the navigation area
from the content area
Creating a CSS-only tab bar that automates the active page
Required filesThe graphical-navigation-starting-point folder from the chapter 5 folder
What you’ll learn
Completed files
How to create a tab-style navigation bar, using only CSS for styling (no images)
The css-only-tab-bar folder in the chapter 5 folder
1. Edit the body element—in the HTML page, edit the body start tag, adding the class value shown.
Its significance will be explained later.
2. Edit the body rule. In the CSS document, amend the body rule as shown to add a light gray
background:
body {
font: 62.5%/1.5 Verdana, Arial, Helvetica, sans-serif;
background: #dddddd;
}
3. Style structural divs. Add the following #wrapper rule, which defines a set width for the page,
centers it, and sets the background color to white.
#wrapper {
width: 700px;
margin: 0 auto;
background: #ffffff;
}
Next, style the content div by adding the following rule, which adds a border to all edges but the top one
and defines internal padding:
#content {
padding: 15px 15px 0;
border-right: 1px solid #898989;
border-bottom: 1px solid #898989;
border-left: 1px solid #898989;
}
These rules work slightly differently from those in the previous exercise. We want the content borders to
start right under the navigation, which is why the padding is being applied to the top of the content div,
rather than a margin below the navContainer div.
203
www.freepdf-books.com
Chapter 5
4. Style the navContainer div. Add the following rule to style the navContainer div. The font settings
define a size and family. Avoid setting a line-height value, because that makes it much harder
to line up the tabs with the borders later. The padding value applies some padding above the
soon-to-be-created tabs, and the border-bottom value finally surrounds all edges of the content
div with a border. Because the wrapper div has a white background, this currently shows through
the navContainer div, and so a background setting is applied, using the same background color
value as applied to the body element.
#navContainer {
font: 1.1em Arial, Helvetica, sans-serif;
text-align: center;
padding: 20px 0 0;
border-bottom: 1px solid #909090;
background: #dddddd;
}
5. Style the list. Add the following rule to style the list. The bottom padding value (5px here) adds
padding to the bottom of the list and needs to be equivalent to the padding value you want to be
under the text in each tab.
#navigation ul {
padding: 0 0 5px;
}
Next, style the list items to make them display inline.
#navigation li {
display: inline;
}
6. Add the following rule to style the links. Most of the property values should be familiar by now.
Note how the border value applies a border to each link; this, in tandem with the background
value, gives all the links the appearance of background tabs. The padding setting provides space
around the link contents (and note how the vertical padding value is the same as the bottom
padding value in step 5), and the margin-right setting adds some space between each tab.
#navigation a:link, #navigation a:visited {
text-transform: uppercase;
text-decoration: none;
204
www.freepdf-books.com
Using Links and Creating Navigation
}
color: #000000;
background: #bbbbbb;
border: 1px solid #898989;
padding: 5px 10px;
position: relative;
margin-right: 5px;
As per the previous exercise, the unwanted right-hand value for the rightmost tab (in this case, the marginright setting) can be overridden by using a contextual selector that takes advantage of the id values
defined in the HTML document’s unordered list items.
#navigation #contactDetailsPageLink a:link, #navigation
}
#contactDetailsPageLink a:visited {
margin-right: 0;
7. Style other link states. Add the following two rules to define the other link states. The first makes
the text slightly lighter when a link has been visited. The second brings back the default underline
on the hover state, along with making the link’s background slightly lighter.
#navigation a:visited {
color: #222222;
}
#navigation a:hover {
text-decoration: underline;
background: #cccccc;
}
8. Create page-specific overrides. Remember back in step 1, when you defined an id value for the
body element? This can now be used to automate the active tab via the following rule:
#homePage #homePageLink a:link, #homePage #homePageLink a:visited,
#servicesPage #servicesPageLink a:link, #servicesPage
#servicesPageLink a:visited, #customerSupportPage
#customerSupportPageLink a:link, #customerSupportPage
#customerSupportPageLink a:visited, #contactDetailsPage
#contactDetailsPageLink a:link, #contactDetailsPage
#contactDetailsPageLink a:visited {
background: #ffffff;
border-bottom-color: #ffffff;
}
205
www.freepdf-books.com
Chapter 5
The declaration is simple: a white background is applied, and the bottom border color is changed to white.
The grouped selector is more complex, so I’ll start by explaining the first contextual selector, which is
#homePage #homePageLink a:link. What this means is, “Apply the declaration to the link within an element
with an id of homePageLink that’s in an element with an id of homePage.” In the page you’ve been working
on, the body element has an id of homePage, and the first list element in the unordered list has an id of
homePageLink. Therefore, the link within this list item is automatically given the style, making it look like the
active tab (since the background blends directly into the content area).
The other selectors in the grouped selector behave in the same way (in each case for the link and
visited styles); so if, for example, you change the id value of the body start tag in the HTML document to
customerSupportPage and then refresh the web page, you’ll see the third link become the active tab.
Graphical navigation with rollover effects
Working with text and CSS alone is fine, but designers are creative types and tend to like working with
graphics. Many enjoy creating more visually arresting navigation bars, which make use of imagery and
rollovers. Historically, such systems have required a number of images (three or more per tab) and the use
of JavaScript. However, it’s possible to use CSS, the same unordered list as used for the previous two
exercises, and just a single image to create a graphical navigation bar, as shown in the next exercise.
Using CSS backgrounds to create a navigation bar
Required files
image.gif from
The graphical-navigation-starting-point folder and css-tab-rolloverthe navigation-images folder in the chapter 5 folder
206
www.freepdf-books.com
Using Links and Creating Navigation
What you’ll learn
Completed files
How to create a graphical navigation bar with four different states, driven by CSS,
without using any JavaScript
The graphical-navigation-bar folder in the chapter 5 folder
For this exercise, graphical tabs will be created, using a single GIF image that contains four variations on
the graphic: three are for link states for which styles will be defined (active, hover, and then link and
visited, which share an image); the other is to flag the current page. By applying this image as a
background to links and then amending its vertical positioning on each state, only the relevant portion of
the image will be shown. This technique is called CSS sprites and is used to limit the number of files that
have to be loaded into your page. This is great for updating a site (you need to amend only a single image)
and also from a bandwidth standpoint (one image deals with every tab and every state—no need for
preloading anything), and it’s easy to implement.
1. Edit the body element. Like in the previous exercise, edit the body start tag, adding the id value
shown.
2. Style the structural divs. This page’s structure is simple, as are the CSS rules required to style it.
The #wrapper rule sets a fixed width (which is four times the width of one of the tabs) and centers
the design in the browser window. The #masthead rule adds some padding at the top of the
masthead, so the tabs won’t hug the top of the browser window.
The #navContainer rule has a bottom border (to firmly separate the navigation from the other page
content) and a defined height, which is the height of a tab. The height setting is useful, because these
tabs will be floated, meaning they’re outside of the standard document flow. By giving the container a fixed
height, the border is shown in the right place; without the height definition, the border would be displayed
at the top of the navContainer div, because as far as browsers are concerned, floated elements
technically don’t take up any height within the standard document flow.
207
www.freepdf-books.com
Chapter 5
Finally, the #content rule gives that area a background color and some padding.
#wrapper {
width: 740px;
margin: 0 auto;
}
#masthead {
padding-top: 20px;
}
#navContainer {
height: 30px;
border-bottom: 5px solid #ad3514;
}
#content {
padding: 10px;
background-color: #eeeeee;
}
3. Remove the default bullet points from the list items by adding the following rule:
#navigation ul {
list-style-type: none;
}
4. Style list items. Items within the list are styled to float left. The background value includes the
location
of
the
rollover
image,
with
additional
settings
being
no-repeat (to stop it from tiling), and then 0 and 0, to ensure the relevant portion of the rollover
image is seen by default. The width and height values are the same as that of the image: 185px
and 30px, respectively.
#navigation li {
float: left;
background: url(css-tab-rollover-image.gif) no-repeat 0 0;
width: 185px;
height: 30px;
}
5. Next, style the links. The text is rendered in white, in uppercase, and in Arial, and the default
underlines are removed. Setting display to block makes the entire link container into an active
link, thereby making the navigation bar work in the traditional manner (rather than just the text
being active). Finally, the padding settings position the text correctly over the background images.
208
www.freepdf-books.com
Using Links and Creating Navigation
The height setting, combined with the padding top setting of 9px, adds up to the height of the
container—30px. Without this, the space underneath the text would not be active.
#navigation a:link, #navigation a:visited {
font: bold 1.1em Arial, Helvetica, sans-serif;
text-transform: uppercase;
color: #ffffff;
text-decoration: none;
display: block;
height: 21px;
padding: 9px 0px 0px 30px;
}
6. Style other link states. For the hover and active states, you define which portion of the rollover
graphic is supposed to be visible. This is done via background position values. The first of these
remains 0, because you always want to see the image from its far left. The vertical reading
depends on where the relevant portion of the image appears in the rollover graphic.
If you check css-tab-rollover-image.gif in an image editor, you’ll see the hover state graphic is 40
pixels from the top and the active state graphic is 80 pixels from the top. This means the image needs to
be vertically moved –40 pixels and –80 pixels for the hover and active states, respectively. Therefore, the
rules for these states are as follows:
#navigation a:hover {
background: url(css-tab-rollover-image.gif) 0 -40px;
}
#navigation a:active {
background: url(css-tab-rollover-image.gif) 0 -80px;
}
7. Define the active section state. As per step 8 of the previous exercise, the active state graphic
can be set. In this case, this is done by displaying the fourth state in the rollover image via the
following rule:
#homePage #homePageLink a:link, #homePage #homePageLink a:visited,
#servicesPage #servicesPageLink a:link, #servicesPage
#servicesPageLink a:visited, #customerSupportPage
#customerSupportPageLink a:link, #customerSupportPage
#customerSupportPageLink a:visited, #contactDetailsPage
#contactDetailsPageLink a:link, #contactDetailsPage
#contactDetailsPageLink a:visited {
background: url(css-tab-rollover-image.gif) 0 -120px;
}
Again, you can change the id value of the body element to one of the other list item id values to change
the active section link.
209
www.freepdf-books.com
Chapter 5
Using a grid image for multiple link styles and colors
Required filesThe files from the graphical-navigation-bar folder and
css-rollover-grid.gif from the navigation-images folder in the chapter 5 folder
What you’ll learn
How to amend the previous exercise in order to create a different tab for each
link—still by using a single image
Completed files
The graphical-navigation-bar-grid folder in the chapter 5 folder
Taking
the
previous
exercise’s
completed
files
as
a
starting
point,
along
with
css-rollover-grid.gif, which will be used as the rollover image, you’re now going to have a different tab
for each link. This will be done via more background positioning and by making use of the list item id
values to create rules with contextual selectors specific to each item. Naturally, the rollover image contains
all of the states for the rollover images.
210
www.freepdf-books.com
Using Links and Creating Navigation
1. Amend the list item style. To apply the new background to the list items, amend the #navigation
li rule:
#navigation li {
float: left;
display: inline;
width: 185px;
height: 30px;
background: url(css-rollover-grid.gif) no-repeat 0 0;
}
2. Amend the navContainer div border. Because the tabs are now multicolored, the orange border
at the bottom of the navContainer div won’t look good, so change it to dark gray.
#navContainer {
height: 30px;
border-bottom: 5px solid #333333;
}
3. Set specific background positions. Each tab now requires a separate background position to
show the relevant portion of the background image for each tab. Again, negative margins are
used to pull the image into place in each case. (Because the different colors aren’t obvious in
grayscale, the tabs also have unique icons at the far left.) These rules should be placed after the
#navigation a:link, #navigation a:visited rule.
#navigation #homePageLink {
background-position: 0 0;
}
#navigation #servicesPageLink {
background-position: -185px 0;
}
#navigation #customerSupportPageLink {
background-position: -370px 0;
}
#navigation #contactDetailsPageLink {
background-position: -555px 0;
}
211
www.freepdf-books.com
Chapter 5
4. Edit the active-page state for each tab. The correct portion of the image needs to show when a
tab is the active page, and this is done by replacing the rule from step 6 of the previous exercise
with the following four rules, which should be placed after the rules added in the previous step.
#homePage #homePageLink a:link, #homePage #homePageLink a:visited {
background: url(css-rollover-grid.gif) 0 -120px;
}
#servicesPage #servicesPageLink a:link, #servicesPage
#servicesPageLink a:visited {
background: url(css-rollover-grid.gif) -185px -120px;
}
#customerSupportPage #customerSupportPageLink a:link,
#customerSupportPage #customerSupportPageLink a:visited {
background: url(css-rollover-grid.gif) -370px -120px;
}
#contactDetailsPage #contactDetailsPageLink a:link,
#contactDetailsPage #contactDetailsPageLink a:visited {
background: url(css-rollover-grid.gif) -555px -120px;
}
5. Finally, the two rules for the hover and active states need to be replaced by four rules each—one
for each tab. Again, negative margin values are used to display the relevant portion of the
background image for each state for each image. Add these rules after those from the previous
step.
#navigation li#homePageLink a:hover {
background: url(css-rollover-grid.gif) 0 -40px;
}
#navigation li#servicesPageLink a:hover {
background: url(css-rollover-grid.gif) -185px -40px;
}
#navigation li#customerSupportPageLink a:hover {
background: url(css-rollover-grid.gif) -370px -40px;
}
#navigation li#contactDetailsPageLink a:hover {
background: url(css-rollover-grid.gif) -555px -40px;
}
#navigation li#homePageLink a:active {
background: url(css-rollover-grid.gif) 0 -80px;
}
#navigation li#servicesPageLink a:active {
background: url(css-rollover-grid.gif) -185px -80px;
}
#navigation li#customerSupportPageLink a:active {
background: url(css-rollover-grid.gif) -370px -80px;
}
#navigation li#contactDetailsPageLink a:active {
background: url(css-rollover-grid.gif) -555px -80px;
}
Once again, change the id value of the body element to amend the active section link.
212
www.freepdf-books.com
Using Links and Creating Navigation
CCreating graphical tabs that expand with resized text
Required files The files from the graphical-navigation-bar folder, and the images css-tab-rolloverimage-left.gif and css-tab-rollover-image-right.gif from the navigation-images folder from the chapter 5 folder
What you’ll learn
Completed files
How to amend the result from the “Using CSS backgrounds to create a navigation
bar” exercise, enabling the tabs to expand, resizing with their content
graphical-navigation-bar-sliding-doors in the chapter 5 folder
With both of the graphical tab exercises so far, there is a problem: when the text is resized, the tabs don’t
resize with it.
This can be dealt with using a technique typically referred to as “sliding doors.” This requires two images in
place of the original background image tab—one for its left part and one for the right part, with enough
vertical repetition to expand horizontally. With wider links, more of the right image will be displayed.
213
www.freepdf-books.com
Chapter 5
Note that the increase in flexibility in this method is only horizontal. If you need more
flexibility vertically, increase the height of each “state” in the graphical tabs, remove the
height values from both #navigation li and #navigation a:link, #navigation a:visited, and add
a padding-bottom value to the latter of those two rules.
1. Amend the list. To the list items, apply the css-tab-rollover-image-left.gif background image,
and add a padding-left value that’s the same width as the image. This provides the left side of
each tab. The reason for the padding value is so that the right side of the tab (applied to the link)
doesn’t overlap the left image.
#navigation li {
float: left;
background: url(css-tab-rollover-image-left.gif) no-repeat 0 0;
padding-left: 30px;
height: 30px;
}
2. Amend the link style. Because the padding at the left of the link is now dealt with by the previous
rule, there’s no need for a padding-left value in #navigation a:link, #n avigation a:visited.
However, because the link now stretches with the content, a padding-right value is required, to
stop the tab content in each case from hugging the edge of the tab. This explains the amended
values for the padding property. For the background property, the image file name is amended,
along with its horizontal position, which is now at the far right (100%).
#navigation a:link, #navigation a:visited {
font: bold 1.1em Arial, Helvetica, sans-serif;
text-transform: uppercase;
color: #ffffff;
text-decoration: none;
display: block;
height: 21px;
padding: 9px 30px 0px 0px;
background: url(css-tab-rollover-image-right.gif) no-repeat 100% 0;
}
214
www.freepdf-books.com
Using Links and Creating Navigation
3. With this technique, the left portion of the tab is no longer an active link. It’s therefore usually
recommended to keep the left image as narrow as possible. In this example, the left image is 30
pixels wide, but this was used to show how to convert a standard graphical navigation bar into
one where the tabs can expand—it’s not recommended for the graphical design of such a
system. However, this means the hover and current page states need amending; otherwise,
there’s no feedback. Therefore, for #navigation a:hover, set text-decoration to underline, and
delete everything else within the rule; and for the large, complex rule at the end, set color:
#fff200; as the sole property/value pair in the declaration.
Creating a two-tier navigation menu
Required files The files from the graphical-navigation-bar folder and the images active-sectiontab-background.gif and sub-navigation-background-tile.gif from the navigation-images folder
from the chapter 5 folder.
What you’ll learn
How to create a two-tier navigation system, with different backgrounds and styles
for each tier. This is another method for dealing with navigation text resizing, and it’s
also useful for larger websites, providing a place for subnavigation.
Completed files
two-tier-navigation in the chapter 5 folder.
1. Edit the body element. In the HTML page, give the body start tag an id value of homePage.
215
www.freepdf-books.com
Chapter 5
2. Add some subnavigation. Open the HTML document and add another list for subnavigation,
directly after the navigation div.
one
two
three
four
five
six
seven
3. Amend the body rule. In the CSS document, edit the body rule to add a dark gray background
color and some padding at the top of the document.
body {
font: 62.5%/1.5 Verdana, Arial, Helvetica, sans-serif;
background: #333333;
padding-top: 20px;
}
4. Style the structural divs—add the following three rules to style the three main structural divs.
Adding a light gray bottom border to the masthead makes the transition between the vibrant
navigation to the black-text-on-white-background content area less harsh.
#wrapper {
width: 750px;
margin: 0 auto;
background-color: #ffffff;
border: 1px solid #555555;
}
#masthead {
border-bottom: 8px solid #cccccc;
}
#content {
background: #ffffff;
padding: 10px;
}
5. Add the following two rules to remove list defaults, center list content, and display list items inline.
#navContainer ul {
text-align: center;
}
#navContainer li {
display: inline;
}
216
www.freepdf-books.com
Using Links and Creating Navigation
6. Style the navigation div and its links. Add the following three rules to style the navigation div
and the links within. The padding settings work as per the earlier exercises in this chapter: again,
the vertical padding must be kept constant between the container and the links, which is why the
vertical padding is being set to 6px in both cases. Note the hover color—a bright yellow, designed
to stand out against both the black background of the main navigation bar and the orange
background of the subnavigation and highlighted tab.
#navigation {
background: #111111;
padding: 6px 0;
}
#navigation a:link, #navigation a:visited {
font: bold 1.2em Arial, Helvetica, sans-serif;
color: #ffffff;
text-decoration: none;
padding: 6px 10px;
}
#navigation a:hover {
color: #ffd800;
}
7. Style the active page link. Using one of those grouped contextual selectors we seem to like so
much in this chapter, set a rule to style the active page link. In this case, a background image is
tiled horizontally and set to sit at the bottom of the links. A background color is also defined,
which is handy for if the text is zoomed—if no background color were defined, the image might
run out, leaving the navigation div’s background color to show through instead. This rule,
however, ensures that the background will always have some color, regardless of the font size.
The color setting itself was taken from the top pixel of the background image, so it blends
seamlessly with said image.
#homePage #homePageLink a:link, #homePage #homePageLink a:visited,
#servicesPage #servicesPageLink a:link, #servicesPage
#servicesPageLink a:visited, #customerSupportPage
#customerSupportPageLink a:link, #customerSupportPage
#customerSupportPageLink a:visited, #contactDetailsPage
#contactDetailsPageLink a:link, #contactDetailsPage
#contactDetailsPageLink a:visited {
background: #28b767 url(active-section-tab-background.gif)
217
www.freepdf-books.com
Chapter 5
0 100% repeat-x;
border-top: 1px solid #ca8d5c;
}
8. Add the following three rules to style the subnavigation. Here, a background image is tiled
horizontally behind the entire subNavigation div, and it works in a similar way to the one used in
step 7, blending into a background color if the text is zoomed, dramatically changing the div’s
height. The border-bottom setting provides a darker base to the navigation, which works better
than having the light gray masthead border directly beneath it. The margin-top setting pulls the
entire subNavigation div up two pixels, which stops the layout from splitting at some levels of text
zoom.
#subNavigation {
margin-top: -2px;
background: #b76628 url(sub-navigation-background-tile.gif) 0 100%
repeat-x;
border-bottom: 1px solid #6b6b6b;
padding: 6px 0;
}
#subNavigation a:link, #subNavigation a:visited
font: bold 1.1em Arial, Helvetica, sans-serif;
color: #ffffff;
text-decoration: none;
padding: 6px 10px;
}
#subNavigation a:hover {
color: #ffd800;
}
As you can see from the following images, this navigation bar deals really well with increased text sizes—
only when the text is absolutely massive does it not work entirely as expected, although, crucially, it still
remains usable.
218
www.freepdf-books.com
Using Links and Creating Navigation
Caution: The subNavigation div in this technique sometimes suffers from the hasLayout
bug in Internet Explorer 6. See Chapter 9 for a method of dealing with hasLayout.
Creating a drop-down menu
Required files
Files from the graphical-navigation-bar folder and drop-down-menu-
background.gif (which is a crop of the list item background image) from the navigation-images folder in the
chapter 5 folder
What you’ll learn
Completed files
How to work with an existing CSS-based navigation menu and convert it into a
drop-down menu
The drop-down-menu folder in the chapter 5 folder
The next type of navigation we’re going to explore in this chapter is the drop-down menu. In part
popularized by operating systems such as Windows and Mac OS, drop-down menus are convenient for
storing plenty of links in a relatively small space. However, use them with caution, because the second tier
of navigation is initially hidden from view, unlike in the previous exercise’s system, where it was visible.
However, with drop-downs, all second-tier navigation is available from the menu.
219
www.freepdf-books.com
Chapter 5
1. Edit the web page. For any link you want to have a drop-down menu spawn from, nest an
unordered list in its parent list item, as per the example in the following code block.
Services
link
link
link
link
one
two
three
four
2. Create the drop-downs. Test your page now, and it will look odd because nested list items pick up
the styles for the standard list items. To start dealing with this, add position: relative; to the
#navigation li rule, which will enable nested absolute-positioned elements to take their top and
left values from their containers rather than the page as a whole. Then, after the existing rules in
the CSS, add the #navigation li ul rule shown in the following code block. By setting position
to absolute and left to a large negative value, the nested lists (in other words, the drop-down
menus) are placed offscreen by default but are still accessible to screen readers. Adding the top
border helps visually separate the nested list from its parent button.
#navigation li ul {
border-top: 1px solid #ad3514;
width: 185px;
position: absolute;
left: -10000px
}
3. Next, add the following rule to bring the nested lists back when you hover the cursor over the
parent list item. Upon doing so, the list item’s descendant list’s display value is set to block, and
it’s displayed directly underneath the parent item.
#navigation li:hover ul
display: block;
left: 0;
}
{
220
www.freepdf-books.com
Using Links and Creating Navigation
4. Style nested list items and links. Add the following rule to replace the default background for list
items with one specifically for the drop-down menus. The border-bottom value visually separates
each of the list items.
#navigation li li {
background: url(drop-down-menu-background.gif) repeat-y;
border-bottom: 1px solid #ad3514;
}
5. Next,
add the following rule to style nested
text-transform and padding values of top-level list items.
list
item
links,
overriding
the
#navigation li li a:link, #navigation li li a:visited {
text-transform: none;
padding-left: 10px;
}
6. The final step is to override the hover and active states. For this example, the background value
for top-level lists is overridden and the background image removed (meaning the hover state for
nested list links has no unique background). To make the hover state stand out, the links are
given a vibrant left border. This also moves the text inward by the width of the border.
#navigation li li a:hover, #navigation li li a:active {
background: none;
border-left: 5px solid #f7bc1d;
}
These property values are common to both states, apart from the border color (orange for the hover state
and red for the active state, roughly matching the colors applied to the top-level tab icons in the same
states, although the orange is brighter for the drop-downs so that they stand out more); therefore, add the
following rule to change only the left border’s color on the active state:
#navigation li li a:active {
border-left-color: #ed1c24;
}
221
www.freepdf-books.com
Chapter 5
Note: If you decide to create drop-down menu–based navigation, avoid copying an
operating system’s menu style, because this may confuse visitors using that operating
system and irritate visitors using a rival system. The exception to this rule is if you’re
creating a site that centers around nostalgia for the days where operating systems used
to come on floppy disks. One such site—an amusing Mac OS System 7 look-alike—can
be found at http://myoldmac.net/.
Creating a multicolumn drop-down menu
Required files
What you’ll learn
The drop-down-menu folder from the chapter 5 folder.
How to create a multicolumn drop-down menu, based on the code from the
previous exercise
Completed files
The drop-down-menu-multi-column folder in the chapter 5 folder
The final example in this chapter is a multicolumn drop-down menu. These are increasingly common,
enabling sites to provide a lot of links in a drop-down that simply wouldn’t fit on the screen if they were
listed vertically. For an example of such a drop-down in action (although one that uses a different method),
visit www.2000adonline.com/books/ and hover over the Books List link.
222
www.freepdf-books.com
Using Links and Creating Navigation
Creating a multi
n drop-down menu
colum
1. Edit the HTML to remove the existing nested lists. Then, for the multicolumn drop-down, decide
which link you want it to spawn from and place an unordered link in its parent list item, with a
single list item of its own. Within that list item, place the unordered lists for the columns in the
drop-down, one after the other. Note that if some columns have fewer items, they must still have
the same number of list items. However, list items can be left empty, despite this technically being
a presentational hack. (Note that HTML Tidy might have problems with this and trim the empty list
items. If you use that tool, add a nonbreaking space as the list’s content.)
Services
link 1.4
link 2.1
link 2.2
link 3.1
link 3.2
link 3.3
2. Next, edit the nested list. The list that contains the three lists that form the columns of the dropdown needs styling. Having larger borders on multicolumn drop-downs is a good idea, because it
enables users to focus on the contents more easily, which is the reason for the amended border
setting in the following code block. The other change is to the width setting, which must be a
multiple of three (here, it’s set to 465px, meaning that each column will be 155 pixels wide). With
multicolumn drop-downs, it’s best to avoid making each column the same width as a tab;
otherwise, the result will look strange.
#navigation li ul {
border: 2px solid #ad3514;
width: 465px;
position: absolute;
left: -10000px
}
3. Now, the list item within the nested list needs amending. For the previous exercise, the
#navigation li li rule dealt with the list items in the drop-down, but here it’s primarily for the
container of the three columns. Therefore, the height and width settings need to be set to auto to
enable the list item to stretch to fit its nested items. The background image is superfluous, so it’s
replaced by a flat color, and the border-bottom pair is removed—the borders will be moved to list
items within the columns.
#navigation li li {
background: #d27448;
height: auto;
width: auto;
}
4. The link rules should be styled next. Since the links are now one level deeper in the list, instances
of li li in the selectors are changed to li li li . In this example, this change isn’t technically
necessary, but it always pays to keep your selectors as precise and accurate as possible. For the
link and visited states, padding settings for the top-level links are overridden, as are width and
224
www.freepdf-books.com
Using Links and Creating Navigation
height settings. For the other states, the border used for the hover and active effects is replaced
by a change in background color. Note that the rule that originally had both the hover and active
states in the selector (#navigation li li a :hover, #navigation li li a:active) now requires
only the hover state (#navigation li li li a:hover ), because the rules have nothing in
common.
#navigation li li li a:link, #navigation li li li a:visited {
text-transform: none;
padding: 10px;
width: 135px;
height: auto;
}
#navigation li
background:
}
#navigation li
background:
}
li li a:hover {
#ad3514; !important;
li li a:active {
#ed1c24;
5. Style the column list items. Add a rule to define a width and height for the column list items, along
with a bottom border. The last of those things makes it easier to scan the rows within the list,
while the width and height settings ensure that the layout isn’t affected if the list items have no
links within. (If the width and height settings were omitted, the list items within the columns would
show their bottom borders only underneath their content’s width—and not at all if they were
empty.) The height setting is defined in ems rather than pixels, because this makes it possible for
the list items to stretch vertically if the web page’s text is resized.
#navigation li li li {
width: 155px;
height: 3em;
border-bottom: 1px solid #ad3514;
}
6. Finally, add a rule to float and define a width for the lists that comprise the containers for the list
items styled in the previous step.
#navigation ul ul ul {
border: 0;
width: 155px;
float: left;
position: relative;
}
225
www.freepdf-books.com
Chapter 5
Note: Although the drop-down examples work in currently shipping browsers, neither
works as is in Internet Explorer 6, because that browser doesn’t enable you to do
anything with the hover state unless it’s on a link. To cater for that browser, JavaScript
must be used as a backup.
The dos and don’ts of web navigation
So, that’s the end of our navigation chapter. Before we move on to working with layout, here are a few
succinct tips regarding designing web navigation.
Do
Use appropriate types of navigation.
Provide alternate means of accessing information.
Ensure links stand out.
Take advantage of link states to provide feedback for users.
Get the link state order right (link, visited, hover, active).
Use styled lists for navigation.
Use CSS and as few images as possible (preferably one) for rollovers.
Don’t
Add search boxes just for the sake of it.
Use deprecated body attributes.
Style navigation links like normal body copy.
Use image maps unless absolutely necessary.
Open new windows from links or use pop-ups.
Use clunky JavaScript for rollovers.
226
www.freepdf-books.com
Chapter 6
Tables: How Nature (and the W3C) Intended
227
www.freepdf-books.com
Chapter 6
In this chapter:
Introducing how tables work
Using borders, padding, and spacing
Creating accessible tables
Enhancing tables with CSS
Designing tables for web page layout
The great table debate
Tables were initially intended as a means of displaying tabular data online, enabling web designers to
rapidly mark up things such as price lists, statistical comparisons, specification lists, spreadsheets, charts,
forms, and so on (the following example shows a simple table, taken from www.infoq.com).
It wasn’t long, however, before web designers realized that you could place any web content within table
cells, and this rapidly led to web designers chopping up Photoshop layouts and piecing them back together
in table-based web pages, often by using automated tools.
The strong will of CSS advocates, who typically shout that tables are evil, sometimes leads designers to
believe that tables should be ditched entirely. However, that’s not the case at all. As mentioned, tables
have a specific purpose in HTML, and it’s one that’s still valid. Therefore, the bulk of this chapter is going
228
www.freepdf-books.com
How Nature (and the W3C) Intended
to look at tables in the context for which they’re intended: the formatting of tabular data. Web page layout
will be looked at in the next chapter, which concentrates on CSS layout.
How tables work
In this section, we’re going to look at how tables are structured and some of the table element’s attributes,
which enable you to define the table’s dimensions and borders, along with the spacing, padding, and
alignment of its cells.
Tabular data works via a system of rows and columns, and HTML tables work in the same way. The table
element defines the beginning and end of a table. Within the table element are table row elements
(), and nested within those are table cell elements (). The actual content is placed
inside the td elements. Therefore, a simple table with two rows containing two cells each is created like
this:
Cell one Cell two
Cell three Cell four
Note: Always ensure that you include all end tags when working with tables. If you
began working with HTML in the mid-1990s, you may have learned that it’s OK to omit
the odd end tag from tables or table cells. However, not only does this result in invalid
XHTML, but some browsers won’t render tables accurately (or at all) when end tags are
omitted. Furthermore, there’s evidence to suggest some search engines can’t properly
index pages that contain broken tables.
Adding a border
You can place a border around table cells by using the border attribute and setting its value to 1 or greater.
The adjacent example shows how this looks in a web browser.
HTML borders for tables have a kind of 3D effect and tend to look clunky and old-fashioned. If you want to
add a border to a table, this is best done in CSS.
Cell spacing and cell padding
In addition to amending the border size, it’s possible to change the amount of padding within a table’s
cells, as well as the spacing between all the cells in a table. This is done with the cellpadding and
cellspacing attributes, respectively. In the rather extreme example that follows, cellpadding is set to 20,
cellspacing to 40, and border to 5, so that each can be differentiated with ease (see the subsequent
229
www.freepdf-books.com
Chapter 6
screenshot). As you can see, cellspacing affects not only the spacing between the cells but also the
distance between the cells and the table’s edges. The CSS property border-spacing is intended to do the
same thing as cellspacing.
Cell one Cell two
Cell three Cell four
You might be thinking that designwise, this example sucks, and you’d be right. The chunk-o-vision 3D
border isn’t particularly tasteful. However, you can omit the border attribute and use CSS to style borders
instead—see the “Styling a table” section later on in this chapter. That section also details how to set
padding in CSS, which provides you with sitewide control over cell padding. CSS also gives you much
finer control over the individual elements in a table—whereas the inline HTML attributes impose a onestyle-fits-all straightjacket.
Spanning rows and cells
It’s sometimes necessary for data to span multiple rows or columns. This is achieved via the rowspan and
colspan attributes, respectively. In the following table, the first row has three cells. However, in the second
row, the first cell spans two rows, and the second cell spans two columns. This means the second row
lacks a third cell, and the third row also has only two cells (whose contents align with the second and third
cells of the top row). See the following screenshot of the table to help make sense of this.
230
www.freepdf-books.com
How Nature (and the W3C) Intended
A cell
Another cell
Yet another cell!
A cell that spans two rows
A cell that spans two columns
Another cell
The last cell
Note: In the preceding HTML, the cell elements are indented to make it easier for you to
make them out. This wasn’t done earlier in the chapter. Either method of writing markup
is fine—it’s up to you. Note, however, that if you use images within table cells, this extra
whitespace in the HTML sometimes causes layouts to break and must therefore be
deleted.
Take care when spanning rows or columns with a cell, because it’s easy to add extra cells accidentally.
For instance, in the preceding example, it would be easy to absentmindedly add a third cell to both the
second and third rows—however, doing so appends the extra cells to the end of the table (see the
following example), which looks bad and—more important—makes little structural sense. Also, some
screen readers have difficulty handling such data, often assigning the wrong headers to various pieces of
data (see the “Creating accessible tables” section later in the chapter for information on table headers).
Setting dimensions and alignment
As you can see from the examples so far, browsers by default set cell sizes to the smallest possible values
that are large enough to accommodate the contents and any cell padding settings defined. Although this is
suitable for the majority of purposes, designers tend to want more visual control over layouts.
Longtime designers may be well-versed in the practice of using height and width attributes to control table
and cell dimensions, but beware. The width attribute is fine to use on table start tags (the possible values
of which are a number denoting the width in pixels of the table, and a percentage, which is a percentage of
the parent element’s size). However, the height attribute is nonstandard and fails in many web browsers,
which might come as something of a shock to those people who enjoy centering content in a browser
window by using a table. On the other hand, the CSS height property works as expected.
Take care when using visual web design applications: many of them add deprecated
elements to tables if you manually drag the cells around. Use your favored application’s
preferences to turn off this feature; otherwise, you’ll end up with obsolete and redundant
markup.
231
www.freepdf-books.com
Chapter 6
Vertical alignment of table cell content
If you set your table’s width to a small value or if you have a lot of
content in one cell and relatively little in an adjacent one, something else
becomes apparent: web browsers vertically align content in the middle of
cells. (Generally, horizontal alignment is, as with other text, to the left.)
See the image on the right for an example.
Historically, designers have used the valign attribute to override this
vertical-centering behavior—the attribute can be added to a row or cell
start tag and set to top: valign="top". Other values are middle (the
default) and bottom, the results of which are shown in the adjacent
screenshot.
The problem with valign is that it’s presentational markup and shouldn’t
really be used; in fact, because it’s an obsolete attribute—which means it can’t be used if you’re creating
proper HTML5—you should instead work with the CSS alternative, the vertical-align property, which
provides practically identical results.
As an example of vertical-align in use, say you wanted all cells within a table that had a class value of
priceList to be vertically aligned to the top; you could add the following rule to your CSS:
table.priceList td {
vertical-align: top;
}
This results in the same effect as valign="top", as discussed earlier. Likewise, you can set the verticalalign property to middle, bottom, and various other values, as outlined in Appendix D.
That’s pretty much where many web designers leave tables; however, there are other elements and
attributes that should be used when creating tables, which will be covered in the following sections.
Creating accessible tables
Many web designers ignore all but the most basic elements when working with tables, and in doing so they
end up with output that causes problems for screen readers. By correctly and carefully structuring and
formatting a table, not only will users of screen readers benefit, but you as a designer will also have far
more control over its visual appearance. Additionally, extendable browsers like Firefox can also enable you
to use the table data in other ways, including outside of the browser. For example, the TableTools2 plug-in
(https://addons.mozilla.org/en-US/firefox/addon/tabletools2/) enables sorting, filtering, and
exporting of tabular data from a web page. A properly formatted table will enhance this, making the table
even more useful. Adding a few extra elements and attributes to your table is a win-win situation, and it’s
surprising to note how few designers bother with anything other than rows and cells in their tables.
232
www.freepdf-books.com
How Nature (and the W3C) Intended
Captions and summaries
Two seldom-used table additions that enable you to provide explanations of a table’s contents are the
caption element and the summary attribute. The former is usually placed directly after the table start tag
and enables you to provide a means of associating the table’s title with the table itself. Obviously, this also
helps users—particularly those with screen readers. After reading the caption, the screen reader will go
on to read the table headers (see the “Using table headers” section later in this chapter). Without the
caption, the table’s contents might be relatively meaningless.
By default, most browsers center captions horizontally, and some set their contents in bold type, but these
default styles can be overridden with CSS.
The summary attribute, which is invisible in browsers, is used by screen readers to give the user an
overview of the table’s contents prior to accessing the content. The contents of the summary attribute
should be kept succinct, highlighting the most important aspects of the table contents, letting the user
know what to anticipate.
Many suggest that summaries should be included on all tables, but this isn’t necessarily the case. A
summary should be used only when it performs the task for which it’s designed: to make available a
succinct summary of data within a table. Should you be using tables for layout (which I don’t recommend),
there’s little point including summaries within each layout table. After all, someone using a screen reader is
hardly going to jump for joy upon hearing, for the umpteenth time, “This table is used for laying out the web
page.” Summaries should save time, not waste it.
Using table headers
The table header cell element () performs a similar function to the standard table cell but is
useful with regard to accessibility. Imagine a long data table comprised solely of standard cells. The first
row likely contains the headers, but because they’re not differentiated, a screen reader might treat them as
normal cells, read them once, and then continue reading the remainder of the data. (If it doesn’t do this, it
still has to assume which cells are headers, and it might guess wrong.) When using table headers, the data
is usually read in context (header/data, header/data, and so on), enabling the user to make sense of
everything. Things can be sped up slightly by using the abbr attribute—long table headers can be cut
down, reducing what needs to be repeated when a table’s data is being read. An example of table header
cells and a row of data cells follows:
CountryCapital city
FranceParis
In this case, a screen reader should read the headers and then provide them with the data of each cell
(Country: France, Capital: Paris, and so on). But even with screen-based browsers, the inclusion of
headers proves beneficial for users, because table header cell content by default is styled differently from
data cell content, meaning the two cell types can be easily differentiated.
Although headers are often at the top of a table, they may also be aligned down the left side. Therefore,
you also need to specify whether the header provides header information for the remainder of the row,
233
www.freepdf-books.com
Chapter 6
column, row group, or column group that contains it. This can be done with the scope attribute, which is
added to the table header start tag and given the relevant value (row, col, rowgroup, or colgroup). It’s also
possible to use the headers attribute in conjunction with id values. See the following “Scope and headers”
section for more information.
Row groups
Row group elements are almost never used, the main reason being a supposed lack of browser support.
The three possible row group elements—, , and —
enable browsers to support the scrolling of the body area of long tables, with the head and foot of the table
remaining fixed. Furthermore, when tables are printed, the aforementioned elements enable the table head
and foot to be printed on each page.
Although browser support comes up short in some areas, we still recommend using row groups, because
they encourage you as a designer to think about the structure of the tables you’re creating. Also, although
browsers don’t do all they might with the elements, they still recognize them, which means they can be
used as selectors in CSS, enabling you to set separate styles for the head, body, and foot data.
When using row groups, you can have one or more tbody elements and zero or one thead and tfoot
elements. They should be ordered with the head first, foot second, and body/bodies third, thereby enabling
the browser to render the foot prior to receiving all of the data. Note, however, that despite this order in
HTML, browsers visually render the row groups in the order you’d expect: head, body, and foot.
Scope and headers
Although table header cells provide a means of differentiating headers and other data, a direct means of
associating one with the other can be added via the use of various attributes. For simple data tables, the
scope attribute, added to table headers, provides an indication of which data a heading refers to. For
example, in the previous code block, the table is oriented in columns—the headers are above their
associated data. Therefore, adding a scope attribute to the header cells, with a value of col, clearly defines
this relationship, and this is something that comes in handy for screen readers.
CountryCapital city
FranceParis
If the alignment of the table were changed, with the headers at the left, the row value would instead be
used.
CountryFrance
Capital cityParis
Note that if a table header contains colspan or rowspan attributes—for example, if a header, such as food,
spanned two columns (thereby having the attribute/value pair colspan="2") and had underneath two
further headings, such as fruit and vegetables— you could set scope="colgroup" in the table header
start tag. The equivalent is true for headers with a rowspan attribute, whereupon the scope value changes
to rowgroup. In such cases, you also need to use the colgroup/rowgroup elements.
234
www.freepdf-books.com
How Nature (and the W3C) Intended
These are positioned between the caption and thead of the table (see the following code, and see the
following section for an overview of the various structural elements of tables combined).
Fruit
Vegetable
Citrus
Berry
Root
Legume
For more complex tables that have intricate structures, using many colspans or rowspans, where it
wouldn’t be immediately obvious where the relationship lies between a data cell and a header, you can
use id values and the headers element. Each table header cell should be assigned a unique id value.
Each table data cell that refers to one or more headers requires a headers element. The value of the
headers element is the id or ids that the cell data refers to. Even for simpler data tables, this method can
work well—see the following code block for how our fruit and vegetables table snippet works with id and
headers.
Fruit
Vegetable
Citrus
Berry
Root
Legume
Lemon
Blueberry
Potato
Pea
235
www.freepdf-books.com
Chapter 6
Note that the code blocks in this section are here to highlight the attributes and elements being
discussed—they should not be seen as examples of complete tables.
Building a table
You’re now going to build a table, taking into account all of the information mentioned so far. This will be
based on an iTunes playlist.
As you can see from the screenshot, the playlist lends itself well to being converted to an HTML table. At
the top is the table head, which details each column’s data type (song name, time, and so on). And
although there’s no table foot, you can simply add some information regarding whose choice of music this
is—something of a signature—although the table foot can also be used to provide a succinct summary of
the table’s contents, akin to the value of the summary attribute discussed earlier.
Building the table
Required files
What you’ll learn
Completed files
XHTML-basic.html from the basic-boilerplates folder as a starting point, along
with building-the-table-body.txt from the chapter 6 folder
How to create a table
building-the-table.html in the chapter 6 folder
236
www.freepdf-books.com
How Nature (and the W3C) Intended
1. Structure the table element. To emulate the structure of the iTunes playlist, set the table’s width
to a percentage value. This means the table will stretch with the browser window. As explained
earlier, you should also use the summary attribute to succinctly detail what the table is all about.
Strictly speaking, the border attribute should be omitted. However, prior to adding CSS
rules, it’s a handy way to more prominently show the table’s structure in a browser. Note
also the use of cellspacing—without this, most browsers place gaps between the table
cells of unstyled tables.
2. Add a caption. Immediately after the table start tag, add a caption element to provide the table
with a title.
A playlist of great music
3. Add the basic table structure. Use row groups to provide the table with its basic structure.
Remember that row groups must be added in the order outlined in the previous “Row
groups” section.
4. Using table header cell elements, add the content for the table head (the column headers) as in
the following code block, remembering to include relevant scope attribute/value pairs:
Song Name
Time
Artist
Album
Play Count
There’s no need to add any styling—not even strong tags. By default, most browsers display table header
cell content in bold (and centered) to differentiate it from table data; also, in the following section, you’ll be
using CSS to style everything, anyway.
237
www.freepdf-books.com
Chapter 6
Note: It’s always best to keep your HTML as simple as possible and do any styling in
CSS. This reduces page load times and means that you have a greater degree of
control. It also means that people without the ability to view CSS see the browser
defaults, which are sensible and clear.
5. Add table foot content. As mentioned, the footer for this table is to essentially be a signature,
stating who’s at fault for this selection of music. Because this is a single line of text that could
potentially span the entire table width, simply include a single table cell, set to span five rows
(using the colspan attribute).
Music selection by:
www.snubcommunications.com
6. Add table body content. Finally, add the table’s body content via the usual method, using table
row and table cell elements. This table will have nearly 20 rows, so to save on trees, only the first
two rows are detailed in the following printed code block—you can add all the others in the same
way, or just copy across the content of building-the-table-body.txt from the download files, to
save inputting the data yourself.
In The Art Of Stopping
3:34
Wire
Send
3
Electron John
3:18
Worm Is Green
Push Play
42
Tip: Take care that your table body content aligns correctly with your table headers.
Badly formed tables are one thing, but when the headers and data don’t correlate, the
table is useless.
The following image shows the table so far.
238
www.freepdf-books.com
How Nature (and the W3C) Intended
This table is not pretty, but it’s structurally sound, and it includes all the relevant elements to at least help
make it accessible. As you can see, the addition of the caption and table header cells also makes a
difference. If you’re unsure of this, look at the following screenshot of the same table, with plain table data
cells throughout and no caption.
All the information might be there, but it’s harder to pick out the headers, and users will have to rely on
body copy elsewhere to discover what the data in the table represents.
239
www.freepdf-books.com
Chapter 6
Styling a table
Flip back over the past few pages and you might notice that the table doesn’t exactly bear a striking
resemblance to the iTunes playlist as yet. But then, we’re only halfway through building the table. Now it’s
time to start styling it using CSS.
Adding borders to tables
As mentioned earlier, it’s a good policy to avoid using the default HTML table border. It looks ugly and oldfashioned, and it’s a far cry from a clean, flat, 1-pixel border. You might think it’s a straightforward process
to add CSS borders to a table—logically, it makes sense to simply add a border property/value pair to a
grouped selector that takes care of both the table headers and table data cells.
th, td {
border: 1px solid #c9c9c9;
}
But this doesn’t work. As the screenshot to the right shows, this method results in the
correct single-pixel border around the edge of the table but creates double-thick borders
everywhere else. This is because the borders don’t collapse by default, meaning that the
right border of one cell sits next to the left border of an adjacent cell, and so on.
Designers have historically gotten around this by using a rule to define a style for the top
and left borders of the table and another to define a style for the right and bottom borders
of table cells. However, there’s a perfectly good property that deals with the doubleborder syndrome: border-collapse. When this property, with a value of collapse, is
applied to the table element via an element selector, borders collapse to a single border
wherever possible. The other available border-collapse property value, which reverts borders to their
“standard” state, is separate.
table {
border-collapse: collapse;
}
With this brief explanation of table borders completed, we’ll now move into exercise mode and style the
table.
Styling the playlist table
Required files
table-starting-
styling-the-playlist-table-starting-point.html, styling-the-playlistpoint.css, and table-header-stripe.gif from the chapter 6 folder
What you’ll learn
How to style a table
Completed files
chapter 6
styling-the-playlist-table.html and styling-the-playlist-table.css in the
folder (along with the GIF image, which isn’t amended)
240
www.freepdf-books.com
How Nature (and the W3C) Intended
1. Set things up. If they still exist, remove the border, cellpadding, and cellspacing attributes
within the table start tag. Add the universal selector rule (*) to remove margins and padding, as
shown a bunch of times already in this book. Also, set the default font by using the html and body
rules, as detailed in Chapter 3 of this book. Because we’re creating a playlist based on the iTunes
interface, it may as well be a little more Apple-like, which is why we’re using Lucida variants as
the primary fonts. Note that the padding value in the body rule is there to ensure that the table
doesn’t hug the browser window when you’re previewing the page.
* {
padding: 0;
margin: 0;
}
html {
font-size: 100%;
}
body {
font: 62.5%/1.5 "Lucida Grande", "Lucida Sans Unicode", Arial,
Helvetica, sans-serif;
padding: 20px;
}
2. Style the table borders. As per the “Adding borders to tables” section, style the table borders.
table {
border-collapse: collapse;
}
th, td {
border: 1px solid #c9c9c9;
}
3. Style the caption. The borders have been dealt with already, so the next step is to style the
caption, which currently lacks impact. The caption is effectively a title, and titles should stand
out. Therefore, place some padding underneath it, set font-weight to bold, font-size to 1.3em,
and text-transform to uppercase. Note that, in the following code block, CSS shorthand is used
for three values for setting padding; as you may remember from Chapter 2, the three values set
the top, horizontal (left and right), and bottom values, respectively, meaning the caption will have
0px padding everywhere except at the bottom, where the padding will be 5px.
caption {
font-weight: bold;
font-size: 1.3em;
text-transform: uppercase;
padding: 0 0 5px;
}
241
www.freepdf-books.com
Chapter 6
4. Style the header cells. To make the header cells stand out more, apply the CSS rule outlined in
the following code block. The url value set in the background property adds a background image
to the table headers, which mimics the subtle metallic image shown in the same portion of the
iTunes interface; the 0 50% values vertically center the graphic; and the repeat-x setting tiles the
image horizontally. From a design standpoint, the default centered table heading text looks iffy,
which is why we added a text-align property set to left. These settings ensure that the table
header contents stand out from the standard data cell content.
th {
background: url(table-header-stripe.gif) 0 50% repeat-x;
text-align: left;
}
5. Set the font and pad the cells. At the moment, the table cell text hugs the borders, so it needs
some padding; the text is also too small to comfortably read, so its size needs increasing. This is
dealt with by adding font-size and padding pairs to the th, td rule, as shown here:
th, td {
border: 1px solid #c9c9c9;
font-size: 1.1em;
padding: 1px 4px;
}
242
www.freepdf-books.com
How Nature (and the W3C) Intended
6. Style the footer. The footer content needs to be easy to differentiate from the other data cells; you
can achieve this by setting a background color for the entire row within the tfoot element and by
making the color of the text have less contrast. Also, centering the text and making it smaller than
text within the other data cells ensures it doesn’t distract from the main content in the table.
Centering it also provides some balance, because the caption is also centered.
tfoot {
background-color: #dddddd;
color: #555555;
}
tfoot td {
font-size: 1.0em;
text-align: center;
}
In Chapter 3, we warned against using text with low contrast against a background
graphic. In the case of the table’s footer in this exercise, the contrast is lower than for
other text, but it’s still readable; also, the content is not a huge chunk of body copy— it’s
only a single line of text.
Adding separator stripes
One of iTunes’s best visual features (and something seen in usable tables all over the Internet, but more
often in print and in applications) is missing from the completed table: colored separator stripes, which
assist you in rapidly scanning rows of data. Although you could conceivably add a class (setting a
background color) to alternating rows, such a solution is poor when creating a static site—if you had to add
243
www.freepdf-books.com
Chapter 6
a row in the middle of the table, you’d need to update every subsequent table row start tag, which is hardly
efficient.
David Miller’s article “Zebra Tables” on A List Apart (see www.alistapart.com/articles/zebratables/)
offers a far more elegant solution. This was later reworked by Matthew Pennell
(www.thewatchmakerproject.com),
whose
article
“Stripe
Your
Tables
the
OO
Way”
(www.thewatchmakerproject.com/journal/309/stripe-your-tables-the-oo-way) offers the lowdown on
his technique, including an improved version of his script at www. thewatchmakerproject.com/zebra.html.
Applying separator stripes
Required files styling-the-playlist-table.html, styling-the-playlist-table.css, tableheader-stripe.gif,
and styling-the-playlist-table-stripes.js from the chapter 6 folder
What you’ll learn
How to add separator stripes to a table
Completed files styling-the-playlist-table-stripes.html and styling-the-playlist-tablestripes.css in the
chapter 6 folder (along with the GIF image and JavaScript document, neither of which
is amended)
1. Link to the JavaScript document. Taking things up from the completed table from the previous
exercise (also available in the download files as styling-the-playlist-table.html and stylingthe-playlist-table.css), add a script element in the HTML document’s head section to link to
the JavaScript file styling-the-playlist-table.js. Note that the JavaScript document is also
available in the download files.
2. Give the table a unique id. For the script to do its work, the table start tag must be given a
unique id value. This must match the value given in styling-the-playlist-table.js in the
onload function. Therefore, add the id attribute and value shown in the following code block:
3. In the JavaScript, the relevant code that matches this is already defined, as shown in the
following code block:
window.onload = function() {
zebraTable.stripe('playlist1');
}
4. Assign a separator stripe style. The script creates alternating table rows, which are given a class
value of alt. This can then be styled in CSS by using a rule with the selector tbody tr.alt td:
244
www.freepdf-books.com
How Nature (and the W3C) Intended
tbody tr.alt td {
background: #e7edf6;
}
5. The previous code block styles the background of alternate rows in a light blue.
6. Define a table row hover state. The script also provides a hover state, making it easy for users to
highlight entire table rows by placing the mouse cursor over one of the row’s cells. This is styled
using the rule shown in the following code block. Note that both background and color settings
are defined, which pretty much reverse the standard colors (white on blue, rather than black on a
light color). This makes the highlighted row stand out more and is the same device applications
tend to use. Also note that there are two selectors here. The first is for compliant browsers, which
apply :hover rules to more than just anchors. The second is a fallback for older versions of
Internet Explorer (before version 7), which didn’t do this.
tbody tr:hover td, tbody tr.over td {
background: #5389d7;
color: #ffffff;
}
7. Remove some horizontal borders. With the stripes in place, the top and bottom borders of table
cells in the tbody area are now redundant. Therefore, remove them by adding the following rule:
tbody td {
border-top: 0;
border-bottom: 0;
}
Your table should now look like the following image.
245
www.freepdf-books.com
Chapter 6
To add stripes to more tables, just assign each one a unique id value and then add
another line to the window.onload function in the JavaScript document, as per the
instructions in this exercise. For example, if you added a table with an id value of
playlist2, the line of JavaScript to add to the function would be
ZebraTable.stripe('playlist2');.
Adding separator stripes with PHP
If you’re creating a table from data stored in a database, automating separator stripes is a relatively simple
process. After the PHP for retrieving data and the opening table markup (including headers), you add the
following:
$alternate = TRUE;
while ($row = mysql_fetch_object($sqlresult)) :
if($alternate) :
$class = ' class="alt"';
$alternate = FALSE;
else :
$class = "";
$alternate = TRUE;
endif;
echo '
';
echo ' ';
echo '';
echo '';
endwhile;
246
www.freepdf-books.com
How Nature (and the W3C) Intended
This is then followed by the markup to close the table. Note that in this example, the alt class value is
applied to alternate table rows, so the CSS from the previous exercise should still work fine.
Adding separator stripes with the :nth-child selector
CSS3 includes selectors that let us pick out the rows we want to style. The nth-child selector targets
elements in a document tree that have a certain number of siblings before it. Where n is an integer, :nthchild(an+b) would match the element that has an+b-1 siblings before it. In this scenario, n is basically a
counter, b represents the counter’s starting place, and a is the positions of the elements we match after
that.
For the separator stripes, we need to target only odd or even elements:
/* targets even */
tr:nth-child(2n) {
background: #e7edf6;
}
* targets odd */
tr:nth-child(2n+1) {
background: #5389d7;
color: #ffffff;
}
Tables for layout
This section is going to be brief, because you should avoid using tables for layout or even components of a
layout (excepting tabular data, obviously). There are exceptions—for instance, some web designers
consider tables acceptable for laying out forms. However, generally speaking, tables are less accessible
than CSS, harder to maintain and update, are slow to render in browsers, and they don’t print particularly
well. More importantly, once you know how to create CSS-based layouts, you’ll mostly find working with
tables for layout frustrating and clunky.
A common way of creating tabular layouts is to chop up a Photoshop layout and use images to stretch
table cells to the correct size. (As mentioned earlier, table cells expand to the dimensions of their content.)
Many designers then use a 1-pixel invisible GIF89 (often referred to as a spacer or shim) to force content
into position or stretch table cells to a certain size. Because the 1-pixel GIF is a tiny file that’s cached, it
can be used hundreds of times without impacting download times. However, spacer and table layout
usage pretty much destroys the idea of a semantic Web. Because so much of the layout is defined via
inline HTML, updating it requires amendments to every page on the site (which must also be uploaded and
tested in each case), rather than the simple editing and uploading of an external CSS file.
It is possible to combine CSS and tables—something that’s usually referred to as a transitional layout,
although one might argue that the “transition” from tables to CSS layouts should now be considered a
historic event. Such layouts are usually created to ensure layout-based backward compatibility with
obsolete devices. This direction should be taken only when the target audience is known to definitely
247
www.freepdf-books.com
Chapter 6
include a significant number of users of very obsolete browsers and also when the layout is paramount to
the working of the site (rather than just the content). When working on such a layout, there are a few
golden rules:
Avoid nesting tables whenever possible: Although tables can be nested like any other HTML
element, doing so makes for a web page that is slow to render and nightmarish to navigate for a
screen reader. (Obviously, there are exceptions, such as if you need to present a table of tabular
data within your layout table.)
Structure the information on the page logically: When designers use tables (particularly those
exported from a graphics package), they have a tendency to think solely about how the page
looks rather than its underlying code. However, it’s important to look at how the information
appears in the HTML, because that’s how a screen reader will see it. The content should still
make sense with regard to its flow and order even if the table is removed entirely. If it doesn’t, you
need to rework your table. (You can use Opera’s User mode to temporarily disable tables to find
out how your information is ordered without them. Chris Pederick’s Web Developer toolbar for
Firefox [www.chrispederick.com/work/web-developer/] offers similar functionality via
Miscellaneous ⌂ Linearize Page.) Ensure that content is immediately available; if it isn’t,
provide a link that skips past extraneous content, such as the masthead and navigation—
otherwise, people using screen readers will be driven bonkers. (See www.w3.org/TR/WAIWEBCONTENT/ for more on web content accessibility guidelines.)
Avoid deprecated attributes: For instance, there’s little point in setting the table’s height to 100%
when many web browsers ignore that rule (or need to be in quirks mode to support it).
Use CSS whenever possible to position elements: To give an example—if you’re working with a threecell table and want the middle cell’s content to begin 100 pixels from the top of the cell, don’t use
a spacer GIF. Instead, provide the cell with a class or unique ID, and use CSS padding.
Note: The last two of these rules are primarily concerned with ensuring that if you design
for legacy browsers, you don’t compromise your work for more modern efforts.
As we keep hammering home, CSS is the way to go for high-quality, modern web page layouts, and tables
should be left for the purpose for which they were designed—formatting data. The arguments that rumbled
on for a few years after the 1990s came to a close—that browsers didn’t support enough CSS to make
CSS layouts possible and that visual design tools such as Dreamweaver couldn’t cope with CSS layouts—
are now pretty much moot. Even the previous major release of the worst offender (yes, we’re talking about
Internet Explorer 6) has more than adequate support for the vast majority of CSS layouts, and anything
shipping today is more than capable of dealing with CSS.
Having said that, in March 2011, the W3C HTML Working Group decided that designers may put
role=presentation on a table element so it can be used (in a conforming way) for presentational purposes
(http://lists.w3.org/Archives/Public/public-html/2011Mar/0245.html).
248
www.freepdf-books.com
Chapter 7
Page Layouts with CSS
In this chapter:
Explaining CSS workflow
Positioning web page elements with CSS
Creating boxouts and sidebars
Creating column-based layouts
Amending layouts, depending on body class settings
249
www.freepdf-books.com
Chapter 7
Creating scrollable content areas
Layout for the Web
Although recent years have seen various institutions offer web-oriented courses, the fact remains that
many web designers are not “qualified” per se. What I mean by this is that plenty of them have come from
some sort of design or technology background related to—but not necessarily a part of—the Web.
Therefore, we often see print designers moving over to the Web through curiosity or sheer necessity and
technologists dipping their toes into the field of design.
This accounts for the most common issues seen in web layouts: many designers coming from print try to
shoehorn their knowledge into their website designs, despite the Web being a very different medium from
print. Conversely, those with no design knowledge lack the basic foundations and often omit design
staples. Even those of us who’ve worked with the Web almost from the beginning and who also come from
a design or arts background sometimes forget that the best sites tend to be those that borrow the best
ideas from a range of media and then tailor the results to the desired output medium.
In this section, we’ll take a brief look at a few layout techniques: grids and boxes, columns, and fixed vs.
liquid design.
Grids and boxes
Like print-oriented design, the basis of web page design tends to be formed from grids and boxes.
Regardless of the underlying layout technology (previously, tables; then, CSS; and now HTML5 and
CSS3), web pages are formed of rectangular areas that are then populated with content.
Grid layouts can add visual rhythm to guide your user’s eye, making your design look clean and ordered,
and provide consistency. They enable stability and structure into which you can easily drop new elements
and rearrange existing ones without the time and energy it would take to do so in a nongrid layout.
A grid is a division of layout with vertical and horizontal guidelines that incorporate margins, spaces, and
columns for organizing your content. The grid container should be evenly divisible. For example, a 960pixel total width is a good starting point, because it provides a massive amount of scope for divisions (960
is divisible by 2, 3, 4, 5, 6, 8, 10, 12, 15, 16, 20, 24, 30, 32, 40, 48, 60, 64, 80, 96, 120, 160, 192, 240, 320,
and 480).
That said, too many columns can result in excessive complexity, so when working on initial grid designs,
stick to about a dozen columns. The reason for working with 12 columns (rather than, say, seven or ten) is
because of the flexibility it affords you in being able to divide the layout evenly (2 x 6, 3 x 4) and also in
various other combinations.
A good rule of thumb for web design is to keep things relatively simple. Plan the layout on paper prior to
going near any design applications, and simplify the structure as much as possible. Always design with
mobile and legacy browsers in mind, and use progressive enhancement to add the advanced styles
supported by desktop browsers. A typical web page contains as few as three or four structural areas (such
250
www.freepdf-books.com
Page Layouts with CSS
as masthead, navigation, content, and footer areas), which can then be styled to define their relationship
with each other and the page as a whole.
Working with columns
The vast majority of print media makes heavy use of columns. The main reason for this is that the eye
generally finds it easier to read narrow columns of text than paragraphs that span the width of an entire
page. However, when working with print, you have a finite and predefined area within which to work, and
by and large, the “user” can see the entire page at once. Therefore, relationships between page elements
can be created over the entire page, and the eye can rapidly scan columns of text.
On the Web, things aren’t so easy. Web pages may span more than the screen height, meaning that only
the top portion of the page is initially visible. Should a print page be translated directly to the Web, you may
find that some elements essential for understanding the page’s content are low down the page and not
initially visible. Furthermore, if using columns for text and content, you may end up forcing the user to
scroll down and up the page several times.
Therefore, web designers tend to eschew columns—but let’s not be too hasty. It’s worth bearing in mind
something mentioned earlier: the eye finds it tricky to read wide columns of text. Therefore, it’s often good
practice to limit the width of body copy on a website to a comfortable reading width. Also, if you have
multiple pieces of content that you want the user to be able to access at the same time, columns can come
in handy. This can be seen in the following screenshots from the Smashing Magazine website
(www.smashingmagazine.com/about/).
As you can see, the main, central column of the About page provides an overview of the website. To the
right is the sitewide search and multiple advertisements; and to the left is a sidebar that contains the main
and subnavigation for the website. This provides text columns that are a comfortable, readable width and
enables faster access to information than if the page content were placed in a linear, vertical fashion.
251
www.freepdf-books.com
Chapter 7
Fixed vs. fluid
As already mentioned in this book, the Web is a unique medium in that end users have numerous different
systems for viewing the web page. When designing for print, the dimensions of each design are fixed, and
although television resolutions are varied (PAL, NTSC, HDTV), those designing for the screen work within
a fixed frame—and regardless of the size of the screen, the picture content is always the same.
On the Web, there is an endless supply of new browser dimensions and resolutions, from a tiny mobile
screen at 320px to a high-definition 1080p widescreen monitor at 2560px or higher. This presents a web
designer with many challenges, and the decision to use one layout over another should be determined by
the capabilities of the devices used by your target audience.
Later in the chapter, you’ll see various methods for creating strict, fixed-layout skeletons; liquid designs;
and combinations of the two. Some of these will then be turned into full-page designs in Chapter 10.
Fixed layouts
A fixed-width layout is a static layout whose width is set to a specific value, in pixels. Fixed-width sites are
beneficial in that they enable you to position elements exactly on a web page, and its proportions remain
the same no matter what the user’s browser resolution is. However, because they don’t expand with the
browser window, fixed-width sites restrict you to designing for the lowest common screen size for your
intended audience, meaning that people using larger resolutions see an area of blank space (or a
background pattern).
Fixed-width websites are easier to design and maintain, since you translated what you designed on paper
to the screen. They give the designer greater control over how content is floated, they allow for planned
whitespace, and they are more predictable since the layout doesn’t change when the browser is resized.
While the fixed-width layout is the most common layout used on the Web today, it is not ideal for the
modern Web since it doesn’t take advantage of the available space in the browser window and it won’t
adapt to the smaller browser dimensions and resolution of mobile devices, making it extremely difficult to
read and navigate your content.
Fluid layouts
A fluid or liquid layout is designed by using percentage-based widths so that the design can adapt to the
dimensions of the browser. These layouts take more time and energy to plan, because you need to
foresee issues that might happen at each browser dimension you want to support. The benefit of a fluid
design is that it’s irrelevant what resolution the end user’s machine has—the design stretches to fit. The
drawback is that when designing, you have to be mindful that web page elements move, depending on
each end user’s monitor resolution and/or browser window size. You therefore cannot place elements with
pixel-perfect precision.
Fluid layouts can mix fixed and percentage width columns to create unique configurations with the goal
being to display as much horizontal content as you can fit on the screen.
252
www.freepdf-books.com
Page Layouts with CSS
Logical element placement
Besides the ability to rapidly edit CSS-based layouts, the greatest benefit when using CSS is the emphasis
on accessibility, partly because it encourages the designer to think about the structure of the document
and therefore logically plazce the elements within the web page (first comes the masthead, then the
navigation, then the content, and so on). Each element is then styled to suit.
The logical placement of each element in the web page’s structure results in improved document flow. And
if you’re scratching your head, wondering what on Earth I’m talking about, let me explain. A web page
should still make sense if you remove all formatting and design elements. This is how a screen reader
sees the page—it simply reads from the top of the HTML page downward. While some newer screen
readers can interpret some CSS, it is still best to assume that they can’t. This is because the capabilities of
screen readers varies greatly, and how they interpret some CSS values can cause them to behave
incorrectly. When working with CSS, the structure of the web page isn’t compromised.
Workflow for CSS layouts
This section—and, indeed, much of this chapter—shows how straightforward creating CSS layouts can be,
so long as you carefully plan what you’re going to do. Upon working through the chapter, the benefits of a
CSS-based system will become obvious, including the following: rapidly editing a website’s entire visual
appearance from a single, external file; fine-tuning the placement of elements; and creating flowing,
accessible pages.
Creating a page structure
We’ve covered semantic markup—that is, using HTML elements for the purpose for which they were
created. This theme continues when working with CSS-based layouts. When working with CSS, you need
to be aware of the structure of your web page from the start. That way, you can create structural elements
with id values that relate to their purpose and then style them to suit.
One of the weaknesses of HTML4 and XHTML was that the ability to define the meaning of your content
through your markup was severely limited. In the past, for basic page structure, you would most likely work
with the div element. Custom classes assigned to your div elements defined meaning to your content. The
problem with this solution is that different designers could have a different word for the same thing, such
as header or masthead. This makes it difficult for applications such as search engines to parse your
content and determine its meaning.
While divs are still heavily used for page structure, HTML5 has brought us semantic structural elements
such as header, footer, article, nav, and aside. These tags provide a standard way of defining the meaning
of your content and have been reviewed in detail in Chapter 2.
Box formatting
The box model is mentioned elsewhere in this book (see Chapter 2 and Appendix D), and this is a timely
place for a recap, because the box model is something that confuses some web designers.
253
www.freepdf-books.com
Chapter 7
In CSS, every element is considered to be within its own box, and you can define the dimensions of the
content and then add padding, a border, and a margin to each edge as required, as shown in the following
image.
© Jon Hicks (www.hicksdesign.co.uk)
This is one of the trickiest things to understand about the CSS box model: padding, borders, and margins
are added to the set dimensions of the content, and so the sum of these elements is the overall space that
they take up. In other words, a 100-pixel-wide element with 20 pixels of padding will take up an overall
width of 140 pixels, not 100 pixels with 20 pixels of padding within.
You can force browsers to respect the width you set by applying box-sizing: border-box to all elements:
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
This is supported by all modern browsers without a vendor prefix with the exception of Firefox.
Note that the top and bottom margins on adjacent elements collapse, meaning that the overall box
dimensions aren’t necessarily fixed, depending on your design. For instance, if you set the bottom margin
to 50px on an element and you have a top margin of 100px on the element below it, the effective margin
between the two elements will be 100 pixels, not 150 pixels.
254
www.freepdf-books.com
Page Layouts with CSS
CSS layouts: a single box
In the remainder of this chapter, we’ll walk through a number of common CSS layout techniques, which
can be combined to form countless layouts. In Chapter 10, these skeleton layouts will form the basis of
various full web page layouts, which will also integrate techniques shown elsewhere in the book (such as
navigation bars).
The starting point for any layout is a single box, which this section concentrates on. I typically refer to
these as wrappers (and accordingly provide said divs with an id value of wrapper); you can think of them
as site containers, used to define a width for the site or set a fixed-size design in the center of the browser
window.
Creating a fixed-width wrapper
Required files
What you’ll learn
Completed files
Files from the basic-boilerplates folder as a starting point
How to create a fixed-width div
create-a-fixed-width-wrapper in the chapter 7 folder
things up. Rename the boilerplate documents to create-a-fixed-widthwrapper.html and create-a-fixed-width-wrapper.css. Link the CSS document to the web page
by amending the url value of the style element.
1. Set
2. Add some content. The web page already has a div element with an id of wrapper. Within it, add
a bunch of paragraphs and test the web page. You’ll see that the content stretches with the
browser window and goes right up to its edges—this is a basic liquid design. If the browser
window is very wide, this makes the content all but unreadable.
3. Restrict the wrapper’s width. In CSS, add the following rule:
#wrapper {
width: 600px;
margin: 0 auto;
}
255
www.freepdf-books.com
Chapter 7
The width setting defines a width in pixels for the wrapper div. The margin setting provides automatic
margins to the left and right of the div, which has the effect of centering the layout in the browser window,
as shown in the following screenshot.
Adding padding, margins, and backgrounds to a layout
Required files-Files from add-starting-point in the chapter 7 folder as a starting point
What you’ll learn
Completed files
How to add style to a fixed-width div
add-completed in the chapter 7 folder
1. Add a page background. In the add-starting-point folder, there are two images, both of which
are gradients. One is a black gradient, fading toward gray at its bottom edge; this is intended for a
page background. Add this by adding the following rule to the style sheet (after the add your code
below comment):
body {
background: #4d4d4d url(page-background.gif) repeat-x;
}
2. The repeat-x value ensures that the background tiles horizontally only; the color value #4d4d4d is
the color of the bottom pixel of the gradient image, ensuring the gradient seamlessly blends with
the web page background.
Note that in some examples in this book, selectors are used multiple times, such as body
here, as described in the cascade section of Chapter 1. This is perfectly acceptable,
although if you want to merge rules, you can—just be mindful of the cascade if you do
so.
3. Add a border to the wrapper. Amend the #wrapper rule to add a border around the wrapper. Note
that the wrapper in this example sits flush with the top edge of the browser window view area, so
256
www.freepdf-books.com
Page Layouts with CSS
no top border is needed. That’s why the border-top pair is added, overriding the previous rule for
the top border only.
#wrapper {
width: 600px;
margin: 0 auto;
border: 2px solid #777777;
border-top: 0;
}
4. Add a wrapper background. If you test the page now, the background shows behind all of the
page’s content, thereby making it unreadable. Therefore, add the background pair to the rule,
which sets a background color for the wrapper div and also sets the second image in the addstarting-point folder (a white-to-light-gray vertical gradient) to tile horizontally at the bottom of
the div:
#wrapper {
width: 600px;
margin: 0 auto;
border: 2px solid #777777;
border-top: 0;
background: #ffffff url(wrapper-background.gif) 0 100% repeat-x;
}
257
www.freepdf-books.com
Chapter 7
5. Add some padding. Test the page now, and you’ll see two major layout errors commonly seen on
the Web. First, the content hugs the edges of the div, which makes it hard to read and also looks
cluttered, despite the div being 600 pixels wide. Second, the text at the bottom of the div is
displayed over the gradient—it’s still readable, but it looks a little messy. By adding padding
(more to the bottom edge, to account for the gradient), these issues are dealt with:
#wrapper {
width: 600px;
margin: 0 auto;
border: 2px solid #777777;
border-top: 0;
background: #ffffff url(wrapper-background.gif) 0 100% repeat-x;
padding: 20px 20px 50px;
}
258
www.freepdf-books.com
Page Layouts with CSS
Note that because of the padding and borders added to this div, it now takes up 644
pixels of horizontal space, due to the 20-pixel horizontal padding values and the 2-pixel
borders. To return the overall width to 600 pixels, subtract the 44 pixels from the width
setting, reducing it to 556px.
Creating a maximum-width layout
Required filesFiles from add-completed in the chapter 7 folder as a starting point
What you’ll learn
Completed files
How to create a div with a maximum width
max-width-example in the chapter 7 folder
6. Amend a rule. Replace the width pair in the #wrapper rule with the max-width pair shown
following. This works much like you’d expect: the design works in a liquid manner, up until the
point at which the content area’s width (this does not include the padding and borders) is the
value defined for max-width, whereupon the layout becomes fixed.
259
www.freepdf-books.com
Chapter 7
#wrapper {
max-width: 800px;
margin: 0 auto;
border: 2px solid #777777;
border-top: 0;
background: #ffffff url(wrapper-background.gif) 0 100% repeat-x;
padding: 20px 20px 50px;
}
7. Amend the body rule. At small browser widths, the design fills the browser window. If you still
want some space around the wrapper, even when the browser window is narrow, all you need do
is amend the body rule, adding some horizontal padding.
body {
background: #4d4d4d url(page-background.gif) repeat-x;
padding: 0 30px;
}
Note that it’s possible to use the min-width property to set the minimum width of a div. In
all cases when using max-width and min-width, be sure to test the usability of your design
at a wide range of browser window sizes.
Using absolute positioning to center a box onscreen
Required files
What you’ll learn
Completed files
Files from basic-boilerplates in the chapter 7 folder as a starting point
How to center a div within the browser window
center-a-box-on-screen in the chapter 7 folder
The final exercise in this section shows how to center a box within the browser window, horizontally and
vertically. Note that this kind of layout isn’t particularly flexible, because it needs the containing wrapper to
have a fixed width and height. Therefore, take care when using this device, because if your page has
plenty of content, your users may be forced to scroll a lot.
1. Add a few paragraphs of text to the web page, placing them inside the wrapper div.
2. Add some backgrounds and style the wrapper div.
body {
background: #666666;
}
#wrapper {
background: #ffffff;
border: 4px solid #000000;
padding: 20px;
width: 400px;
height: 300px;
260
www.freepdf-books.com
Page Layouts with CSS
}
3. Position the div. Set the wrapper div’s position value to absolute, and set the top and left
values to 50%. This sets the top-left position of the div to the center of the browser window.
#wrapper {
background: #ffffff;
border: 4px solid #000000;
padding: 20px;
width: 400px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
}
261
www.freepdf-books.com
Chapter 7
4. Use negative margins. Clearly, the div is not positioned correctly as yet, and that’s—as
mentioned in the previous step—because absolute positioning and the top and left values
specify the position of the top left of the element they’re applied to. To place the div centrally,
negative top and left margins are used to pull it into place, the values of which are half the width
or height, depending on the margin in question. For the margin-left value, you need the negative
of half the horizontal space the div takes up, which is found by adding its width, horizontal
padding, and horizontal margin values (4 + 20 + 400 + 20 + 4 = 444), dividing by two (222), and
making the number negative (–222). Similarly, the margin-top value is the sum of the vertical
dimensions (300px height, two lots of 20px padding and two lots of 4px borders, which comes to
344px) divided by 2 and made negative.
#wrapper {
background: #ffffff;
border: 4px solid #000000;
padding: 20px;
width: 400px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -222px;
margin-top: -172px;
}
262
www.freepdf-books.com
Page Layouts with CSS
Note that if you use this kind of layout and have too much content for your wrapper, it
will spill out of it. See later in the chapter for dealing with this issue by creating scrollable
areas for page content.
Nesting boxes: boxouts
Boxouts are design elements commonly used in magazines, but they can, in principle, also be used on the
Web. A boxout is a box separate from other page content that is often used to house images, captions,
and other ancillary information. In magazines, these may be used for supporting text, alternate features, or
magazine mastheads (with contributor information). Online, this enables you to immediately present
content that’s complementary to the main text.
The elements aside and figure are perfect for boxouts. A figure should be used when the content is related
to the main content but is not meant to stand alone without it. An aside should be used when the content
can stand alone without the main content to support it.
In the following screenshot of the HTML5 Rocks website (www.html5rocks.com/en/features/offline), a
boxout is used to house demos of the offline feature, with a link to a page containing the full demo.
263
www.freepdf-books.com
Chapter 7
The float property
Mastering the float property is key to creating CSS-based web page layouts. It enables you to position an
element to the left or right of other web page content, which then wraps around it.
Creating a boxout
Required files Files from boxout-starting-point in the chapter
7 folder as a starting point
What you’ll learn
Completed files
How to create and style a boxout in CSS
boxout-complete in the chapter 7 folder
As mentioned earlier, boxouts can be handy on web pages for displaying
ancillary content simultaneously with the main text (rather than having
supporting text following the main content). Like any other element, a
boxout can also be styled, which is what this exercise will show how to do.
Steps 1 through 3 show you how to create a basic, plain boxout, and step
264
www.freepdf-books.com
Page Layouts with CSS
4 onward shows how to style it. The final boxout will look like that shown in the image to the right: the
corners are rounded; the plain background of the content area darkens slightly at its base; and the heading
is on a colored background with a gradient (not obvious in a grayscale book, but if you check out the
completed files, you’ll see it’s orange) and a white stripe beneath it to help make the boxout’s heading and
content distinct.
1. Examine the web page. Open boxout.html and look at the page’s body content. The content of
the web page is within a wrapper div. The bulk of the page content is a bunch of paragraphs. The
boxout is an aside element with a class value of boxout, and this is placed before the content the
boxout is supposed to float right of. (In other words, by placing the boxout before the other
content, the other content will wrap around it once the boxout is floated.)
2. Style the wrapper and body. The boxout-starting-point folder contains the images from the
“Adding padding, margins, and backgrounds to a layout” exercise earlier in this chapter, so add
the body and #wrapper rules from that exercise to style the page’s general layout.
body {
background: #4d4d4d url(page-background.gif) repeat-x;
}
#wrapper {
width: 600px;
margin: 0 auto;
border: 2px solid #777777;
border-top: 0;
background: #ffffff url(wrapper-background.gif) 0 100% repeat-x;
padding: 20px 20px 50px;
}
3. Position the boxout. To do so, you need to float it right and assign it a fixed width—if no width is
set, the boxout will span the width of its container, which in this case would be the width of the
wrapper div. Margin values at the bottom and left ensure that the boxout doesn’t hug content that
wraps around it.
.boxout {
float: right;
display: block;
width: 180px;
margin: 0 0 20px 20px;
}
265
www.freepdf-books.com
Chapter 7
4. Add a background. As shown earlier, the boxout has a
background, and this is added by applying a CSS gradient to the
boxout that blends into a solid background color. Finally, padding
values are added to ensure that the boxout content doesn’t go
right up to the edge of the background.
.boxout {
float: right;
width: 180px;
margin: 0 0 20px 20px;
padding: 0 10px;
display: block;
background-color: #e1e1e1;
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%,
from(#e1e1e1), to(#b5b5b5));
background-image: -webkit-linear-gradient(top, #e1e1e1, #b5b5b5);
background-image:
-moz-linear-gradient(top, #e1e1e1, #b5b5b5);
background-image:
-ms-linear-gradient(top, #e1e1e1, #b5b5b5);
background-image:
-o-linear-gradient(top, #e1e1e1, #b5b5b5);
}
266
www.freepdf-books.com
Page Layouts with CSS
5. The boxout header now needs styling, which will add the second
part of the background. A contextual selector is used for this,
ensuring that the style applies only to level-two headings within
an element with a class value of boxout. The first three pairs in
the rule style the header font (see Chapter 3 for more on styling
type); a background CSS gradient has been applied as in step 4.
.boxout h2 {
font: bold 1.2em Arial, Helvetica, sans-serif;
text-transform: uppercase;
color: #ffffff;
background-color: #d7932a;
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#e3b46a), to(#d7932a));
background-image: -webkit-linear-gradient(top, #e3b46a, #d7932a);
background-image:
-moz-linear-gradient(top, #e3b46a, #d7932a);
background-image:
-ms-linear-gradient(top, #e3b46a, #d7932a);
background-image:
-o-linear-gradient(top, #e3b46a, #d7932a);
}
6. Position the header. If you test the page, you’ll see that the header has a gap at its left and right.
This is because the header is within the boxout aside, which has 10 pixels of padding on its left
and right edges. By applying negative margins of the same value to the header, the horizontal
space it takes up is increased to span the entire width of the boxout. Some padding is then added
to ensure that the heading text doesn’t hug its container’s edges. Next, the bottom-border setting
shown following adds a single-pixel white line under the header.
.boxout h2 {
font: bold 1.2em Arial, Helvetica, sans-serif;
text-transform: uppercase;
color: #ffffff;
background-color: #d7932a;
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#e3b46a), to(#d7932a));
background-image: -webkit-linear-gradient(top, #e3b46a, #d7932a);
background-image:
-moz-linear-gradient(top, #e3b46a, #d7932a);
background-image:
-ms-linear-gradient(top, #e3b46a, #d7932a);
background-image:
-o-linear-gradient(top, #e3b46a, #d7932a);
margin: 0 -10px 10px;
padding: 5px 10px;
border-bottom: 1px solid #ffffff;
}
7. A final rule styles paragraphs within the boxout, differentiating them from other text.
.boxout p {
font-size: 0.9em;
}
267
www.freepdf-books.com
Chapter 7
Note that because of the way the header’s background is styled, using a CSS gradient that stretches to fill
the available space, there’s no chance of the background running out, even if the page’s text is massively
zoomed (see the following image). Although the vast majority of users will never use such settings, it
always pays to see how well your sites fare when very atypical settings are used in the browser. While
some problems will be tricky to get around, others just require a little lateral thinking, as shown here.
Advanced layouts with multiple boxes and columns
The layouts so far in this chapter have laid the foundation, showing you how to get to grips with creating a
wrapper for site content and then nesting a div within the wrapper, providing a little added scope for
layout. In this section, you’re going to find out how to fashion the basic building blocks of more complex
layouts, working with two and then three or more structural divs, finding out how they can be styled using
268
www.freepdf-books.com
Page Layouts with CSS
CSS. In all cases, try to think in a modular fashion, because the methods for creating the basic building
blocks shown can be combined in many different ways to create all sorts of layouts.
One of the main reasons for working with two structural divs is to create columns on a web page. Although
columns of the sort found in newspapers and magazines should be avoided online, columns can be useful
when you’re working with various types of content. For instance, you may offer current news in one column
and an introduction to an organization in another. Using columns makes both sets of information
immediately available. If a linear layout is instead used, you’ll need to decide which information you want
the user to see first and which information will initially be out of sight. The general principle of columns is
about more than written site content, though. For example, you could use one column to house a vertical
navigation bar and another to contain thumbnail images relating to an article.
Working with two structural divs
In the following exercise, you’ll work with two structural divs, seeing how seemingly small changes to CSS
rules can make a major difference to the layout of the web page. This will highlight the flexibility of web
layouts, showing how quickly you can build pages and also how easy it is to experiment with designs and
make edits and rapid changes should they be required.
Manipulating two structural divs for fixed-width layouts
Required files
What you’ll learn
Completed files
Files from two-divs-starting-point in the chapter 7 folder as a starting point
How to use two structural divs to create various types of fixed-width layouts,
including two-column designs
two-divs-fixed-complete in the chapter 7 folder
1. Examine the code. Open two-divs.html, and you’ll see a simple page layout. A level-one
heading is followed by the first div, with an id value of divOne. This is then followed by a second
div, which has an id value of divTwo. Both divs have a level-two heading and some paragraphs
within. Some initial styles are also in the style sheet, defining the fonts and placing 20 pixels of
padding around the page’s content (via the padding pair in the body rule) so the page content
doesn’t hug the browser window edge.
269
www.freepdf-books.com
Chapter 7
2. Add the background colors. When initially working on CSS layouts and hand-coding, it’s often
useful to apply background colors to your main structural divs. This enables you to more easily
see their edges and how they interact. Therefore, add the following rules to your CSS:
#divOne {
background: #dddddd;
}
#divTwo {
background: #aaaaaa;
}
3. If you test the web page at this point, you’ll see the divs are positioned in a basic linear fashion.
The gap between the two occurs because the paragraphs have margins assigned on their bottom
edges—therefore, the gap is from the margin of the top div’s last paragraphs.
270
www.freepdf-books.com
Page Layouts with CSS
Note that for an actual website, you should use id (and class) values relevant and
appropriate to the content within them, as evidenced by wrapper and boxout earlier in this
chapter. The values of divOne and divTwo are used in this exercise to enable you to
easily keep track of each one.
4. Make the divs flush to each other. By adding padding-bottom values equal to the margin-bottom
value for paragraphs, you can make the div backgrounds flush to subsequent content.
#divOne {
background: #dddddd;
padding-bottom: 1.5em;
}
#divTwo {
background: #aaaaaa;
padding-bottom: 1.5em;
}
271
www.freepdf-books.com
Chapter 7
5. Float the divs to make columns. By adding width values and floating both divs in the same
direction, the divs stack horizontally, thereby creating columns.
#divOne {
background: #dddddd;
padding-bottom: 1.5em;
float: left;
width: 350px;
}
#divTwo {
background: #aaaaaa;
padding-bottom: 1.5em;
float: left;
width: 250px;
}
272
www.freepdf-books.com
Page Layouts with CSS
Note how each div only stretches to fill its content. Later, you’ll find out how to mimic fullheight columns by using a background image (creating what are known as faux
columns).
6. Switch the column order. You can switch the stack direction by amending the float values,
changing left to right. This can be useful for when you want information to be displayed in a
certain order on-screen but in a different order in code. For example, your main content might be
on the right and a sidebar on the left on-screen, but screen readers would go through the main
content before the sidebar.
7. Note that floats start stacking from the edge of their container, which in this case is 20 pixels in
from the browser window edge. For more control over the overall layout, columns can be placed
in a wrapper, which will be discussed later in the chapter.
273
www.freepdf-books.com
Chapter 7
#divOne {
background: #dddddd;
padding-bottom: 1.5em;
float: right;
width: 350px;
}
#divTwo {
background: #aaaaaa;
padding-bottom: 1.5em;
float: right;
width: 250px;
}
8. Add padding and margins. Switch the right values for float back to left, and then change the
padding-bottom properties to padding, adding values for the top and horizontal edges. A marginright setting for #divOne provides a gap between the two divs.
274
www.freepdf-books.com
Page Layouts with CSS
#divOne {
background: #dddddd;
padding: 10px 10px 1.5em;
float: left;
width: 350px;
margin-right: 10px;
}
#divTwo {
background: #aaaaaa;
padding: 10px 10px 1.5em;
float: left;
width: 250px;
}
275
www.freepdf-books.com
Chapter 7
Manipulating two structural divs for liquid layouts
Required files
What you’ll learn
Files from two-divs-starting-point in the chapter 7 folder as a starting point
How to use two structural divs to create various types of liquid layouts, including
two-column designs
Completed files
two-divs-liquid-complete in the chapter 7 folder
This exercise looks at working with liquid rather than fixed layouts. Because of the nature of liquid layouts,
there are some very important differences in method that must be taken into account, as you’ll see.
1. Add backgrounds and padding. As per the previous exercise, add background colors to the two
divs to make it easy to see their boundaries.
276
www.freepdf-books.com
Page Layouts with CSS
#divOne {
background: #dddddd;
}
#divTwo {
background: #aaaaaa;
}
2. Float the divs and set widths. As explained in the previous exercise, setting a width for the two
divs and then floating them both in the same direction enables you to stack them horizontally,
thereby providing columns. Note that in this exercise, we’ll be floating divs only left, but you can
float them right, too. Regarding width values, you must ensure that their sum doesn’t exceed
100%, because otherwise the divs will be wider in total than their container and will display in a
linear fashion, one under the other.
#divOne {
background: #dddddd;
float: left;
width: 40%;
}
#divTwo {
background: #aaaaaa;
float: left;
width: 60%;
}
277
www.freepdf-books.com
Chapter 7
3. Add a margin. In the previous exercise, a margin was included to separate the two divs. This can
be done here, again by adding a margin-right value to #divOne. However, you need to ensure
the overall width of the width and margin values doesn’t exceed 100%. In this example, the
margin is set to 2%, and 1% is removed from each of the two width values to cater for this.
#divOne {
background: #dddddd;
float: left;
width: 39%;
margin-right: 2%;
}
#divTwo {
background: #aaaaaa;
float: left;
width: 59%;
}
278
www.freepdf-books.com
Page Layouts with CSS
4. If you want to add padding to the divs, the method changes depending on the required value. If
you’re adding padding on a percentage basis, you add it in the same way as the margin in step 3,
removing relevant values from the width settings. (For example, if you set the padding to 1% for
both divs, this would mean there would be 1% of padding on each side, so 2% would need to be
removed from each width value to keep the combined width of the two divs under 100%.)
5. However, if you want to add pixel-based padding values, things become a little more complex,
because there’s no way of specifying something like 39% - 20px for a width. The most sensible
workaround is to use nested divs: add a content div within each of the two existing divs, and
then set padding for those nested divs to a pixel value. In HTML, you end up with the following:
279
www.freepdf-books.com
Chapter 7
You then apply a padding value to .columnContent in the CSS.
Note that, clearly, liquid layouts can have widths lower than 100%; this example showed
that percentage because it’s the most common width used for liquid layouts and has the
most problems to overcome. Also, rounding errors can cause problems with liquid
layouts when the width values add up to 100%—see the “Dealing with rounding errors”
section in Chapter 9 for more on this.
Placing columns within wrappers and clearing floated content
The heading of this section is a bit of a mouthful, but it makes sense at this point to combine the two things
it mentions—placing columns within wrappers and clearing floated content—because once you’ve started
working with columns, that’s what you’ll likely next have to do. Placing columns within a wrapper enables
you to position the overall layout (for example, centering it within the browser window) and restrict its width
to a set size in pixels or a liquid measurement. Clearing floated content is an important concept to
understand, because floated content appears outside of the normal document flow; subsequent content
then wraps around floated content. Therefore, float an object left and subsequent content will stack to its
right. Also, backgrounds don’t appear behind floated content if it isn’t cleared and doesn’t contain
nonfloated elements, because browsers consider floated elements to technically take up no height.
Placing columns within a wrapper
Required files
What you’ll learn
Completed files
Files from two-divs-starting-point in the chapter 7 folder as a starting point
How to use two structural divs to create a two-column fixed-width layout, using
both pixel- and percentage-based values
using-wrappers-to-contain-columns in the chapter 7 folder
1. Add a wrapper. Open the HTML document, place a div around the web page’s content, and give
the div an id value of wrapper.
[web page content]
2. Amend the body rule. Because the page will be fixed and centered, there’s no longer a need for
horizontal padding on the body element; therefore, amend the body rule in the CSS file as follows:
body {
font: 62.5%/1.5 Verdana, Arial, Helvetica, sans-serif;
padding: 20px 0;
}
280
www.freepdf-books.com
Page Layouts with CSS
3. Add the following rule to center the wrapper, per the “Creating a fixed-width-wrapper” exercise
earlier in this chapter:
#wrapper {
width: 700px;
margin: 0 auto;
}
4. Finally, add the following two rules to float the columns, set their widths, and then place a margin
between them (by adding a margin-right setting to the left column).
#divOne, #divTwo {
float: left;
width: 340px;
}
#divOne {
margin-right: 20px;
}
No matter the size of the browser window, the two-column design sits centrally horizontally.
Note that the fixed-width values for the two columns can be replaced with percentages:
#divOne, #divTwo {
float: left;
width: 49%;
}
#divOne {
margin-right: 2%;
}
281
www.freepdf-books.com
Chapter 7
In such cases, the width of each div (and the margin) is a percentage of the parent element—the wrapper
div—rather than the browser window.
Note: When using percentages to size columns, it makes sense to use them also to size
the gutters and margins between them. If you don’t, you’ll have a hard time trying to
match up column widths in percentages and margins in pixels.
Clearing floated content
Required files
Files from using-wrappers-to-contain-columns in the chapter 7 folder as a starting
point
What you’ll learnHow to clear floated content, thereby making a wrapper’s background display
behind the content within it
Completed files
clearing-floated-content in the chapter 7 folder
1. To highlight issues with content that doesn’t clear floated content, you need to make some quick
changes to the HTML and CSS from the using-wrappers-to-contain-columns folder. First, add a
paragraph of text after the closing tag of the wrapper div:
Subsequent content...
2. Next, add a background color to the #wrapper rule in the CSS, and change the width and marginright settings of the #divOne, #divTwo, and #divOne rules, as shown following:
#wrapper {
width: 700px;
margin: 0 auto;
background: #bbbbbb;
}
#divOne, #divTwo {
float: left;
width: 300px;
}
#divOne {
margin-right: 20px;
}
3. Upon previewing the amended page, you’ll see that the subsequent content stacks to the right of
the floated content; also, the background color for the wrapper doesn’t extend behind the floated
content. Both of these issues can be fixed by clearing the floated content.
282
www.freepdf-books.com
Page Layouts with CSS
Note that Internet Explorer’s behavior is different from other browsers here: the wrapper
isn’t being collapsed, so the background extends fully, and the paragraph of text added
after the wrapper doesn’t flow around the floated divs, presumably because the wrapper
isn’t collapsing.
4. Clear the floated content. There are many different clear fixes available today. The micro clearfix
uses the minimum amount of CSS required. This version was introduced by Nicolas Gallagher
(nicolasgallagher.com/micro-clearfix-hack/), and it builds on the work of Thierry Koblentz
(www.yuiblog.com/blog/2010/09/27/clearfix-reloaded-overflowhidden-demystified/). First, add a
class value of clearFix to the container of the floated content (the wrapper div, in this example),
and then add the following rules in CSS:
.clearFix:before,
.clearFix:after {
content: "";
display: table;
}
.clearFix:after {
clear:both;
}
283
www.freepdf-books.com
Chapter 7
5. The magic of this method is in the CSS rule. By using the :after pseudo-selector, an empty
string is added after the element the class is applied to (in this case, after the wrapper div), and
said empty string’s display is set to table. This creates an anonymous table cell that is set to clear
the element. Unlike previous clearFix methods, there is no content added and therefore no need
to hide it. The genius of the method is that you need no extra markup to clear floats. The :before
pseudo-selecter is not required to clear the float but is used to prevent the top margin from
collapsing in modern browsers. In Chapter 9, I will show you a simple method for making this
clear fix work in IE 6/7.
6. Use an alternate method. The clearFix method is great for when you have content following a
containing wrapper. In some cases, you may not have this, though. For example, place your
subsequent content within the wrapper div, as shown here:
Subsequent content...
7. The clearFix method won’t work here, because the content is now inside the div that has the
clearFix rule applied to it. Various options are open; the first is to wrap the floated elements in an
internal wrapper and apply the clearFix class to that. In many cases, this will be fine, but you can
end up with a case of divitis, where many nested divs impair the clean nature of the markup. An
284
www.freepdf-books.com
Page Layouts with CSS
alternate option is to apply clearing directly to the element that follows the last piece of floated
content. In HTML, this would look as follows:
8. In CSS, this is styled as follows:
.clearFloats {
clear: both;
}
Generally, the clearFix method is considered superior to adding styles to specific elements, but on
occasions when it doesn’t work for your design, it’s good to have a fallback, so be mindful of both clearing
methods when working on your designs.
Working with sidebars and multiple boxouts
In this chapter so far, you’ve seen how to create web page columns and also how to fashion a boxout. In
this section, two exercises will expand upon these ideas, showing how to create two different layouts that
make use of sidebars. Sidebars are common in print, either for dividing up a page, thereby enabling a
designer to show a main story and a smaller story, or for providing an area for ancillary content to the main
story, but without having text wrapping underneath it (like in a boxout). The Pinkflag.com website (the
official website of the rock band Wire) makes use of sidebars throughout the site. In the following image, a
page from the Us section is shown. The main section of the page shows a photo of a band member, along
with a short biography. In the sidebar is a selection of the subject’s favorite tracks.
285
www.freepdf-books.com
Chapter 7
Based on what you’ve seen so far, you might think the best way to create such a layout would be to create
a two-column layout and then add a border to one of the columns. However, in CSS, borders and
backgrounds stop as soon as the content does. Therefore, if you add a border to the main content area but
the sidebar’s content makes it taller than the main content area, the separating border stops short. What
you therefore need to do is ensure that the two columns are placed in a wrapper and then apply a
vertically tiling background to the wrapper, thereby “faking” the column separator. This technique is
commonly referred to as creating faux columns and is explained fully in the following exercise.
Creating a sidebar with faux-column backgrounds
Required files
What you’ll learn
Completed files
faux-columns-background.gif from the image folder and all files from usingwrappers-to-contain-columns (both in the chapter 7 folder) as a starting point
How to use two structural elements and a background image to create faux columns
faux-columns in the chapter 7 folder
1. Clear the floated content, using the method outlined in step 2 of the “Clearing floated content”
exercise.
2. Change the id values. When creating a website, you should amend your elements id values to
something appropriate for the content within them. Don’t use generic names such as divOne and
286
www.freepdf-books.com
b
Page Layouts with CSS
divTwo for a completed website. (They’ve been used for some exercises in this chapter just to
make the exercises simpler to work through.) In both the HTML page and the CSS document,
change all instances of divOne to mainContent and all incidences of divTwo to sidebar. Amend
the two level-two headings in the web page accordingly, too. Finally, since the sidebar contains
content that will support the main body, change the div used for the sidebar into an aside.
3. Change the width settings for the columns, making sidebar narrower than mainContent.
#mainContent, #sidebar {
float: left;
width: 479px;
}
#mainContent {
margin-right: 41px;
}
#sidebar {
width: 180px;
display: block;
}
4. Add the background image. Apply the background image (shown right) to the wrapper div, as
shown following. The horizontal position is the width of the main content div, plus
half the margin once 1 pixel is removed from that value (because the width of the
“border” in the background image is a single pixel). By placing the background
image 499 pixels from the left, it ends up exactly halfway between the content of
the two divs.
#wrapper {
width: 700px;
margin: 0 auto;
background: url(faux-columns-background.gif) 499px 0 repeat-y;
}
5. To make it easier to differentiate the two areas of text, change the size of the text in the sidebar,
making it smaller.
#sidebar {
width: 180px;
font-size: 90%;
}
Using a percentage value is a quick way of doing this, with all values being based on those from the main
content area. If you want to set specific values for each of the text elements within the sidebar, you could
do so using contextual selectors (#sidebar h1, #sidebar p, and so on).
287
www.freepdf-books.com
Chapter 7
Note: There is an alternate way to create faux columns; see step 5 of the “Creating
flanking sidebars” exercise later in the chapter.
Boxouts revisited: creating multiple boxouts within a sidebar
Required files
point
Files from multiple-boxouts-starting-point in the chapter 7 folder as a starting
What you’ll learn
How to use faux columns, boxouts, and the cascade to create a page design with a
sidebar that contains multiple boxouts
Completed files
multiple-boxouts-complete in the chapter 7 folder
the code. Open the web page and CSS document from multipleboxouts-starting-point, and also open the web page in a browser so you can see what it looks
like. Lots of work has already been done here, but it’s all stuff you already know. Essentially, this
page is a combination of the “Creating a boxout” and “Creating a sidebar with faux-column
backgrounds” exercises from earlier in the chapter. A few changes have been made, however.
The boxout has been duplicated three times and placed within the sidebar, the float: right pair
from .boxout has been deleted (because the boxouts no longer need to float—they are within a
container that itself is floated), and some bottom padding has been added (to ensure there’s a
gap below the final paragraph of each boxout). A section has been used instead of multiple
asides since the containing element is an aside.
1. Examine
.boxout {
width: 180px;
padding: 0 10px 1px;
margin: 0 0 20px;
display: block;
background-color: #e1e1e1;
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#e1e1e1), to(#b5b5b5));
background-image: -webkit-linear-gradient(top, #e1e1e1, #b5b5b5);
288
www.freepdf-books.com
Page Layouts with CSS
}
background-image:
background-image:
background-image:
-moz-linear-gradient(top, #e1e1e1, #b5b5b5);
-ms-linear-gradient(top, #e1e1e1, #b5b5b5);
-o-linear-gradient(top, #e1e1e1, #b5b5b5);
Also, the background from the faux columns exercise isn’t there, because the vertical line the boxouts
create is enough to make the column visually distinct—another separator isn’t necessary.
2. Add class values. While consistent style is good for a website, it’s sometimes neat to offer
multiple styles for an element. This can come in handy for categorization—for example, each
boxout in this design could contain information about a certain area of the website, and therefore
color coding them and providing each with an icon (for those viewers with color vision difficulties)
may help users navigate more easily. Because you can use multiple class values in CSS, it’s
possible to simply add a second class value to each of the boxout sections and then create an
override rule for each in CSS.
3. Add new CSS rules. By using three contextual rules, overrides are created, setting a new
background color and gradients for each of the three heading classes defined in step 2.
.questionsHeader h2 {
background-color: #d72a49;
background-image: url(background-icon-questions.gif), -webkit-gradient(linear, 0% 0%, 0% 100%,
from(#d72a49), to(#dc4561));
background-image: url(background-icon-questions.gif), -webkit-linear-gradient(top,
#d72a49, #dc4561);
background-image: url(background-icon-questions.gif),
-moz-linear-gradient(top,
#d72a49, #dc4561);
background-image: url(background-icon-questions.gif),
-ms-linear-gradient(top,
#d72a49, #dc4561);
background-image: url(background-icon-questions.gif),
-o-linear-gradient(top,
#d72a49, #dc4561);
}
.chatHeader h2 {
background-color: #2a84d7;
background-image: url(background-icon-chat.gif), -webkit-gradient(linear, 0% 0%, 0% 100%,
from(#2a84d7), to(#4594dc));
background-image: url(background-icon-chat.gif), -webkit-linear-gradient(top, #2a84d7,
#4594dc);
background-image: url(background-icon-chat.gif),
-moz-linear-gradient(top, #2a84d7,
#4594dc);
289
www.freepdf-books.com
Chapter 7
background-image: url(background-icon-chat.gif),
-ms-linear-gradient(top, #2a84d7,
#4594dc);
background-image: url(background-icon-chat.gif),
-o-linear-gradient(top, #2a84d7,
#4594dc);
}
.toolsHeader h2 {
background-color: #d72ab0;
background-image: url(background-icon-tools.gif), -webkit-gradient(linear, 0% 0%, 0% 100%,
from(#d72ab0), to(#dc45bb));
background-image: url(background-icon-tools.gif), -webkit-linear-gradient(top, #d72ab0,
#dc45bb);
background-image:
url(background-icon-tools.gif), -moz-linear-gradient(top, #d72ab0,
#dc45bb);
background-image:
url(background-icon-tools.gif), -ms-linear-gradient(top, #d72ab0,
#dc45bb);
background-image:
url(background-icon-tools.gif), -o-linear-gradient(top, #d72ab0,
#dc45bb);
}
Note that these rules must be placed after the .boxout h2 rule in the CSS, because the CSS cascade
ensures that the rule closest to the element is applied. If these were placed above the .boxout h2 rule,
they would be overridden by it, resulting in the boxouts all retaining their default appearance.
The following image shows what your page should now look like.
290
www.freepdf-books.com
Page Layouts with CSS
Creating flanking sidebars
Although some sites can be designed around a two-column model, you’ll frequently need more. This can
be achieved by adding further columns to the pages created in earlier exercises or by nesting wrappers
with two columns. (In other words, the first wrapper can contain a sidebar and a wrapper, which itself
contains the main content and another sidebar.)
The only issue with this is that it doesn’t allow for information to be provided in code in an order different
from that shown on the screen. For users of alternate devices, a site with a sidebar (perhaps for navigation
and advertising), followed by the main content, followed by another sidebar (perhaps for boxouts), would
require them to wade through the first sidebar before accessing the main content. You can get around this
by using a “skip to main content” link (as per the skip navigation link from Chapter 5), but you can also set
the content in the order you want in the code (main content, first sidebar, second sidebar) and then use
CSS to reorder the columns on the screen.
Creating flanking sidebars
Required files
Files from flanking-sidebars-starting-point in the chapter 7 folder as a starting
point
291
www.freepdf-books.com
Chapter 7
What you’ll learnHow to create flanking sidebars for a content area, thereby enabling you to set
content in one order in the code and another on-screen
Completed files-flanking-sidebars-liquid and flanking-sidebars-fixed in the chapter 7 folder
1. Check out the page. Open flanking-sidebars.html in a web browser and in a text editor. In the
code, you have a wrapper that contains a masthead, followed by a wrapper for the columns,
followed by a footer. Within the column wrapper are three structural elements : mainContent,
leftSidebar, and rightSidebar. Each of these has a content wrapper (as per step 4 of the
“Manipulating two structural divs for liquid layouts” exercise). In CSS, the page defaults and font
styles are already set, as are styles for the masthead and footer. The clearFix method (see the
“Clearing floated content” exercise) has also been used, since the three columns will be
positioned by being floated. Note that for this exercise, the layout will be a liquid one, based on
percentage values for widths and margins.
2. Add the column backgrounds. Add the following two rules, which supply two backgrounds. The
first is applied to the column wrapper, setting the background to gray and adding a horizontally
tiling drop-shadow image. The second is applied to the main content div, defining its background
as white and setting its own background. This will create a seamless shadow effect, but the main
content will be differentiated from the sidebar via a brighter background.
#columnWrapper {
background: #ebebeb url(assets/grey-shadow-top.gif) 0 0 repeat-x;
}
#mainContent {
background: #ffffff url(assets/white-shadow-top.gif) 0 0 repeat-x;
}
3. Set column widths. Amend the #mainContent rule and add rules for the two sidebars, floating all
of the columns left and setting width values. This is a liquid design, so percentages must be used,
and they must add up to 100%.
#mainContent {
background: #ffffff url(assets/white-shadow-top.gif) 0 0 repeat-x;
float: left;
width: 50%;
}
#leftSidebar {
float: left;
width: 30%;
}
#rightSidebar {
float: left;
width: 20%;
}
292
www.freepdf-books.com
l
Page Layouts with CSS
4. Position the sidebars. At the moment, the columns are in the order specified in the code.
However, via the use of margins, this order can be changed. For the main content div, set a
margin-left value equal to the width of the left sidebar. Next, set a margin-left value for
#leftSidebar that’s the negative value of the sum of the width and left margin values of the main
content area.
#mainContent {
background: #ffffff url(assets/white-shadow-top.gif) 0 0 repeat-x;
float: left;
width: 50%;
margin-left: 30%;
}
#leftSidebar {
float: left;
width: 30%;
margin-left: -80%;
}
#rightSidebar {
float: left;
width: 20%;
}
293
www.freepdf-books.com
Chapter 7
Note: Internet Explorer may cause problems with this layout, making the right sidebar
sometimes appear beneath the others when the browser window is resized. This is
caused by a rounding error (see the “Dealing with rounding errors” section in Chapter 9).
Therefore, it’s often useful to amend one of the percentages (and any related values),
dropping them by 0.0001%—for example, change the width value of #mainContent to
49.9999% and the margin-left value of #leftSidebar to 79.9999%.
5. Fine-tune the design. Add the three rules in the following code block to finish off the layout and
tidy things up:
.columnContentWrapper {
padding: 30px 10px;
}
#mainContent, #leftSidebar, #rightSidebar {
padding-bottom: 32767px !important;
margin-bottom: -32767px !important;
}
#columnWrapper {
overflow: hidden;
}
294
www.freepdf-books.com
Page Layouts with CSS
The first rule merely adds some padding to the column content wrappers. The next rule applies a large
amount of padding to the bottom of each column and a negative margin of the same size, bringing the
document flow back to the point where the padding begins. The use of overflow: hidden on the column
container removes the overflow below the longest column’s content. Note that the value used here is the
maximum allowed by Apple’s Safari because it is the highest number that can be represented in a 16-bit
signed integer. You can also use the second rule in the previous code block to control padding by reducing
the margin-bottom value: the difference between the padding-bottom and margin-bottom values effectively
becomes padding, although in this exercise, padding has been dealt with via the .columnContentWrapper
rule.
6. Make the layout fixed. Amending the layout to a fixed one is simple. Because the layout will no
longer span the window width, a border needs to be placed around the wrapper (otherwise the
drop-shadow cutoffs at the left and right just look weird). Therefore, add a padding-bottom value
of 20px to the body rule, and create the #wrapper rule shown following:
295
www.freepdf-books.com
Chapter 7
#wrapper {
width: 700px;
margin: 0 auto;
border: 1px solid #555555;
border-top: 0;
}
7. Next, update the width and margin-left values for the three rules shown in the following code,
being mindful of the relationships mentioned in step 4 and the fact that the width values cannot
exceed the value set for the wrapper’s width in the previous step:
#mainContent {
background: #ffffff url(assets/white-shadow-top.gif) 0 0 repeat-x;
float: left;
width: 400px;
margin-left: 175px;
}
#leftSidebar {
float: left;
width: 175px;
margin-left: -575px;
}
#rightSidebar {
float: left;
width: 125px;
}
The following image shows what your page should now look like.
296
www.freepdf-books.com
Page Layouts with CSS
Automating layout variations
The final exercise in this section shows how to automate page layouts in a similar manner to automating
navigation, as described in Chapter 5 (namely, in the “Creating a CSS-only tab bar that automates the
active page” exercise). By defining a class value for the body element, contextual selectors can be used to
amend the layout of a web page. This technique comes in handy when working on large sites that have
many variations throughout but some consistent elements. For example, the site’s overall width,
masthead, and footer may remain constant, but the number of columns on the page may change, or they
may change widths.
Using body class values and CSS to automate page layouts
Required files
What you’ll learn
Completed files
Files from faux-columns in the chapter 7 folder as a starting point
How to use body class values and contextual selectors to automate page layouts
automate-page-layouts in the chapter 7 folder.
1. Examine the files. The files from the “Creating a sidebar with faux-column backgrounds” exercise
are used as the basis for this one. The web page has two structural elements, one for the main
content (mainContent) and another for the sidebar (sidebar). The default setup is for the main
content area to take up most of the width and for the sidebar to be narrow, with smaller text.
During the next two steps, contextual selectors will be designed to create two alternate layouts,
one of which will have a single column and one of which will split the columns evenly.
297
www.freepdf-books.com
Chapter 7
2. Create single-column rules. The way this method works is to create overrides for relevant rules.
The contextual selectors will begin with a class selector that will be applied to the page’s body
start tag, followed by the rules that require overriding. For a single column, the wrapper no longer
needs a background, the main content area needs to be as wide as the wrapper (700 pixels), and
the sidebar doesn’t need to be displayed. Also, the default margin-right value for #wrapper
needs to be overridden; otherwise, the main content area will end up 700 pixels wide plus 41
pixels of margin.
.singleColumn #wrapper {
background: none;
}
.singleColumn #mainContent {
width: 700px;
margin-right: 0;
}
.singleColumn #sidebar {
display: none;
}
3. This style can be applied to the web page by setting the body element’s class value to
singleColumn.
298
www.freepdf-books.com
Page Layouts with CSS
Note that when using designs such as this, be sure to empty the contents of
nondisplayed elements—any content left within them is just a waste of bandwidth.
4. Create an equal-column-split rule. For an equal column split, the column widths need to be
amended to the same value. But because the margin-right setting defined earlier is 41px, the
sidebar has been set to 1 pixel narrower than the main content area. (An alternate option would
have been to set both column widths to 330px and set margin-right in .equalSplitColumns
#mainContent to 40px.) The background-position horizontal value needs changing to reflect the
new column positions. Finally, because both columns command equal prominence, the
font-size setting for the sidebar is set to 100% in .equalSplitColumns #sidebar.
.equalSplitColumns #wrapper {
background-position: 350px 0;
}
.equalSplitColumns #mainContent {
width: 330px;
}
.equalSplitColumns #sidebar {
width: 329px;
font-size: 100%;
}
This style can be applied to the web page by setting the body element’s class value to equalSplitColumns.
299
www.freepdf-books.com
Chapter 7
As mentioned, this exercise works in a similar way to some of the navigation ones in Chapter 5. With a
little thought, it should be easy enough to see how this automation method can assist when creating
websites. As long as the site’s structure has been carefully planned, you can usually get away with a
single navigation bar and a single structure but have multiple layouts, each one driven by the CSS
variations and the body class value.
Scrollable content areas
Scrolling is a matter of fact on the Web. Although designers should be careful not to make users scroll too
much (or in multiple directions—sites that force both horizontal and vertical scrolling tend to be awkward
and annoying to use), some scrolling is inevitable with the vast majority of websites. In the past, some
designers created fixed sites that sat in the middle of the browser window, content restricted by the
viewing area. Various techniques later enabled designers to get around this limitation, creating in-page
scrollable content areas. First came frames, and later came CSS-driven scrolling areas. Both enable you
to create in-page scrollable content, but although such things are explored in the final part of this chapter,
scrollable areas should be used with care—if you need a user to see something right away, don’t hide it
“under the fold,” and remember that if you create a centered, fixed-view window, test it using many
different screen resolutions to ensure it looks and works OK for all of your users.
Scrollable content areas with CSS
Scrollable content areas in CSS are often used to provide a lot of information on a single page that can be
viewed at the user’s convenience. Typically the content in a scrollable area isn’t key to the main content of
the page, such as a list of events related to an article. This method allows the content to remain part of the
web page, which is better for accessibility, site maintenance, and search engine indexing.
To do this, create a div with a unique class value:
[content...]
Then style it in CSS—the rule provides the div’s dimensions and determines how the div’s overflow
works:
300
www.freepdf-books.com
Page Layouts with CSS
.scrollableContent {
width: 200px;
height: 200px;
overflow: auto;
}
When overflow is set to auto, scrollbars appear only when the content is too large for the set dimensions
of the div. Other available values are hidden (display no scrollbars), scroll (permanently display both
scrollbars), and visible (render content outside of the defined box area). Adding some padding, especially
at the right side of the scrollable content box, helps improve the area aesthetically, ensuring that content
doesn’t hug the scrollbar.
.scrollableContent {
width: 200px;
height: 200px;
overflow: auto;
padding: 0 10px 0 0;
}
Note that by also using server-side includes (PHP in this example), you can even make scrollable content
separate from the main web page, thereby emulating an iframe, without resorting to using frames at all.
Note: Inline frames (iframes) are the only type of frame allowed in HTML5. Iframes allow
you to include content from external sources into your web page. You can find more
information about iframes in Appendix A.
In this code block, a PHP page called document-name.php is being included into the scrollableContent div.
This implementation is a simple example and should not be attempted without knowledge of PHP.
Another more accessible option than using iframe elements is to use the object element to embed an
external HTML document within a region of the page; when combined with the scrolling div method shown
in this section, it pretty much provides all the benefits of an iframe with very few of the drawbacks (the
content is on the page, unlike with frames and iframes—their content remains external).
The following code block shows how an object element can be added to the page. Note the alternate
content within the object element, displayed if the browser cannot show the object. This can be used to
directly link to the file in the data attribute.
[alternate content]
301
www.freepdf-books.com
Chapter 7
Like other elements, the object element can be styled using CSS, although Internet Explorer adds a
border, so you need to overwrite existing border settings using conditional comments (see Chapter 9 for
more on those) to prevent a double border. Also, if the content is too large for the object dimensions, it will
scroll in whatever direction is needed, unless you explicitly set overflow to hidden.
Fluid grid layouts
Fluid grid layout is designing in proportions instead of fixed pixels and arbitrary percentages. This allows
your layout to look right when crammed onto a tiny mobile screen since all the sections of your layout are
in proportion with each other. A fluid grid layout can be implemented by using div layers percentages and
some simple math. In 2009 Ethan Marcotte introduced “Fluid Grids” on A List Apart
(www.alistapart.com/articles/fluidgrids/). Fluid grids center around a simple formula for converting pixels to
percentages:
(target / context) x 100 = result
How does it work?
1. Pick a section of your design and measure its width. This is your target.
2. Take the target’s measurement and divide it by its parent (the context).
3. Multiple that by 100, and you get your result (round to two decimal places).
4. You now have a percentage that you can drop into your style sheets.
For example, you have a site that has a max width of 960 pixels, and it contains a sidebar of 300 pixels:
(300/960) x 100 = 31.25%
The result is that columns don’t have a fixed width: they can very based on the resolution of the screen or
the resolution of the screen. Fluid grid layouts are an important part of creating a responsive design.
Introduction to fluid grid layouts
Required files
What you’ll learn
Completed files
Files from fluid-grids in the chapter 7 folder
How to use everything you've learned so far to great a fluid grid layout
fluid-grids in the chapter 7 folder
302
www.freepdf-books.com
Page Layouts with CSS
Examine the files. The fluid grid layout markup takes elements of everything you’ve learned so far to
create an advanced layout. The wrapper div is a full width container div that allows layouts to span
the full width of the browser. It has 20px padding applied to the left and right to keep the content
away from the edges. Like a true grid, a row is a row of columns. It centers them and defines a
maximum width. This grid layout is made up of 12 columns and can have any number of columns in
a row that add up to 12. In this example, we have four threecols, but we could easily have two
threecols and a sixcol or any combination that adds up to 12.
[content]
[content]
[content]
[content]
The maximum width I have chosen for this layout is the popular 960 pixels. All the columns from one to
twelve have had their widths calculated using the previous formula.
Let’s start by finding the width of one column: 960 / 12 = 80. I’ve chosen to have 20px-wide gutters, so
let’s subtract 20 pixels from our total. We have 60. Now using our formula, you can get the width of
column one: (60 / 960) * 100 = 6.25%. For the rest of the columns, we multiply by our original width of 80
pixels, subtract 20 pixels for our gutters, and use our formula to get the rest of the widths (remember to
round to two decimal places).
.onecol{ width: 6.25%; }
.twocol( width: 14.58%; }
.threecol{ width: 22.91%; }
.fourcol{ width: 31.25%; }
As you can see from the following screenshot, building a fluid grid is easy once you know the formula.
The rest of this exercise uses the standard floats and clear fixes explained earlier in this chapter.
303
www.freepdf-books.com
Chapter 7
Responsive Web Design
Over the years designers have come up with many solutions that use and combine fixed
and fluid layouts. In an article entitled “Responsive Web Design” published on A List Apart
(www.alistapart.com/articles/responsive-web-design/), Ethan Marcotte takes this a step further, by uniting
the existing technologies of fluid grids, flexible images, and media queries into a new way of approaching
web design. This is a very different way of designing websites, and it represents the future.
Users are browsing your website using their mobile phone, tablet, netbook, or desktop browser. Are you
going to create a new design for each new device? Layouts need to be adaptive. They need to
automatically adjust to fit not only the browser size but the platform and orientation of the device as well.
A responsive design typically consists of a mix of fluid and flexible grid layouts, and the use of CSS media
queries that can reformat your web page and markup to meet the needs of your users.
CSS media queries are used to target styles to specific capabilities, applying different styles based on the
capabilities that match your query. They can test for capabilities such as width, height, max-width, maxheight, device-height, orientation, aspect ratio, and more. Tests can be combined using operators (AND
and NOT) to allow for flexible targeting.
The wide range of devices used to browse your website can generate extreme size changes that may call
for an altogether layout change, through either a separate style sheet or CSS media queries. If you have
structured your CSS correctly, most of your styles can remain the same through inheritance.
Typically a responsive layout would have a main style sheet, which will define the structure, colors,
typography, and backgrounds of your website. Other style sheets would then be defined that would adopt
all the styles from the main style sheet and then redefine the style for new dimensions. A good set of target
pixel widths that should serve as starting points is 320, 480, 600, 768, 900, and 1200. When deciding
which resolutions to target the decision is ultimately up to you as the designer. The more resolutions you
target, the more time it will take to complete your design.
304
www.freepdf-books.com
Page Layouts with CSS
As you can see from the following screenshots, Smashing Magazine (www.smashingmagazine.com) and
Media Queries (http://mediaqueri.es) are great examples of a responsive layout.
Introduction to Responsive Design
Required files
What you’ll learn
Completed files
Files from responsive-starting-point in the chapter 7 folder
How to use make a fluid grid responsive
responsive-complete in the chapter 7 folder
Let’s take our fluid grid a step further and make it responsive.
1. Open
@media
@media
responsive-starting-point.css,
and
add
the
(max-width:
(max-width:
following
600px)
767px)
to
the
bottom:
{}
{}
These are the different media queries that allow you to change the layout of your design to better
fit your targeted screen size. You can choose as many as you like, but for this example I have
picked two to show you the power of responsive design.
305
www.freepdf-books.com
Chapter 7
2. Since the media styles will be inherited from 767, we will change the width of the wrapper to auto
so that it can scale down with the browser size. Add the following between the brackets of the
media
query
targeting
767
pixels.
.wrapper{
width:
}
auto;
3. As the browser scales down, let’s stop floating the columns. Add this to the 767 media query:
.row
float:
display:
width:
margin:0;
}
>
[class*="col"]{
none;
block;
auto;
This targets and applies the style to all elements that contain the string "col" in its class.
4. Finally, let’s adjust the callout section font size for the 600-pixel media query.
.row.callout
font-size:
}
.row.callout
font-size:
line-height:
margin-top:
}
h2
{
32px;
p
{
16px;
18px;
5px;
As you have seen throughout this chapter, even the most complex layout can be broken
down to simple layout techniques combined to create powerful responsive designs.
306
www.freepdf-books.com
Chapter 8
Getting User Feedback
In this chapter:
Creating forms and adding fields and controls
Styling forms in CSS
Configuring a mailform CGI script
Sending forms using PHP
307
www.freepdf-books.com
Chapter 8
Creating a layout for a user feedback page
Creating an online business card using microformats
Introducing user feedback
One of the main reasons the Web has revolutionized working life and communications is its immediacy.
Unlike printed media, websites can be continually updated at relatively minimal cost and also be available
worldwide on a 24/7 basis. However, communication isn’t one-way, and the Web makes it very easy to
enable site users to offer feedback.
Using mailto: URLs
One of the most common methods of providing immediate user feedback is by using mailto: URLs within
anchor tags. Instead of the anchor tag’s value being a file name or URL, it begins with mailto: and is
immediately followed by the recipient e-mail address.
Click to email!
It’s possible to take this technique further. You can define multiple recipients by using a comma-separated
list; in addition, by placing a question mark immediately after the final recipient address, you can add
further parameters, such as a subject and recipients to carbon copy (cc) and blind carbon copy (bcc). If
using more than one parameter, you must separate them with encoded ampersands (&). Note that
spaces within the subject should also be encoded (as %20).
Click
to email!
Note: There should be no spaces in a mailto: value. Therefore, don’t place spaces
before or after colons, commas, or the ? and = symbols.
Although this may sound great, this system has several problems. First, e-mail addresses online are often
harvested by spambots. Second, a mailto: link relies on the user having a preconfigured e-mail client
ready to go—something that people working on college and library machines most likely won’t have. Third,
not all browsers support the range of options explained earlier.
A way to combat the spambots is presented in the next section. For the second issue (the mailto: link’s
reliance on a preconfigured mail client), we recommend using forms for any complex website feedback,
which we will come to later in this chapter. For the third issue (browser support for the more advanced
mailto: options), we recommend just keeping things simple. Place your e-mail address online as a
mailto:, and enable the user to fill in any other details, such common as the subject line.
308
www.freepdf-books.com
Getting User Feedback
Scrambling addresses
In our experience, having an e-mail address online for just a few days is enough to start receiving regular
spam. A workaround is to encrypt e-mail addresses using a bulletproof concoction of JavaScript. The
Enkoder form from Hivelogic is a neat way of going about this and produces decent results.
This online form at www.hivelogic.com/enkoder/form enables you to create a mailto: link that’s
composed of complex JavaScript. Although in time spambots will likely break this code, as they have with
simpler encoders, it’s the best example we’ve seen, and the results we’ve had with it have been good.
Beware, though, that any users with JavaScript disabled won’t see the address, so ensure that you cater
to them by including some other means of contacting the site owner.
Enkoder is also available as a plug-in for Ruby on Rails.
Working with forms
In this section, we’ll work through how to create a form and add controls. We’ll also look at how to improve
form accessibility by using the tabindex attribute and the label, fieldset, and legend elements.
As suggested earlier in the chapter, the best way of getting user feedback is through an online form that
the user fills in and submits. Fields are configured by the designer, enabling the site owner to receive
specific information. However, don’t go overboard: provide users with a massive, sprawling online form,
and they will most likely not bother filling it in and will go elsewhere.
Similarly, although you can use JavaScript to make certain form fields required, we’re not fans of this
technique, because it annoys users. Some sites go overboard on this, “forcing” users to input a whole
bunch of details, some of which may simply not be applicable to the user. In such cases, users will likely
either go elsewhere or insert fake data, which helps no one.
So, keep things simple and use the fewest fields possible. In the vast majority of cases, you should be able
to simply create name, e-mail address, and phone number fields, as well as include a text area that
enables users to input their query.
Creating a form
Form controls are housed within a form element, whose attributes also determine the location of the script
used to parse it (see the “Sending feedback” section later in the chapter). Other attributes define the
encoding type used and the method by which the browser sends the form’s data to the server. A typical
start tag for a form therefore looks like this:
309
www.freepdf-books.com
Chapter 8
The preceding form start tag includes attributes that point at a CGI script, but alternative
methods of sending forms exist, including PHP, ASP, and ColdFusion. Check with your
hosting company about the methods available for sending forms, and use the
technology supported by your ISP.
Adding controls
Some form controls are added using the input element. The type attribute declares what kind of control
the element is going to be. The most common values are text, which produces a single-line text input
field; checkbox and radio, which are used for multiple-choice options; and submit, which is used for the allimportant Submit button.
Other useful elements include select, option, and optgroup, used for creating pop-up lists, and textarea,
which provides a means for the user to offer a multiple-line response (this is commonly used in online
forms for a question area). The basic HTML for a form may therefore look like the following, producing the
page depicted in the following screen grab.
Name
Email address
Telephone
Are you a Web designer?
Yes |
No
What platform do you favor?
Windows
Mac
Linux
Other
Message
310
www.freepdf-books.com
Getting User Feedback
The bulk of the HTML is pretty straightforward. In each case, the name attribute value labels the control,
meaning that you end up with the likes of Telephone: 555 555 555 in your form results, rather than just a
bunch of answers. For multiple-option controls (check boxes and radio buttons), this attribute is identical,
and an individual value attribute is set in each start tag.
By default, controls of this type—along with the select list—are set to off (that is, no values selected), but
you can define a default option. I’ve done this for the select list by setting selected="selected" on the
Windows option. You’d do the same on a radio button to select it by default, and with a check box you’d set
checked="checked".
Some of the attributes define the appearance of controls: the input element’s size attribute sets a
character width for the fields, while the textarea’s rows and cols attributes set the number of rows and
columns, again in terms of characters. It’s also worth noting that any content within the textarea element
is displayed, so if you want it to start totally blank, you must ensure that there’s nothing—not even
whitespace—between the start and end tags. (Some applications that reformat your code, and some
website editors, place whitespace here, which some browsers subsequently use as the default
value/content of the textarea. This results in the textarea’s content being partially filled with spaces, and
anyone trying to use it may then find their cursor’s initial entry point partway down the text area, which can
be off-putting.)
Longtime web users may have noticed the omission of a Reset button in this example. This button used
to be common online, enabling the user to reset a form to its default state, removing any content they’ve
added. However, I’ve never really seen the point in having it there, especially seeing as it’s easy to click by
mistake, resulting in the user having to fill in the form again, which is why it’s absent from the examples in
this chapter. However, if you want to add such a button, you can do so by using the following code:
311
www.freepdf-books.com
Chapter 8
Note: A full list of controls is available in Appendix A.
Improving form accessibility
Although there’s an on-screen visual relationship between form label text and the controls, they’re not
associated in any other way. This sometimes makes forms tricky to use for those people using screen
readers and other assistive devices. Also, by default, the Tab key cycles through various web page
elements in order, rather than jumping to the first form field (and continuing through the remainder of the
form before moving elsewhere). Both of these issues are dealt with in this section.
The label, fieldset, and legend elements
The label element enables you to define relationships between the text labeling a form control and the
form control itself. In the following example, the Name text is enclosed in a label element with the for
attribute value of realname. This corresponds to the name and id values of the form field associated with
this text.
Name
Most browsers don’t amend the content’s visual display when it’s nested within a label element, although
you can style the label in CSS. However, most apply an important accessibility benefit: if you click the
label, it gives focus to the corresponding form control (in other words, it selects the form control related to
the label). Note that the id attribute—absent from the form example earlier in the chapter—is required for
this. If it’s absent, clicking the text within the label element won’t cause the browser to do anything.
The fieldset element enables you to group a set of related form controls to which you apply a label via
the legend element.
Personal information
Name
Email address
Telephone
312
www.freepdf-books.com
Getting User Feedback
As you can see from the previous screenshot, these elements combine to surround the relevant form fields
and labels with a border and provide the group with an explanatory title.
Note that each browser styles forms and controls differently. Therefore, be sure to test
your forms in a wide range of browsers and don’t be too concerned with trying to make
things look exactly the same in each browser.
Adding tabindex attributes
The tabindex attribute was first mentioned in Chapter 5 (in the “Using accesskey and tabindex” section).
For forms, it’s used to define the page’s element tab order, and its value can be set as anything from 0 to
32767. Because the tabindex values needn’t be sequential, it’s advisable to set them in increments of ten,
enabling you to insert others later, without having to rework every value on the page. With that in mind,
you could set tabindex="10" on the realname field, tabindex="20" on the email field, and tabindex="30"
on the phone field (these field names are based on their id/name values from the previous example).
Assuming no other tabindex attributes with lower values are elsewhere on the page, the realname field
becomes the first element highlighted when the Tab key is pressed, and then the cycle continues (in order)
with the email and phone fields.
Note: The reason for starting with 10 rather than 1 is because if you ignore the last digit,
the tabindex values become standard integers, starting with 1. In other words, remove
the final digits from 10, 20, and 30, and you end up with 1, 2, and 3. This makes it easier
to keep track of the tabindex order.
Note that whenever using tabindex, you run the risk of hijacking the mouse cursor, meaning that instead
of the Tab key moving the user from the first form field to the second, it might end up highlighting
something totally different, elsewhere on the page. What’s logical to some people in terms of tab order
may not be to others, so always ensure you test your websites thoroughly, responding to feedback.
Generally, it makes sense to use the value only for form fields, and then with plenty of care.
313
www.freepdf-books.com
Chapter 8
Client-side form validation
With HTML5, forms can be annotated in such a way that the browser will check the user’s input before the
form is submitted. The server still has to verify the input is valid, but this technique allows the user to avoid
the wait incurred by having the server be the sole checker of the user’s input.
The simplest annotation is the required attribute, which can be specified on input elements to indicate that
the form is not to be submitted with an empty value. By adding this attribute to the name and email fields,
we allow the user agent to notify the user when the user submits the form without filling in those fields:
Personal information
Name
Email address
Telephone
It is also possible to limit the length of the input, using the maxlength attribute. By adding this to the
realname element, we can limit the size of names to 25 characters:
Personal information
Name
Email address
Telephone
Form validation is hard and error prone, so having it performed natively by the browsers and being RFCcompliant in cases like email, for example, is very helpful. Some forms of validation are notoriously hard to
perform correctly even for the browsers. For example, Chrome validates the string foo@bar as a correct
email address.
Some mobile devices that don’t have a physical keyboard can recognize several of the new HTML5 input
types and dynamically change the on-screen keyboard to optimize for that kind of input. For example,
when you use an iPhone and focus an input type="email" element, you get an on-screen keyboard that
contains a smaller-than-usual spacebar, plus dedicated keys for the @ and. characters. Similarly, for input
type="number", you get a number scroller, and so on.
Default validation alerts are ugly, but in the future it will be easy to add CSS style to them. Chrome and
Safari have recently added support for pseudoselectors like ::-webkit-validation-bubble{}, ::-webkitvalidation-bubble-top-outer-arrow{}, ::-webkit-validation-bubble-top-inner-arrow{}, and ::-webkit-validationbubble-message{}. At the time of this writing, Firefox has no way to style the error messages. Similarly,
you might want to change the text of the error messages. Firefox has support for the attribute x-moz-
314
www.freepdf-books.com
Getting User Feedback
errormessage, which enables you to change the text of the error message. The same can be
accomplished in Chrome using CSS and the -webkit-validation-bubble-message.
Date, time, and number formats
The time, date, and number formats used in HTML and in form submissions, are based on the ISO 8601
standard for computer-readable date and time formats, and are intended to be computer-readable and
consistent irrespective of the user’s locale. Dates, for instance, are always written in the format "YYYYMM-DD", as in "2012-03-18". Users are not expected to ever see this format.
The time, date, or number given by the page in the wire format is then translated to the user’s preferred
presentation (for example, locale), before being displayed to the user. Similarly, after the user inputs a
time, date, or number using their preferred format, the user agent converts it to the wire format before
putting it in the DOM or submitting it. This allows scripts in pages and on servers to process times, dates,
and numbers in a consistent manner without needing to support dozens of different formats, while still
supporting the users’ needs.
When an input element’s type attribute is datetime, it represents a control for setting the
element’s value to a string representing a specific global date and time. User agents may display
the date and time in whatever time zone is appropriate for the user. The min and max attributes, if
specified, must have a value that is a valid date and time string. The step attribute is expressed in
seconds. The step scale factor is 1000 (milliseconds), and the default step is 60 seconds. It’s
similar to datetime-local, which represents a local date and time, with no time-zone offset
information.
When an input element’s type attribute is in date, it represents a control for setting the element’s
value to a string representing a specific date. The min and max attributes, if specified, must have
a value that is a valid date string. Here the step attribute is expressed in days. The step scale
factor is 86,400,000 (days to milliseconds), and the default step is 1 day.
When an input element’s type attribute is month, it represents a control for setting the element's
value to a string representing a specific month. The min and max attributes, if specified, must
have a value that is a valid month string. The step attribute is expressed in months, it has a scale
factor of 1, and the default step is 1 month.
When an input element’s type attribute is week, it represents a control for setting the element’s
value to a string representing a specific week. The min and max attributes, if specified, must have
a value that is a valid week string. The step attribute is expressed in weeks. The step scale factor
is 604,800,000 (weeks to milliseconds); the default step is 1 week.
When an input element's type attribute is time, it represents a control for setting the element’s value to a
string representing a specific time. The min and max attributes, if specified, must have a value that is a
valid time string. Here the step attribute is expressed in seconds and has a scale factor of 1000 (seconds
to milliseconds), and the default step is 60 seconds.
315
www.freepdf-books.com
Chapter 8
More HTML5 input formats
To make developers’ lives easier, HTML5 offers a set of the most common input field types that should
provide validation, although they’re still not common in browsers:
type=url: For editing a single absolute URL given in the element’s value
type=email: For editing one or multiple e-mail address given in the element’s value
type=password: Represents a one line plain text edit control, which the browser obscures
type=number: For setting the element’s value to a string representing a (floating-point) number
type=range: For setting the element's value to a string representing a number, when the exact value is not important
type=color: For setting the element’s value to a string representing a simple color
More HTML5 form elements
Here are some other HTML5 elements that can be used to create powerful forms and improve the user
experience:
Element
button
Usage
A button
Details
The type attribute controls the behavior of the button when it is
activated, and its value can be “submit,” “reset,” or “button”
(which does nothing).
select
A control for selecting
amongst a set of options
The multiple attribute is a boolean attribute. If the attribute is
present, then the select element represents a control for
selecting zero or more options from the list of options.
The size attribute gives the number of options to show to the
user.
The required attribute is a boolean attribute. When specified, the
user will be required to select a value before submitting the form.
datalist
A set of option elements
for predefined options for
other controls
The datalist element can be hooked up to an input element using
the list attribute on the input element.
optgroup
A group of option
elements with a common
label
When showing option elements in select elements, browsers
show the option elements of such groups as being related to
each other and separate from other option elements.
316
www.freepdf-books.com
Getting User Feedback
option
A option in a select
An option element can be a select element’s placeholder label
element or as part of a list option. A placeholder label option does not represent an actual
in a datalist element
option but instead represents a label for the select control.
textarea
A multiline plain-text edit
The readonly attribute is a boolean attribute used to control
whether the text is editable.
keygen
A key/pair generator
control
When the control’s form is submitted, the private key is stored in
the local keystore, and the public key is packaged and sent to
the server.
CSS styling and layout for forms
Earlier, we covered how to lay out a form using paragraphs and line breaks. In this section, you’ll see how
tables and CSS can also be used to produce a more advanced layout.
Adding styles to forms
Form fields can be styled, enabling you to get away from the rather clunky default look offered by most
browsers. Although the default appearance isn’t very attractive, it does make obvious which elements are
fields and which are buttons. Therefore, if you choose to style forms in CSS, ensure that the elements are
still easy to make out.
A simple, elegant style to apply to text input fields and text areas is as follows:
.formField {
border: 1px solid #333333;
background-color: #dddddd;
padding: 2px;
}
In HTML, you need to add the usual class attribute to apply this rule to the relevant element(s):
This replaces the default 3D border with a solid, dark gray border, and it also sets the background color as
a light gray, thereby drawing attention to the form input fields. Note that browsers that support :hover and
:focus on more than just anchors can have these states styled with different backgrounds, thereby
providing further prompts. For example, upon focusing a form field, you might change its background color,
making it more obvious that it’s the field in focus.
317
www.freepdf-books.com
Chapter 8
Because the border in the previous code is defined using a class, it can be applied to multiple elements.
The reason we don’t use a tag selector and apply this style to all input fields is that radio buttons and
check boxes look terrible with rectangular borders around them. However, applying this style to the select
element can work well.
Note that the background color in this example is designed to contrast slightly with the page’s background
color but still provide plenty of contrast with any text typed into the form fields; as always, pick your colors
carefully when working with form styles.
The default Submit button style can be amended in a similar fashion, and padding can also be applied to
it. This is usually a good idea because it enables the button to stand out and draws attention to the text
within.
Should you desire a more styled Submit button, you can instead use an image:
Along with the fields and controls, it’s also possible to style the elements added in the previous section
“The label, fieldset, and legend elements.” The fieldset rule applies a 1-pixel dashed line around the
elements grouped by the fieldset element, along with adding some padding and a bottom margin. The
legend rule amends the legend element’s font and the padding around it and sets the text to uppercase; it
also adds a background color so that the dotted line of the fieldset won’t be shown behind the legend
text in Internet Explorer. Note that not all browsers treat margins on legend elements in the same way, so
if you add a margin value, be sure to thoroughly test your page. The screenshot that follows also includes
the styles included in the default CSS document from the basic-boilerplates folder.
fieldset {
border: 1px dashed #555555;
padding: 10px;
margin-bottom: 10px;
}
318
www.freepdf-books.com
Getting User Feedback
legend {
padding: 0 10px;
font-family: Arial, Helvetica, sans-serif;
color: #000000;
background: #ffffff;
text-transform: uppercase;
}
A final style point worth bearing in mind is that you can define styles for the form itself. This can be useful
for positioning purposes (for example, controlling the form’s width and its bottom margin); the width setting
can prove handy, since the fieldset border stretches to the entire window width, which looks very odd if
the form labels and controls take up only a small area of the browser window. Reducing the form’s width to
specifically defined dimensions enables you to get around this. Alternatively, you can set a fixed width on
the fieldset itself (or float it, enabling you to display fieldsets side by side).
You can also color the form’s (or fieldset’s) background in addition to or instead of the input fields,
thereby making the entire form prominent. This is a device I’ve used on various versions of the Snub
Communications website’s contacts page, as shown in the following screenshot.
319
www.freepdf-books.com
Chapter 8
Regardless of the form styles you end up using, be sure to rigorously test across browsers, because the
display of form elements is not consistent. Some variations are relatively minor—you’ll find that defining
values for font sizes, padding, and borders for input fields doesn’t always result in fields of the same height
and that text fields and Submit buttons don’t always align. A more dramatic difference is seen in versions
of Safari prior to 3.0, which ignore many CSS properties for forms, instead using the Mac OS X “Aqua”
look and feel—see the following screenshot for how the Snub Communications form looks in that browser.
Form functionality is not affected by this, but layouts can be.
320
www.freepdf-books.com
Getting User Feedback
Advanced form layout with CSS
A common way of laying out forms is to use a table to line up the labels and form controls, although with
the output being nontabular in nature, this method is not recommended (CSS should be used for
presentation, including positioning elements on a web page); it’s provided here to show a (partial) table
layout that can be replicated in CSS. For our first three fields, a table-based form may have something like
this:
Personal information
' . $row->field1 . ' ' . $row->field2 . '
321
www.freepdf-books.com
Chapter 8
Because a class value was added to the table, the contextual selector .formTable th can be used as the
selector for styling the form labels, defining the text-align property, along with other CSS properties such
as font-weight. Applying a padding-right value to these cells also produces a gap to the right of the label
cells. Another contextual selector, .formTable td, can then be used to style the cells—for example, to add
padding at the bottom of each cell. The image below shows these styles applied to the various elements in
the previous code block, along with the styles shown in the “Adding styles to forms” section.
.formTable td {
padding: 0 0 5px 0;
}
.formTable th {
padding-right: 10px;
text-align: right;
font-weight: bold;
}
Note that the fieldset and legend elements must surround the table containing the relevant
fields. If using these elements, you may need multiple tables for your form.
Although forms are not tabular in nature, using a table to create a form can result in a pleasing visual
appearance, with the labels right-aligned and placed next to their associated labels. This kind of layout can
be replicated using CSS, via a structure built from divs to replace the table rows. This method retains
semantic integrity via the semantic relationship created by the label and associated field’s id. Using CSS
for form layout also brings with it the benefit of being able to rapidly restyle and move form components.
This isn’t a complete form—it’s just a guide to using this method. This example lacks, for
instance, a Submit button and many of the controls in the example from earlier in the
chapter.
Note the use of the clearing device, the clearFix class value, as outlined in Chapter 7’s
“Placing columns within wrappers and clearing floated content” section.
Various styles are then defined in CSS. The form itself has its width restricted, and label elements are
floated left, the text within aligned right, and the font-weight property set to bold. The width setting is
large enough to contain the largest of the text labels.
form {
width: 350px;
}
label {
float: left;
text-align: right;
font-weight: bold;
width: 95px;
}
The form controls—the input elements—are floated right. Because only input elements within the div
rows should be floated (rather than all of the input elements on the page), the contextual selector .row
input is used. (The containing divs have a class value of row.) The width setting is designed to provide a
gap between the labels and input elements.
.row input{
float: right;
width: 220px;
}
Finally, to make a gap between the rows, a .row
class is added and given a margin-bottom value.
.row {
margin-bottom: 5px;
}
The method works fine in all browsers except Internet Explorer, which doesn’t apply margin-bottom
correctly. However, the slightly different layout in Internet Explorer can largely be fixed by adding the
following in a style sheet attached via an IE-specific conditional comment:
.row {
clear: both;
margin-top: 5px;
}
Alternatively, add the following:
.clearFix {
display: inline-block;
}
323
www.freepdf-books.com
Chapter 8
Example forms for the sections in this chapter are available in the chapter 8 folder of the
download files.
Sending feedback
In this section, you’ll check out how to send form data using a CGI script and PHP. Once users submit
information, it needs to go somewhere and have a method of getting there. Several techniques are
available for parsing forms, but we’re first going to cover using a server-side CGI script. Essentially, this
script collects the information submitted, formats it, and delivers it to the addresses you configure within
the script.
FormMail, available from Matt’s Script Archive (www.scriptarchive.com), is probably the most common,
and a number of web hosts preconfigure this script in their web space packages. However, FormMail does
have flaws, and it hasn’t kept up with current technology. A better script is nms FormMail (available from
http://nms-cgi.sourceforge.net/ and described next)—it emulates the behavior of FormMail but takes a
more modern and bug-free approach.
Configuring nms FormMail
The thought of editing and configuring scripts gives some designers the willies, but nms FormMail takes
only a couple of minutes to get up and running. First, you need to add some more input elements to your
web page, after the form start tag:
Note that some browsers display an outline where hidden fields are if input elements are
set to display as block. In such cases, you can apply a class value of hidden to the
relevant fields, with display set to none.
Obviously, the values in the preceding elements need changing for your site. The subject value can be
whatever you like—just make it obvious, so you or your clients can use an e-mail package to filter website
form responses efficiently.
The redirect value isn’t required, but it’s good to provide positive feedback to users, not only to confirm
that their form has been sent but also to communicate that their query will be dealt with as soon as
possible. Many “thank you” pages online tend to look a little barren, with a single paragraph of text. That’s
why we tend to make this page a duplicate of our standard contact page but with the confirmation
paragraph above the form. The script itself needs only minimal editing. Because CGI scripts tend to break
with slight errors, I highly recommend editing them in a text editor that doesn’t affect document formatting,
such as HTML-Kit for Windows (www.chami.com) or BBEdit for Mac (www.barebones.com).
324
www.freepdf-books.com
Getting User Feedback
The first line of the script defines the location of Perl on your web host’s server. Your hosting company can
provide this, so you can amend the path accordingly.
#!/usr/bin/perl -wT
Elsewhere, you only need to edit some values in the user configuration section. The $mailprog value
defines the location of the sendmail binary on your web host’s server. You can find this out from your web
host’s system admin.
$mailprog = '/usr/lib/sendmail -oi -t';
The $postmaster value is the address that receives bounced messages if e-mails cannot be delivered. It
should be a different address from that of the intended recipient.
$postmaster = 'someone@your.domain';
The @referers value lists IP addresses or domain names that can access this script, thereby stopping just
anyone from using your script and your server resources. For instance, the Snub Communications mail
form has snubcommunications.com and the site’s IP address for this value (as a space-delimited list). If you
use localhost, that enables local testing, if you have the relevant software set up on your PC.
@referers = qw(dave.org.uk 209.207.222.64 localhost);
The @allow_mail_to value contains the addresses to which form results can be sent, again as a spacedelimited list. If you include just a domain here, then any address on that domain is valid as a recipient. If
you’re using only one address, set the $max_recipients value to 1 to increase security.
@allow_mail_to = qw(you@your.domain some.one.else@your.domain
localhost);
Multiple recipients
You can also use the script to e-mail multiple recipients. To do so, an additional hidden input element is
needed in the HTML:
And in the script itself, two lines are changed. The @allow_mail_to value is removed, because it’s catered
for by the newly amended %recipient_alias. Both are shown here:
@allow_mail_to = ();
%recipient_alias = ('emailgroup =>
'your-name@your.domain,your-name@somewhere-else.domain');
Should a script be used for multiple groups of recipients, you need a unique value for each in the HTML
and to amend the %recipient_alias value accordingly:
%recipient_alias = ('emailgroup1' => 'your-name@your.domain,your-name@
somewhere-else.domain', 'emailgroup2' => 'foo@your.domain');
Script server permissions
Upload the script to your site’s cgi-bin. Once there, the script’s permissions must be set. Exactly how this
is achieved depends on what FTP client you’re using. Some enable you to right-click and “get info,” while
325
www.freepdf-books.com
Chapter 8
others have a permissions or CHMOD command buried among their menus. Consult your documentation and
find out which your client has. If you can, use the CHMOD command to set the octal numbers for the script
(thereby altering the file permissions) to 755. If you have to manually set permissions, do so as per the
screenshot to the right. Check that the script’s file extension matches that in your form element’s action
attribute (.pl or .cgi—the latter is usually preferred by servers). Also, you might want to amend your
script’s name (and update the form element’s action value accordingly), in an attempt to outfox automated
spammers. (This explains the rather odd name of the script in the screenshot below.)
Not all hosts require you to place CGI scripts in a cgibin directory: some prefer a cgi
directory, and some enable you to place such scripts
anywhere on the server. If in doubt, talk to your web
host’s support people about the specific
requirements for your account. Also note that not all
hosts enable CGI support, so if you want to use such
a script, check that it’s possible with your host before
you spend a load of time trying to set something up
that’s not permitted and won’t run anyway.
Sending form data using PHP
If your hosting company offers support for PHP, the most widely used server-side technology, there is no
need to install a CGI script such as FormMail. Everything can be done with PHP’s built-in mail() function.
As a minimum, the function requires the following three pieces of information:
The address(es) the mail is being sent to
The subject line
The message itself
An optional fourth argument to mail() permits you to send additional information in the e-mail headers,
such as from, cc, and bcc addresses, and to specify a particular character encoding (if, for instance, you
need to include accented characters or an Asian language in the e-mail). Unfortunately, spammers
frequently exploit this ability to add extra e-mail headers, so you need to check the form input for
suspicious content and stop the e-mail from being sent if any is found. A script written by fellow friends of
ED author David Powers does this for you automatically. Even if you have no experience working with
PHP, the following instructions should have you up and running quickly:
326
www.freepdf-books.com
Getting User Feedback
1. Copy process_mail.inc.php from the download files to the same folder (directory) as the page
containing the form. This is the PHP script that does all the hard work. You don’t need to make
any changes to it.
2. Save the page containing the form with a PHP extension—for instance, feedback.php. Amend the
opening form tag like this:
If you’ve read through Chapter 7, you’ll see that this layout is formed using techniques shown in the
“Creating a fixed-width wrapper,” “Placing columns within a wrapper,” and “Manipulating two structural divs
for fixed-width layouts” exercises.
Within the masthead div is a level-one heading with an empty span element. This is as per the imagereplacement method shown in the “Image-replacement techniques” section of Chapter 3. The CSS applied
to the elements (shown later in this section) effectively places the span over the text and sets the heading
image exported from the mock-up as its background.