Thursday, September 30, 2010

Outdated methods for hacking CSS documents

Historically, web designers have resorted to exploiting parsing bugs in order to get around
Internet Explorer problems. Perhaps the most famous of these is Tantek Çelik’s box model
hack, designed to get around Internet Explorer 5.x’s inability to correctly deal with the box
model: it places padding and borders within the defined content dimensions of a box,
rather than on the outside. In other words, a box with a width setting of 300px and
padding of 20px should take up a total width of 340 pixels in a compliant browser, but in
IE 5.x, it only takes up 300 pixels. Also, only 260 pixels are available for content, due to the
40-pixel padding being placed inside the defined width of the box.
Tantek’s hack works by exploiting a CSS-parsing bug. In the following code block, padding
is set in the rule, along with a width for Internet Explorer 5.x, which terminates the rule in
the voice-family lines. Compliant browsers continue reading, thereby using the second
width value to override the first. The net result is that all browsers show the box at the
correct width.
.box {
padding: 20px;
width: 340px;
voice-family: "\"}\"";
voice-family: inherit;
width: 300px;
}
A further rule is added by some designers to cater for Opera’s then-inability to read past
the voice-family lines—the “be nice to Opera” hack took advantage of Internet Explorer
5.x not understanding child selectors, and therefore used one to set the correct width in
that browser:
html>body .box {
width: 300px;
}
The box model hack itself was later simplified further, to the simplified box model hack (or
SBMH), which involved using a single backslash in the second pair to get Internet Explorer
5.x to terminate the rule:
.box {
padding: 20px;
width: 340px;
w\idth: 300px;
}

In a sense the opposite of the box model hack, the star HTML hack is also often seen, in
order to make only Internet Explorer see a rule:
* html .box {
background: #000000;
}
There are myriad other CSS hacks out there, but they won’t be explored here. Not only do
hacks mess up your otherwise clean and compliant style sheet, but they’re also not futureproof,
as evidenced when the star HTML hack stopped working upon the release of
Internet Explorer 7. Also, hacks often need overrides, as evidenced by the “be nice to
Opera” hack. A far better and more future-proof method is to ditch CSS hacks entirely,
instead making a totally clean style sheet for a website, and using conditional comments to
fix bugs in Internet Explorer

Dealing with Internet Explorer bugs

As mentioned elsewhere, Microsoft made a huge leap forward with Internet Explorer 7,
but it’s still not without its problems. Also, because Microsoft’s browser enjoyed such an
immense market share for so long, older versions remain in use for years, sometimes
enjoying a share of the market that manages to eclipse every other browser apart from the latest release of Internet Explorer. With this in mind, along with the sad fact that
Microsoft’s browser has been the least compliant one out there for a long time now, this
section is dedicated to exploring how to deal with the most common Internet Explorer
bugs. These are all worth committing to memory, because if you’re working on CSS layouts,
these bugs will affect your designs at some point, and yet most of the fixes are
extremely simple.

Installing multiple versions of browsers

One of the big problems when it comes to web design testing is that some browser manufacturers
don’t enable you to run multiple versions of their products. The two biggest
culprits here are, unsurprisingly, Microsoft and Apple, who presumably argue that as their
browsers rely on system-level code, they can’t provide standalone testing environments
for older releases. Luckily, enterprising developers have proven this to not be the case.
Online, there are now a number of sites that enable you to install standalone versions of
previous incarnations of Internet Explorer. By far the best is Tredosoft’s effort, which packages
everything up into a no-nonsense installer. This enables you to install standalones for
Internet Explorer versions from 6 way back to 3 (the following image shows an example of
three versions of Internet Explorer running simultaneously). Usefully, conditional comments
work fine, too, which wasn’t the case with earlier standalones. Download the
installer from www.tredosoft.com/Multiple_IE. Alternatively, you can manually install the
versions you require from Evolt (http://browsers.evolt.org/) and use the information
at Position Is Everything (www.positioniseverything.net/articles/multiIE.html) to
repair lost functionality.

In a similar vein, Michel Fortin has produced standalone versions of Safari for the Mac,
available from www.michelf.com/projects/multi-safari/. However, because of the
nature of WebKit (the application framework that’s the basis for Safari), there are limitations
regarding which versions of the browser can be run on which versions of Mac OS X.
David Hellsing of David’s Kitchen also notes in his “Browser Suite for Developers” article
(www.monc.se/kitchen/91/browser-suite-for-developers) that you can use the WebKit
nightly builds instead of the public downloads, in order to test in multiple versions of
Safari. Links are available from the article.
Elsewhere, things are simpler. For Firefox, different versions can happily live on the same
machine, although they can’t be run simultaneously, unless you start each version with a
different profile—see “Geek to Live: Manage Multiple Firefox Profiles,” by Gina Trapani
(www.lifehacker.com/software/firefox/geek-to-live--manage-multiple-firefox-å
profiles-231646.php), for how to do this on Windows; and “Running Multiple
Firefox Versions Concurrently,” by Jeroen Coumans (www.jeroencoumans.nl/journal/
multiple-firefox-versions), for how to do this on Mac OS X. Opera is even simpler: you
can install multiple versions and run them without having to do anything special.

A browser test suite

when various browsers were created, their approximate
share of the market, and the major problems they cause. However, it’s important to
note that the market is in continual change—just a quick look at Netscape’s fortunes
should be enough to prove that. Utterly dominant during the period when the Web first
started to become mainstream, its share of the market was decimated by the then-upstart
Internet Explorer, and it’s now all but vanished. The point, of course, is that you cannot
predict how the browser market will change, and although Internet Explorer is sitting
proud today, its share of the market has been hit hard in recent years by Firefox, and this
downward trend for Microsoft’s browser could continue . . . or not. Also, each year sees
new releases of web browsers, with new features and updated—but usually incomplete—
standards support.
All of this is a roundabout way of saying that you need to think hard about browsers when
you’re creating your work. Don’t only test sites in a single browser, and don’t use the most
popular for your starting point if it’s not the most standards-compliant. Instead, use a
browser with a good grasp of web standards for your first line of tests, until you’ve got
your templates working. I personally use the Gecko engine as a starting point—more
specifically, I favor Firefox as an initial choice of browser. Opera is also a decent choice,
and Mac users can probably get away with using Safari for initial tests.
Once the basic structure is up and running, I test in a range of alternate web browsers, typically
in the following order:

1. The other compliant browsers: Typically, I use Firefox as a starting point, although
sometimes I use Safari. Whichever one you choose to start in, it’s a good idea to
test in the other compliant browsers first. Sometimes, one will pick up a coding
error the others don’t, and it’s a good sanity check to ensure everything’s working
well. If you’re lucky, everything will work fine right away in all of these browsers, on
both Mac and Windows.

2. A browser in text mode: What I mean by this is testing the site without CSS, which
is a way of somewhat figuring out if it’s usable on alternate devices. Old hands
might use Lynx for this, but I instead use the Accessibility layout option of Opera’s
User mode (see the following screenshot). The Firefox Web Developer toolbar
(www.chrispederick.com) offers similar options.

3. Internet Explorer 7 for Windows: Although this release of Internet Explorer is a vast
improvement over previous efforts, it’s not as standards-compliant as the other
mainstream browsers. Therefore, tests need to be done to ensure everything’s
working properly, not least because Internet Explorer 7 is the most popular
browser in terms of market share. If things aren’t working right, conditional comments
need to be used (see the “Dealing with Internet Explorer bugs” section later
in the chapter).

4. Internet Explorer 6 for Windows: Previously the most popular browser, this release
is still in heavy use. Fairly compliant, it nonetheless has a raft of bugs, and complex
CSS layouts will almost certainly need a little tweaking to work properly, again via
the use of conditional comments. Note that because only Windows XP users can
upgrade from Internet Explorer 6 to 7 (7 being the native browser for Windows
Vista), a fair number of users—those with an earlier version of Windows—will likely
use 6 for some time to come.

5. Internet Explorer 5.5 for Windows: How far you go back, in terms of versions of
Internet Explorer, depends on your target market, the client’s budget, and general
expectations. Typically, I test the most recent three major versions of Microsoft’s
browser, due to their heavy usage. Internet Explorer 5.0 can be considered almost
extinct, however. Overall, Internet Explorer 5.5 has more problems than Internet
Explorer 6, although most of them are easy enough to work around. Generally, I
don’t aim to get sites working perfectly in this browser—a few cosmetic oddities
are acceptable, in my opinion, because there’s no point in compromising a totally
compliant site to make it more compatible for an aging browser whose market
share is in rapid decline. Ensuring content is accessible in the browser is essential,
however, and the primary concern when dealing with obsolete browsers.

6. Everything—all over again: When any major changes are made, you need to go back
through your browsers and make sure the changes haven’t screwed anything up.

There are other browsers out there, but the preceding list will deal with the vast majority
of your users. However, always try to find out the potential audience for a website to
ascertain whether you should place more focus on a particular browser. For example, if
authoring a site for a mostly Mac-based audience, it might make sense to use Safari as the
basis for testing, and perhaps even wheel out the long-canceled Internet Explorer 5 for
Mac, just to make sure your site works in it.
At each stage of testing, I recommend that you save HTML and CSS milestones on a very
regular basis. If something fails in a browser, create a copy of your files and work on a fix.
Don’t continually overwrite files, because it’s sometimes useful—and, indeed, necessary—
to go back to previous versions.
Whichever browsers you test in, it’s important to not avoid the “other side.” Windows
users have long seen the Mac as being inconsequential, but at the time of writing Safari
now counts for about 4% of all web users, and the trend for Mac sales (as a percentage of
the market) is upward. Usefully, there’s now a version of Safari for Windows, but even the
Mac and Windows versions of Firefox show slight differences in the way sites are handled
(mostly regarding text). Even worse, many Mac-based designers don’t test on a Windows
PC or in Internet Explorer, which has the bulk of the market. If you’re a Windows user, grab
a cheap Mac that’s capable of running Mac OS X (such as a second-hand iBook or a Mac
mini), and if you’re a Mac user, either grab a cheap Windows PC to test with or run
Windows as a virtual machine (via Parallels Desktop or VMware Fusion) on an Intel Mac or
using Virtual PC if you have a PPC-based machine. (You can also use Boot Camp on an Intel
Mac, but that requires booting back and forth between Windows and Mac OS X, so using
a virtual environment is more efficient unless you have two computers.) Linux users also
have a range of browsers to test on. Firefox is popular on that platform, and Safari is a
rough analog for Konqueror. It is worth noting, however, that the default fonts with Linux
vary considerably from those that you’d expect on a Mac or Windows PC—so you should
always define fallback fonts accordingly, and test in Linux if possible. See Chapter 3 for
more on font stacks.

DEALING WITH BROWSER QUIRKS : Weeding out common errors

Testing in browsers isn’t everything; in fact, you may find that your site fails to work for no
reason whatsoever, tear your hair out, and then find the problem lurking in your code
somewhere. With that in mind, you should either work with software that has built-in and
current validation tools (many have outdated tools, based on old versions of online equivalents),
or bookmark and regularly use the W3C’s suite of online tools: the Markup
Validation Service (http://validator.w3.org/), CSS Validation Service (http://jigsaw.
w3.org/css-validator/), Feed Validation Service (http://validator.w3.org/feed/),
Link Checker (http://validator.w3.org/checklink), and others (www.w3.org/QA/Tools/)
as relevant.
Other useful online services include WDG Link Valet (www.htmlhelp.com/tools/valet/),
WDG HTML Validator (www.htmlhelp.com/tools/validator/), and Total Validator (www.
totalvalidator.com/). Accessibility-oriented services include HP’s Color Contrast Verification
Tool (www.hp.com/hpinfo/abouthp/accessibility/webaccessibility/color_tool.html);
Etre’s Colour Blindness Simulator (www.etre.com/tools/colourblindsimulator/); and
the Cynthia Says Portal Tester (www.cynthiasays.com/fulloptions.asp), which can
aid you in Section 508 and WAI (Web Accessibility Initiative—see www.w3.org/WAI/)
compliance.
Here are some of the more common errors you might make that are often overlooked:

Spelling errors: Spell a start tag wrong and an element likely won’t appear; spell an
end tag wrong and it may not be closed properly, wrecking the remaining layout. In
CSS, misspelled property or value names can cause rules—and therefore entire layouts—
to fail entirely. British English users should also remember to check for and
weed out British spellings—setting colour won’t work in CSS, and yet we see that
extra u in plenty of web pages (which presumably have their authors scratching
their heads, wondering why the colors aren’t being applied properly).

Incorrect use of symbols in CSS: If a CSS rule isn’t working as expected, ensure
you’ve not erred when it comes to the symbols used in the CSS selector. It’s a
simple enough mistake to use # when you really mean . and vice versa.

Lack of consistency: When working in XHTML, all elements and attributes must be
lowercase. In CSS, tag selectors should also be lowercase. However, user-defined id
and class values can be in whatever case the author chooses. Ultimately, decide
on a convention and stick to it—always. If you set a class value to myvalue in CSS
and myValue in HTML, chances are things won’t work. For the record, I prefer
lowerCamelCase, but there’s no reason for choosing a particular case.

Not closing elements, attributes, and rules: An unclosed element in HTML may
cause the remainder of the web page (or part of it) to not display correctly.
Similarly, not closing an HTML attribute makes all of the page’s content until the
next double quote part of the attribute. Not closing a CSS rule may cause part or
all of the style sheet to not work. Note that CSS pairs that aren’t terminated with a
semicolon may cause subsequent rules to partially or wholly fail. A good tip to
avoid accidentally not closing elements or rules is to add the end tag/closing
bracket immediately after adding the start tag/opening bracket. This also helps to
avoid incorrect nesting of elements.

Multiple rule sets: In CSS, ensure that if you use a selector more than once, any
overrides are intentional. It’s a common error for a designer to duplicate a rule set
and have different CSS property values conflicting in different areas of the CSS.
Errors with the head and body elements: As stated earlier in the book, HTML content
should not appear outside of the html element, and body content should not
appear outside of the body element. Common errors with these elements include
placing content between the closing head element tag (</head>) and the body start
tag (<body>), and including multiple html and body elements.

Inaccessible content: Here, we’re talking in a more general sense, rather than about
accessibility for screen reader users. If you create a site with scrollable areas,
ensure users can access the content within, even if browser settings aren’t at their
defaults. Problems mostly occur when overflow is set to hidden. Similarly,
textarea elements that don’t have properly marked-up cols and rows settings
will often be tiny when viewed without CSS (these attributes are functional as well
as presentational). The same is true for text input fields without a defined size
attribute.

Dead links: These can take on many forms, such as a link to another page being
dead, an image not showing up, or external documents not being accessible by the
web page. If a JavaScript function isn’t working for some reason, try checking to see
whether you’ve actually linked it—in some cases, the simpler and most obvious
errors are the ones that slip through the net. Also, if things aren’t working on a live
site, check the paths—you may have accidentally created a direct link to a file on
your local machine, which obviously won’t be accessible to the entire Internet.
Spaces within href values or the original file names can also be accidentally overlooked.

Whitespace errors: In CSS, do not place whitespace between class/id indicators and
the selector name, or between numerals and units for measurements. However, do
not omit whitespace from between contextual selectors, otherwise you’ll “combine”
them into a new, probably unknown, one.

Using multiple units: In CSS, a value can only accept a single unit—the likes of
50%px can cause a rule to partially or wholly fail.

Wednesday, September 29, 2010

Contact details structure redux

In this chapter, and in the microformats exercise, the address and other contact details
were styled using paragraphs and line breaks. An alternative structure, which perhaps has
greater integrity from a semantic standpoint, is to use a definition list, with further nested
definition lists within. At the top level, the term is Contact details and the definition is
the actual contact details. At the next level, there are two terms, Mail and Telephone/fax,
each with respective definitions. For the latter, the definition has a third definition within,
providing term/definition pairs for the different types of telephone and fax numbers.
<dl>
<dt>Contact details</dt>
<dd>
<dl class="vcard">
<dt>Mail</dt>
<dd>
<address>
<strong>Company name</strong><br />
00, Street Name<br />
Town or City<br />
County or Region<br />
Postal/ZIP code<br />
Country name
</address>
</dd>
<dt>Telephone/fax</dt>
<dd>
<dl>
<dt>Tel:</dt>
<dd>+1 (0)0000 555555</dd>
<dt>Fax:</dt>
<dd>+1 (0)0000 555556</dd>
<dt>Mobile/cell:</dt>
<dd>+1 (0)7000 555555</dd>
</dl>
</dd>
</dl>
</dd>
</dl>
For the CSS, use the existing rules from using-microformats.css in the usingmicroformats-
starting-point folder, and the .vcard rule from the previous exercise.
The following rules can then be used to style the definition list and its contents.
First, the dt rule is used to style the Contact details text (as per the h1 element in the
previous exercise), with the dd dt rule providing override styles for dt elements within a
dd element. This rule is aimed to style the equivalent of the h2 elements from the previous
exercise: the Mail and Telephone/fax text. The dd dd dt rule provides a third level of
override, styling the dt elements within the telephone/fax definition list. Also, because the
dt/dd pairs are displayed in a linear fashion by default, the dd dd dt rule floats the
telephone/fax list dt elements to the left, enabling the dd elements to stack to the right in
each case.
dt {
font: bold 1.5em/1.2em Arial, Helvetica sans-serif;
margin-bottom: 1.2em;
text-transform: uppercase;
}
dd dt {
font: bold 1.2em/1.5em Arial, Helvetica sans-serif;
text-transform: uppercase;
margin-bottom: 0;
}
dd dd dt {
float: left;
padding-right: 5px;
display: block;
text-transform: none;
}
The next two rules deal with formatting and fine-tuning of the text. The address rule adds
the gap between the bottom of the address and the telephone/fax heading, along with
reverting the address element content to normal text (it’s italic by default). The second
rule in the following code block defines a font for the address element content and the
content of the telephone/fax definition list’s term and definition.
address {
padding-bottom: 1.5em;
font-style: normal;
}
address, dd dd dt, dd dd dd {
font: 1.2em/1.5em Verdana, Arial, sans-serif;
}
With these styles added, the contact details look virtually identical to those in the exercise.
At this point, you can add hooks for the vCard as per steps 2 and 3 of the “Using microformats
to enhance contact details” exercise. See contact-details-structure-redux.css
and contact-details-structure-redux.html in the chapter 8 folder for the completed
files.
We’ve covered plenty of ground here, so now it’s time to leave the subject of collecting
user feedback and progress to the next chapter, which explores how to test your websites
and deal with common browser bugs.

How to use microformats to enhance a set of contact details.

1. Add a surrounding div. Open using-microformats.
html, and place a div with a class value of vcard
around the contact details content, as shown (truncated)
following:
<h1>Contact details</h1>
<div class="vcard">
<h2>Mail</h2>
[...]
Mobile/cell: +1 (0)7000 555555</p>
</div>

2. Structure the address. Marking up the address is fairly
simple, and few changes are required to the general
structure of the code. However, because each individual set of information requires
its own container, and the best way of creating a container for the address is to
place it within a block element of its own, the company name and the address each
need their own paragraphs, rather than a line break separating the two. The organization’s
paragraph is then given a class value of fn org. Here, fn stands for “full
name” and org defines that the name belongs to an organization, rather than a
person.
The address paragraph’s class value is adr, and each line of the address is placed
within a span element. The various class values assigned to the spans denote
which element of the address the content refers to, and those are all straightforward
to understand. However, address books—and therefore microformats—
enable you to distinguish between different types of data. For example, you can
have a work address or a home address. This can be defined by adding the relevant
word (e.g., work) and wrapping it in a span with a class value of type, thereby
defining the type for the parent property. In this case, the address is being defined
as a work address.
For cases when you don’t want this information shown on the web page (which will
likely be most of the time—after all, adding a lowercase “work” in front of the
street name hardly looks great), add a second class value, hidden. Later, CSS will
be used to make content with a hidden value invisible.
<h2>Mail</h2>
<p class="fn org">Company name</p>
<p class="adr">
<span class="type hidden">work</span>
<span class="street-address">00, Street Name</span><br />

<span class="locality">Town or City</span><br />
<span class="region">County or Region</span><br />
<span class="postal-code">Postal/ZIP code</span>
<span class="country-name">Country name</span>
</p>

3. Structure the telephone/fax details. Each definition for a telephone number
requires its own container, and so the single paragraph must be split into three, as
shown in the following code block. Each paragraph’s class value should be tel. As
with the address, a span with a class value of type hidden is used to define the
type for each parent property. For tel, there are various options available, including
work, home, fax, cell, pager, and video. Should duplicate types be required
(such as for a work fax), two type spans are added. As for the contact number
itself, that’s placed in a span element with a class value of value.
<h2>Telephone/fax</h2>
<p class="tel">
Tel: <span class="type hidden">work</span>
<span class="value">+1 (0)0000 555555</span></p>
<p class="tel">
Fax: <span class="type hidden">fax</span>
<span class="type hidden">work</span>
<span class="value">+1 (0)0000 555556</span></p>
<p class="tel">
Mobile/cell: <span class="type hidden">cell</span>
<span class="value">+1 (0)7000 555555</span></p>
4. Style headings and paragraphs. The style sheet,

using-microformats.css, already has some
defined styles, which do the usual removal of
margins and padding and setting of the default
font size. The body rule also adds some padding
to the page content so that it doesn’t hug the
browser window edges. To this, add the following
three rules, which style the headings and paragraphs.
Both headings are rendered in uppercase
Arial, helping them to stand out, aiding visual
navigation of the contact details.
h1 {
font: bold 1.5em/1.2em Arial, Helvetica
å sans-serif;
margin-bottom: 1.2em;
text-transform: uppercase;
}
h2 {
font: bold 1.25em/1.44em Arial, Helvetica sans-serif;
text-transform: uppercase;
}
p {
font-size: 1.2em;
line-height: 1.5em;
margin-bottom: 1.5em;
}

5. Hide hidden elements. As noted in steps 2 and 3, some information requires a type
to be defined for it, but as you can see in the previous image, this is displayed
onscreen like any other content. This is why the hidden value was also applied to
the relevant span elements. By adding the following rule, these spans are made
invisible.
.hidden {
display: none;
}

6. Deal with margin issues. Because the telephone
details are each in an individual paragraph, they
each have a bottom margin, and this makes the layout
look awful. The same problem also affects the
company name paragraph. However, because each
paragraph has its own class attribute value, it’s
easy to remove the bottom margins from the relevant
paragraphs using the following rule:
.tel, .fn {
margin-bottom: 0;
}

7. Embolden the company name. Balance-wise, the
company name could do with standing out more. This is within a paragraph that
has a class value of org, so making the contents bold is child’s play—just add the
following rule.
.org {
font-weight: bold;
}

8. Finally, style the vcard div via the following rule. This sets a background color,
width, border, and padding, but perhaps the most important property here is
margin-bottom. This is required because the margins from paragraphs with a tel
class were removed in step 6. When you add a bottom margin to the vcard div, the
typical spacing you’d expect after a paragraphs returns.
.vcard {
width: 200px;
background: #eeeeee;
border: 1px solid #cccccc;
padding: 8px;
margin-bottom: 1.5em;
}
Note that further simplification of some elements of the code shown in the exercise is
possible. For example, where you have the Fax line, the type span could be directly
wrapped around the relevant label, and the hidden class removed.
Where before you had the following:
<p class="tel">
Fax: <span class="type hidden">fax</span>
<span class="type hidden">work</span>
<span class="value">+1 (0)0000 555556</span></p>
you’ll now have this:
<p class="tel">
<span class="type">Fax</span>:
<span class="type hidden">work</span>
<span class="value">+1 (0)0000 555556</span></p>
The same is also true for the Mobile/cell line.
Note also that this is a relatively new technology, so it’s not without its drawbacks. As mentioned
earlier, some details are not carried through to some address books. Also, the need
to hide extra data is problematic, since under some circumstances (such as in text readers),
it will be displayed, which could lead to confusion. However

Using microformats to enhance contact information

As shown in the previous section, user feedback may come in the form of a telephone call
or letter, rather than an e-mail, and therefore you should always add other forms of contact
details to a website—even if the site is an online store, customers will need other ways
to get in touch (faceless multinational organizations, take note). In the most basic sense,
these can be marked up by using some headings and paragraphs, as follows:
<h1>Contact details</h1>
<h2>Mail</h2>
<p><strong>Company name</strong><br />
00, Street Name<br />
Town or City<br />
County or Region<br />
Postal/ZIP code<br />
Country name</p>
<h2>Telephone/fax</h2>
Tel: +1 (0)0000 555555<br />
Fax: +1 (0)0000 555556<br />
Mobile/cell: +1 (0)7000 555555</p>
Now, there’s nothing at all wrong with the previous block of code: it’s valid, it does the job
perfectly well, and it’s semantically sound, which also means it’s easy enough to style using
CSS. However, by utilizing microformats, the page’s functionality can be enhanced without
compromising the markup.
More about microformats can be found at the microformats website at www.
microformats.org, and in the book Microformats: Empowering Your Markup for Web 2.0,
by John Allsopp, so I won’t dwell on them too much. In short, though, microformats provide
a way of adding commonly used semantics to web pages, working with common technologies,
such as XHTML. For the example, you’re going to see how to take a basic set of
contact details and then use microformats to provide users with a means of efficiently
downloading and storing the information as a vCard—the vCard format being that
commonly used by address books). The semantic information is also of use to any other
application that is microformat-aware—for example, some Firefox plug-ins are able to
auto-detect microformat information on any web page and enable a user to browse and
manipulate it.

 

Using e-mail to send form data

In rare cases, it may not be possible to set up a form to send form data (although even
most free web hosts tend to provide users with some kind of form functionality, even if it’s
a shared script that doesn’t allow a great deal of customization). If you find yourself in this
sticky situation, it’s possible to use a mailto: URL for the form’s action attribute value.
This causes browsers to e-mail the form parameters and values to the specified address.
<form method="post" action="mailto:anemailaddress@somewhere.com"
å enctype="text/plain">
This might seem a simpler method than messing around with CGI scripts, but it has major
shortfalls:
Some browsers don’t support mailto: as a form action.
The resulting data may arrive in a barely readable (or unreadable) format, and you
have no control over this.
This method isn’t secure.
The user won’t be redirected and may therefore not realize data has been sent.
That last problem can be worked around by adding a JavaScript alert to the form start tag:
<form method="post" action="mailto:anemailaddress@somewhere.com"
å enctype="text/plain" onsubmit="window.alert('This form is being
å sent by email. Thank you for contacting us.')">
Of course, this relies on JavaScript being active on the user’s browser—but, then again, this
is a last resort.

Css Tutorial : 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:
<input type="hidden" name="subject" value="Contact form from
å website" />
<input type="hidden" name="redirect"
å value="http://www.yourdomain.com/contact-thanks.html" />
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 I tend to make this page a duplicate of
my 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).
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 space-delimited 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:
<input type="hidden" name="recipient" value="emailgroup" />
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
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 adjacent screenshot.)

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 my 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:
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:
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">

3. At the top of the page, insert the following PHP code block above the DOCTYPE.
Although I’ve warned you elsewhere in the book never to place any content above
the DOCTYPE, it’s perfectly safe to do so in this case, because the PHP code doesn’t
produce any HTML output.
<?php
if (array_key_exists('SUBMIT', $_POST)) {
//mail processing script
$to = 'me@example.com'; // use your own email address
$subject = 'Feedback from website';
// list expected fields
$expected = array('realname', 'email', 'phone', 'message');
// set required fields
$required = array('realname', 'email', 'message');
$headers = 'From: My website<feedback@example.com>';
$process = 'process_mail.inc.php';
if (file_exists($process) && is_readable($process)) {
include($process);
}
else {
$mailSent = false;
mail($to, 'Server problem', "$process cannot be read", $headers);
}
}
?>

4. This script begins by checking whether the PHP $_POST array has been set. This
happens only when a user clicks the form’s Submit button, so this entire block of
code will be ignored when the page first loads. It sets the address to which the
e-mail is to be sent and the subject line. It then checks that all required fields have
been filled in, and sends the form input for processing by process_mail.inc.php.
If the mail processing file can’t be found, the script e-mails an error message
to you.
To adapt this script to your own form, you need to change some of the values, as
explained in upcoming steps.

5. Change SUBMIT in the second line of the script to the same value as the name of the
form’s Submit button.

6. Replace me@example.com with the e-mail address that the feedback is to be sent to.
Make sure the address is in quotes, and that the line ends with a semicolon.
If you want to send the e-mail to multiple addresses, separate them with commas
like this:
$to= 'me@example.com, him@example.com, her@example.com';

7. Replace the content inside the quotes in the following line (Feedback from website)
with whatever you want the subject line to say.

8. Next, list the name attributes of each form element as a comma-separated list
between the parentheses in the following line:
$expected = array('realname', 'email', 'phone', 'message');
This tells the script what form input you’re expecting. This is very important, as it
prevents malicious users from trying to pass unexpected—and possibly dangerous—
data through your form. Any form field not included in this list will be
ignored, so make sure you update the list whenever you add a new field to a form.
Note that the commas go outside the quotes. You can use single or double quotes.
It doesn’t matter as long as each set of quotes is a matching pair.

9. The next line of code looks very similar:
$required = array('realname', 'email', 'message');
This is used to check whether all required fields have been filled in. You’ll notice
that I’ve omitted phone from the list, so the script will treat it as optional. The order
of items in the $expected and $required arrays is not important, but it makes
maintenance easier if you use the same order as they appear in the form.

10. The next line looks like this:
$headers = 'From: My website<feedback@example.com>';
This sets the e-mail’s From: header. Change My website <feedback@example.com>
to the name and e-mail address that you want the e-mail to be sent from.
There are many additional headers you can add to an e-mail, such as Cc, or Bcc.
You can also set the encoding to UTF-8 (for messages that require accents or Asian
languages). The following example shows how to add a cc address and UTF-8
encoding:
$headers = "From: My website<feedback@example.com>\r\n";
$headers .= "Cc: copycat@example.com\r\n";
$headers .= "Content-type: text/plain; charset=UTF-8";
There are a couple of important points to note about this code. First, the headers
are enclosed in double quotes. This is because each header must be on a separate
line, and the characters \r\n at the end of the first two lines represent a carriage
return and new line when enclosed in double quotes. You need these two characters
at the end of each header except the last one. Second, there’s a period in front
of the equal sign in the second and third lines. This has the effect of stringing all
the values together so the script treats the headers as a single block.
One nice touch with e-mail headers is to put the user’s e-mail address in the
Reply-to field of the e-mail, so all the user has to do is click Reply in their e-mail
program to send a message back to the right person. Unfortunately, this is frequently
used by spammers to inject malicious code into your script. The code in
process_mail.inc.php filters out potential attacks and inserts the sender’s e-mail
address only if it’s safe to do so. Consequently, there is no need to add a Reply-to
header yourself; it’s done automatically by the script.
If you want to use a special encoding, such as UTF-8, for your e-mails, make sure
the web page containing the form uses the same encoding in its meta tag.
You don’t need to use all these headers. Just remove the complete line for any you
don’t want.

11. You don’t need to make any other changes to the code you inserted in step 3.

12. The script in process_mail.inc.php processes the form input and sends the e-mail
if there are no problems. The final stage is to let the user know what happened.
Immediately above the form in the main part of your page, insert the following
code:
<?php
if ($_POST && isset($missing) && !empty($missing)) {
?>
<p class="warning">Not all required fields were filled in.</p>
<?php
}
elseif ($_POST && !$mailSent) {
?>
<p class="warning">Sorry, there was a problem sending your message.
Please try later.</p>
<?php
}
elseif ($_POST && $mailSent) {
?>
<p><strong>Your message has been sent. Thank you for your feedback.
</strong></p>
<?php } ?>
This block of code displays an appropriate message depending on the outcome.
Put whatever messages you like in place of the ones shown here, and add the following
rule to your style sheet:
.warning {
font-weight: bold;
color: #ff0000;
}
If you’re using a visual HTML editor like Dreamweaver, all three messages will
appear to be displayed at once. However, when you load the page onto your website,
the PHP conditional logic hides all the messages, and only the appropriate one
is displayed after the user submits the form.

13. Save the page and upload it to your hosting company, together with process_
mail.inc.php. Test it. In a few moments, you should receive the test message in
your inbox. That’s all there is to it!
If you get error messages or a blank screen, it means you have made a mistake in
the script. Check the commas, quotes, and semicolons carefully. If you get a message
saying that process_mail.inc.php cannot be read, it probably means that
you have forgotten to upload it, or that it’s not in the same folder as the form.

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 non-tabular 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:
<fieldset>
<legend>Personal information</legend>
<table class="formTable" cellpadding="0" cellspacing="0" border="0"
å summary="A contact details form.">
<tr>
<th scope="row">
<label for="realname">Name</label></th>
<td><input class="formField" type="text" id="realname"
å name="realname" size="30" /></td>
</tr>
<tr>
<th scope="row"><label for="email">Email address</label></th>
<td><input class="formField" type="text" id="email" name="email"
å size="30" /></td>
</tr>
<tr>
<th scope="row"><label for="phone">Telephone</label></th>
<td><input class="formField" type="text" id="phone" name="phone"
å size="30" /></td>
</tr>
</table>
</fieldset>

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 to the
right 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;
}
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.
<form action="http://www.yourdomain.com/cgi-bin/FormMail.cgi"
å method="post">
<fieldset>
<legend>Personal information</legend>
<div class="row clearFix">
<label for="realname">Name</label> <input class="formField"
å type="text" id="realname" name="realname" size="30" />
</div>
<div class="row clearFix ">

<label for="email">Email address</label> <input class="formField"
å type="text" id="email" name="email" size="30" />
</div>
<div class="row clearFix ">
<label for="phone">Telephone</label> <input class="formField"
å type="text" id="phone" name="phone" size="30" />
</div>
</fieldset>
</form>
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;
}

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):
<input class="formField" tabindex="11" type="text" id="realname"
å name="realname" size="30" />
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.
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:
<input type ="image" src="submit.gif" height="20" width="100"
å alt="Submit form" />
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;
}
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 (e.g., 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.
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.

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, I’m not a
fan 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, and
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:
<form action="http://www.yourdomain.com/cgi-bin/FormMail.cgi"
å method="post">

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 multiplechoice
options; and submit, which is used for the all-important 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.
<form action="http://www.yourdomain.com/cgi-bin/FormMail.cgi"
å method="post">
<p><strong>Name</strong><br />
<input type="text" name="realname" size="30" /></p>
<p><strong>Email address</strong><br />
<input type="text" name="email" size="30" /></p>
<p><strong>Telephone</strong><br />
<input type="text" name="phone" size="30" /></p>
<p><strong>Are you a Web designer?</strong><br />
<input type="radio" name="designer" value="yes" />Yes |
å <input type="radio" name="designer" value="no" />No</p>
<p>What platform do you favor?<br />
<select name="platform">
<option selected="selected">Windows</option>
<option>Mac</option>
<option>Linux</option>
<option>Other</option>
</select></p>
<p><strong>Message</strong><br />
<textarea name="message" rows="5" cols="30"></textarea></p>
<p><input type="submit" name="SUBMIT" value="SUBMIT" /></p>
</form>
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 (i.e., 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.)Long-time 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, hence its absence from the examples in this chapter. However,
if you want to add such a button, you can do so by using the following code:
<input type="reset" name="RESET" value="RESET" />


Improving form accessibility

Although there’s an onscreen 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.
<p><label for="realname">Name</label><br />
<input type="text" name="realname" id="realname" size="30" /></p>
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.
<fieldset>
<legend>Personal information</legend>
<p><label for="realname">Name</label><br />
<input type="text" id="realname" name="realname" size="30" /></p>
<p><label for="email">Email address</label><br />
<input type="text" id="email" name="email" size="30" /></p>
<p><label for="phone">Telephone</label><br />
<input type="text" id="phone" name="phone" size="30" /></p>
</fieldset>
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.

Adding tabindex attributes

The tabindex,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 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.

GETTING USER 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.
<a href="mailto:someone@your.domain">Click to email!</a>
It’s possible to take this technique further. You can define multiple recipients by using a
comma-separated list, and 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 (&amp;). Note that spaces within the subject should also
be encoded (as %20).
<a href="mailto:someone@your.domain,someoneelse@your.domain?subject=
åContact%20from%20website&amp;cc=bigboss@your.domain">Click
å to email!</a>
Although this may sound great, there are several problems with such a system. 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), I recommend using forms for any
complex website feedback, which we will come to later on in this chapter. For the third
issue (browser support for the more advanced mailto: options), I 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

Adding padding, margins, and backgrounds to a layout

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

2. 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, and so 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;
}

















3. 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 add-starting-point folder (a white-to-lightgray
vertical gradient) to tile horizontally at the bottom of the div: 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 add-starting-point folder (a white-to-lightgray
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;
}















4. 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.
Secondly, 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;
}

Scrollable content areas with CSS

Although iframes can be useful for practical reasons, many designers use them for aesthetic
reasons, in order to provide a lot of information on a single page. For example,
iframes are popular for lists of news items because they enable many hundreds of lines of
text to be contained in a small area. However, if this is your reason for using an iframe,
you’re better off replacing it with a div and using CSS to control the overflow. If you use
this method, the content will remain part of the web page, which is better for accessibility
and site maintenance.
To do this, create a div with a unique class value:
<div class="scrollableContent">
[content...]
</div>
Then style it in CSS—the rule provides the div’s dimensions and determines how the div’s
overflow works:
.scrollableContent {
width: 200px;
height: 200px;
overflow: auto;
}
When overflow is set to auto, scroll bars only appear when the content is too large for the
set dimensions of the div. Other available values are hidden (display no scroll bars),
scroll (permanently display both scroll bars), and visible (render content outside of the
defined box area). Adding some padding, especially at the right-hand side of the scrollable
content box, helps improve the area aesthetically, ensuring that content doesn’t hug the
scroll bar.
.scrollableContent {
width: 200px;
height: 200px;
overflow: auto;
padding: 0 10px 0 0;
}
Note that by also using PHP includes (see PHP Solutions, by David Powers, for more on
those), you can even make scrollable content separate from the main web page, thereby
emulating another aspect of an iframe, but without resorting to using frames at all.
<div class="scrollableContent">
<?php @include $_SERVER['DOCUMENT_ROOT'] .
å "/include/document-name.php"; ?>
</div>

In this code block, @ suppresses errors, so if it didn’t work, you’d receive no indication—
removing @ would show any errors. Also, the document root setting sets the include to
take the HTML/document root instead of the server root as the starting point for looking
for the included file (when the file path starts with a /), so be aware of that when defining
paths. An alternative would be to use a relative path, such as include/document-name.
php. This would work without pointing to the server at the document root (so long as the
path was correct).
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.
<object data="a-file.html" type="text/html">
<p>[alternate content]</p>
</object>
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; however, this setting doesn’t work in Internet
Explorer and Opera.

Working,with,internal,frames (iframes)

The only type of frames in general use today are iframes. These enable you to update a
page section without reloading the rest of it. Popular sites using iframes include
Newstoday (www.newstoday.com/) and Pixelsurgeon (www.pixelsurgeon.com/), the latter
of which uses a small inline frame to display its news feed.
In a more general sense, this can be handy for enabling users to update a portion of a
site’s design without touching the rest of the design, and without resorting to a costly content
management system. However, there are superior and more accessible alternatives to
this system, as you’ll see later in the chapter.
An iframe can be placed anywhere within a web page. Its available attributes are outlined
in Appendix A (XHTML Reference), but two worth mentioning here are width and height,
which define the dimensions of the iframe. Set these with caution, because it’s annoying if
an iframe is bigger than the viewable area, or if the content of the iframe is too big for its
defined dimensions. Note that these attributes can be omitted from HTML and instead
defined in CSS (by way of an iframe tag selector or by applying a class to the iframe).
Here’s some example code for an iframe:
<iframe src="internal_news.html" name="news" width="200" height="200"
å scrolling="yes" frameborder="0">Your browser doesn't support
å iframes. Please <a href="internal_news.html">click here
å to see the iframe's content</a>.</iframe>
Note the succinct content for the iframe, which enables non-frames-compatible devices to
directly access the content of the iframe—compliant devices ignore this.

Css Tutorial : How to create a fixed-width div

1. Set 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.
@import url(create-a-fixed-width-wrapper.css);


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;
}
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,

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. With
tables, cells are used to lay out a design and are merged, split, chopped, and changed until
everything works visually. But 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.
For basic page structure, you mostly work with the div element. This element has been
around for some time, but used to be used for aligning text left, right, or centrally.
However, its real purpose is as a divider element, used to divide a document into blocklevel
groups or divisions. Therefore, in CSS-based layouts, the div element’s role is pivotal:
a number of divs are added to the web page in logical order, creating the basic structure;
each is provided with a unique id relating to its purpose; and the divs are then styled to
provide spacing, padding, backgrounds, and so on.

Anatomy of a layout: Tables vs. CSS

To use a fine art analogy, working with tables is like painting by numbers: you create a
skeleton layout and then fill in the gaps with the content of choice. And, like painting by
numbers, a lot of work is required to change the layout after it’s completed. Working with
CSS is more akin to sculpting with clay: you begin with something simple and then gradually
fashion your layout. Making changes, tweaks, and even additions at a later date is simpler,
and the whole process feels more organic.
Long-time web designers may feel intimidated by CSS because they don’t initially have the
skeleton layout of table borders to work with. In some ways, CSS sits at the extremes of
web technologies, being both very graphic and design-like (in its flexibility), but also quite
technical (in how it’s created). Tables tend to sit in the middle of these two extremes.
However, once you get the hang of CSS workflow, it soon becomes second nature. Now,
we’ll look at how to create a web page structure, and we’ll then recap the CSS box model.

Workflow for CSS layouts

Many designers use CSS for styling fonts, but few venture further. 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.
Before we begin, it is worth mentioning that some browsers have problems with CSS, and
this is often given as a reason to not proceed with CSS-based layouts. Of those browsers
still in widespread use, Internet Explorer 6 (and the increasingly rare 5.x) for Windows
causes the most frustration; however, that browser’s usage is in terminal decline. And
although Safari, Opera, Firefox, and Internet Explorer 7 don’t always see eye to eye, their differences are generally slight. For supporting earlier browsers and dealing with bugs,
there are usually simple workarounds anyway (see Chapter 9), leading me to believe that
many naysayers of CSS are negative because they don’t know how to create such layouts.

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 place the elements within the web page
(first comes the masthead, then the navigation, then the content, etc.). Each element is
then styled to suit.
Using CSS for layout instead of tables is one way of working toward this ideal. 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. Because of the way table-based layouts are created, most
designers aren’t concerned with how the document is structured—merely how it looks.
Therefore, although one element may follow another visually onscreen, that may not be
the case when you look at the document’s code. (Also, tables tend to encourage superfluous
markup, which can also hamper accessibility.) When working with CSS, the structure of
the web page isn’t compromised.

Layout technology: Tables vs. CSS

Unless you’re the sort of person who favors very basic web pages, with most elements sitting
underneath each other, you’ll need to employ some kind of layout technology when designing your web pages. Historically, web designers tended to use tables for doing this,
combined with invisible GIFs (sometimes called spacers or shims) to stretch table cells to
the required size. In the early 2000s, CSS layouts gained a foothold, and now more and
more designers are moving toward CSS as a means of page layout.
With few exceptions, pretty much everything you can do with a table can be done faster,
better, and with a greater emphasis on accessibility when using CSS. With content and
design separated, it’s much easier to tweak or rework a website, because you’re editing an
external document that controls spacing and positioning, rather than messing around with
complex tables. We discuss one of CSS’s major benefits in this regard, how it encourages
logical element placement, in the next section. Tables should really be reserved for their
original purpose: formatting tabular data.

Fixed vs. liquid design

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.
In a similar fashion, it’s possible to design fixed-width sites for the Web. The earlier shot of
the Thalamus Books site is an example of this. Fixed-width sites are beneficial in that they
enable you to position elements exactly on a web page. 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).
You can get around this limitation by creating a liquid web design—one that stretches with
the web browser window. The benefit of a liquid design is that it’s irrelevant what resolution
the end user’s machine has—the design stretches to fit. The drawback is that you
have to be mindful when designing 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.
Generally speaking, largely text-based sites tend to work best with liquid layouts, although
you have to take care to ensure the content area is always readable. (I’ve seen numerous
liquid sites where the text spans the entire web page width, which is tricky enough to read
at 8005600, let alone on larger monitor resolutions.) Sites that are largely image-based in
nature (such as portfolios and many online magazines) tend to work better as fixed websites.
For instance, for any site with fixed-width images at the top of text columns (common
for online magazines), the images would not sit snugly within the columns if the
layout were liquid, and could instead end up lost among large areas of whitespace.
Overall, though, there are no hard-and-fast rules and, despite what some designers might
claim, neither fixed nor liquid design is better than the alternative. You should use whatever
technique is suitable for each project you work on. Later in the chapter, you’ll see various
methods for creating strict, fixed layout skeletons, liquid designs, and combinations of
the two.