Accessible HTML standards

The following explanations are mandatory knowledge for any Front End Developer working on a project that has to fulfil the accessibility guidelines1 set by the W3C2 and enforced by the UK Government Standards3 or the US Section 508 4standards.

Accessibility means making the web site accessible for everybody, regardless of software, hardware or mean of web access. Surfers can use web sites with browsers, text browsers, switch access or screen readers. An accessible web site has to ensure that each of these ways can be used to reach the same goal.

This does not mean that the web site has to be bland and boring, it means that the HTML has to be good and understandable for even the most basic means; more visual experience or usability enhancing elements get added later.

This is nothing new, all it takes is some more discipline of the HTML scripter.

Write well-formed HTML

HTML that is not well-formed will cause a lot of assistive technology to choke. That is why the HTML developed has to adhere to one of the HTML standards defined by the W3C. This can be bland HTML 4.05 or even 3.26 if you need to cater older browsers with as visually appealing results as current ones, or xHTML7, if you want your HTML to be readable and parseable for XML Software.

In any case, the HTML needs to be validated either via the Homesite validator or the W3C validator8.

Set the DOCTYPE

By defining the correct DOCTYPE9 you tell the browser software what this document is and how it should treat it. Depending on the DOCTYPE browsers display HTML either in Quirks or in Standard mode10. Quirks mode simulates the flaws in rendering of older browsers even in the new ones, Standard mode forces the correct W3C compliant display. In the case of Internet Explorer this especially means the W3C box model11 will be properly displayed12.

To ensure standards compliant rendering on IE6, Mozilla and Opera, use the following DOCTYPES:

HTML

<!DOCTYPE HTML PUBLIC "­//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">

xHTML

<!DOCTYPE html PUBLIC "­//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1­transitional.dtd">

Define the encoding and the language

The next thing you need to teach the browser, is how to deal with special characters and define the language of the document. This is necessary for the display of special characters in languages like German, French, Spanish or Scandinavian Languages. The Definition of the language helps screen reader users to select a different voice to read out the text with the correct pronunciation.

The display of the characters is defined in the character encoding13. When dealing with European or English pages we can use the ISO-8859-1 encoding, multinational sites and HTML documents necessary to be XML compliant without CDATA elements should use UTF-8.

The last thing the browser needs to know is how the text will be read, either from left to right (ltr) or from right to left (rtl).

<html dir="ltr" xml:lang="en" lang="en">
<head>
	<meta http­equiv="Content­Type" content="text/html; 
	charset=iso­8859­1" /> 
</head>

Lowercase all tags, nest tags correctly

Valid (x)HTML needs to have all tags in lower case! There are no exceptions. Under no circumstances mix the cases.

In HTML 4.0 you need to ensure all tags are nested correctly, in xHTML you additionally need to close all tags.

To ensure backward compatibility with older browsers, do not close tags in themselves without a space, f.e. <hr/> could make older browsers to skip the tag, whereas <hr /> will be rendered as a horizontal rule.

Wrong example

<DIV class=headline>How to mess up:</DIV>
<UL>
	<li>mix upper and lower case</LI>
	<li>use HTML elements for another purpose</LI>
	<ul>
		<li>nest incorrectly</li>
		<li>don't think of HTML as a node tree</li>
	</ul>
	<LI>Mix display, markup and content
</ul>

Valid example

<h1>How to make HTML understandable</h1>
<ul class="goodHTMLinfo">
	<li>Lowercase all tags</li>
	<li>Ensure your HTML is a valid document
		<ul>
			<li>Nest correctly</li>
			<li>Try to keep a clean, parseable 
			node tree</li>
		</ul>
	</li>
	<li>Keep markup, visual appearance and content 
	separate.</li>
</ul>

Create valid attributes

Attributes in valid HTML need to be lowercase and embedded in quotation marks.

Theoretically these could be also inverted commas (') but general practise is to use the code quotation mark ("). Some attributes are not a name-value pair, like "selected", "noshade" or "checked". In xHTML, these have to be turned into one.

Wrong example

<a HREF=Javascript:void() onClick=popup('annoy.html')>Click 
here</a>
<input TYPE=checkbox VALUE="test" checked>Are you OK 
with popups?

Valid example

<a href="annoy.html" onclick="popup(this.href);return false">
Click here to open in a popup</a>
<input type="checkbox" id="popcb" value="test" 
checked="checked" />
<label for="popcb">Are you OK with popups?</label>

Use HTML elements for their purpose

When HTML was invented, it was meant to be a mean of taking a text and cutting it up into logical elements; HTML is there to describe what a certain text element is.

That is all there is to it. By following these logical definitions, we can make our markup scripting life a lot easier.

Headlines

The headline tags, h1 to h6, are to be used to tell the browser what is a headline. Screen reader software allows users to jump from headline to headline to scan through a text faster; search engines prefer headlines to scan and compare texts to their search matches.

So any time a text has a headline, use an h tag, not a div with an id or class or an image.

Use headlines consistently, the main page headline is h1, one below is h2, another below is h3, one on the same informational level as the second one is h2 again.

Do not nest headlines incorrectly.

Paragraphs

Paragraphs are parts of a text followed by a break. In HTML, use the P tag to mark them. If possible, try to refrain from using line breaks (BR) instead of paragraph tags. Reason for this is that by using a P, you

HTML

The quick brown fox jumped over the lazy dog, not realising that the dog was just pretending to sleep. The quick brown fox jumped over the lazy dog, not realising that the dog was just pretending to sleep.

The quick brown fox jumped over the lazy dog, not realising that the dog was just pretending to sleep. The quick brown fox jumped over the lazy dog, not realising that the dog was just pretending to sleep.

The quick brown fox jumped over the lazy dog, not realising that the dog was just pretending to sleep. The quick brown fox jumped over the lazy dog, not realising that the dog was just pretending to sleep.

The quick brown fox jumped over the lazy dog, not realising that the dog was just pretending to sleep. The quick brown fox jumped over the lazy dog, not realising that the dog was just pretending to sleep.

Javascript

Use Javascript to remove second paragraph. or to replace fox with cat.
function remove(){
	parentObj=document.getElementById('demo2');
	todel=parentObj.getElementsByTagName("p")[1].
	firstChild;
	parentObj.getElementsByTagName("p")[1].
	removeChild(todel);	
}	
function replace(){
	parentObj=document.getElementById('demo2');
	txt=parentObj.getElementsByTagName("p")[0].
	firstChild.nodeValue.replace('fox','cat');	
	parentObj.getElementsByTagName("p")[0].firstChild.
	nodeValue=txt;	
}	

CSS

p{
	margin:.5em 0 0 0;
	text-indent:1em;
	text-align:justify;
}

Source

<div id="demo1">
The quick brown fox jumped over the lazy dog, not realising 
that the dog was just pretending to sleep. The quick brown 
fox jumped over the lazy dog, not realising that the dog 
was just pretending to sleep.  
<br /><br />
The quick brown fox jumped over the lazy dog, not realising 
that the dog was just pretending to sleep. The quick brown 
fox jumped over the lazy dog, not realising that the dog 
was just pretending to sleep.  
<br /><br />
</div>
<div id="demo2">
<p>
The quick brown fox jumped over the lazy dog, not realising 
that the dog was just pretending to sleep. The quick brown 
fox jumped over the lazy dog, not realising that the dog 
was just pretending to sleep.  
</p>  
<p>
The quick brown fox jumped over the lazy dog, not realising 
that the dog was just pretending to sleep. The quick brown 
fox jumped over the lazy dog, not realising that the dog 
was just pretending to sleep.  
</p>  
</div>

Lists

Lists are very handy when you want to give information in a very compact format or when you need to ensure that elements are separated from another without being long enough to be own paragraphs.

A perfect example of a list is a site navigation. As the accessibility standards require links to be separated by something different than whitespace, use a list to create the navigation. With the correct stylesheet, you can make the navigation look the same, but the markup is perfectly readable for screen readers and CSS-unaware browsers.

Under no circumstance use UL to indent a text, this should be done with CSS instead.

HTML

Source

<div id="nav">
<ul>
	<li><a href="index.html">Home</a></li>
	<li><a href="nav1.html">
	<strong>Element1</strong>
	</a></li>
	<li><a href="nav2.html">Element2</a></li>
	<li><a href="nav3.html">Element3</a></li>
	<li><a href="nav4.html">Element4</a></li>
	<li><a href="nav5.html">Element5</a></li>
</ul>
</div>

CSS

#nav ul{
	list-style-type:none;
	margin:0;
	padding:0;
	text-indent:0;
	width:12em;
	border-bottom:1px solid #000;
}
#nav li{
	text-indent:0;
	border:1px solid #000;
	border-bottom:none;
}
#nav li a{
	color:#000;
	display:block;
	margin:0px;
	width:100%;
	text-decoration:none;
	font-family:sans-serif;
}
#nav li a strong,#nav li a:hover{
	color:#fff;
	font-weight:normal;
	display:block;
	margin:0px;
	width:100%;
	background:#369;
}

Links

Links are what makes the web what it is, use them to link documents and to send the surfer to a target on the page.

Links to targets in the page can and should be used as skip links to allow screen reader users to jump over tedious elements of the page.

Make sure to only add links that will work under any circumstance, do not link Javascripts directly.

When using links next to another, make sure to add a different character so separate them than whitespace. One common standard is the pipe character (|).

Each link can get a title attribute explaining in more detail where the link leads to.

Title example

<a href="test.doc" title="Test results document in Microsoft Word 
format, 80 Kilobytes">Download test.doc</a>

Skip link example

<a href="#content">Skip to content</a>
<div id="nav">
<ul>
	<li><a href="index.html">Home</a></li>
	<li><a href="nav1.html"><strong>Element1</strong>
	</a></li>
	<li><a href="nav2.html">Element2</a></li>
	<li><a href="nav3.html">Element3</a></li>
	<li><a href="nav4.html">Element4</a></li>
	<li><a href="nav5.html">Element5</a></li>
</ul>
</div>
<a href="#content">Content starts here</a>

Calling a Javascript

<a href="#explanations" 
onclick="trigger('exp');return false;">
Click here to show/hide explanations</a>
<div id="exp"><h1><a name="#explanations">Explanations</a></h1>
[...]</div>

If for any reason the Javascript function trigger() should fail, the browser simply jumps to the target in the explanations DIV.

<a href="annoy.html" onclick="popup(this.href);return false">
Click here to open in a popup</a>

Should Javascript not be available, the file annoy.html will be opened in the same browser window, if Javascript is available, a popup window will appear.

Images

One of the biggest concerns of making web sites accessible for everybody is the question how to make a blind person get the same experience from an image than a sighted one. The answer is alternative texts, titles and, if necessary, long descriptions.

You have to set an ALT attribute in each image, and, to describe it further, a TITLE attribute. If the size of the image is known, it does not hurt to add a width and height attribute to help the browser render faster.

Longdescription is hardly necessary, but sometimes there are images that need it.

ALT vs. TITLE

The ALT attribute of the IMG tag is there to be a text replacement, should the image not be available or should images be turned off or not at all in the browser specifications. The TITLE attribute is there to give detailed information of what the image is about. For years browsers have rendered the ALT information as a tooltip popup when you hovered your mouse over the image. This is actually a bug, as this is what title is for. IE still has that flaw, but overwrites the ALT tooltip when there is a TITLE attribute available. Opera and Mozilla do it correctly.

HTML

Visit Britain Logo

Source

<img src="footlogo.gif" width="115" height="26" 
alt="Visit Britain Logo" 
title="Visit Britain, your official guide to Britain" 
border="0" />

Although most of the time you won't have to write these texts, just remember one tip should you want to do this: A good alt text simply states what the image is, like "sunset over an island", whereas a good title explains a bit more and conveys some emotions. "Picture of a setting sun over an island, you can see the palm trees dark in front of a red and yellow sun. The picture shows that it warm and beautiful there". To test if your text is good, imagine someone reading it out to you over the phone. Would you be able to envision what the image is about and would you get a "feeling" for it?

Screen Furniture

Screen furniture are images that are nice to look at, but don't have any real meaning for the layout or the content of the document. These can be the infamous spacer GIFs for table layouts or just rounded corners. In any case they are just playing a small role in the visual layout of the page.

Do not give these images any title and do not give these images any alternative text.

Simply add a blank alt attribute alt="" in them. This will make text browsers and screen readers blank out the image. Not giving the image an alt attribute would display/read out the filename to the user.

Sliced Images

When you have an image that is sliced up into different parts, probably as different image formats made more sense, do not repeat the same alt and title for each of them, as that would repeat this info for screen readers and text browsers. Simply add all the information to the first image and treat the rest as screen furniture.

Long description

For really complex images (schemas, charts), you can use the longdesc attribute to link the image to a very basic HTML document explaining what it is about.

Longdesc is not properly supported by browsers to date. That's the reason why some designers that need this technique started to add a textlink called [D] directly after the image, that links to the same document. This technique is quite known in the screen reader user world by now, but not really necessary.

HTML

Visit Britain Logo [D]

Source

<img src="footlogo.gif" width="115" height="26" 
alt="Visit Britain Logo" longdesc="logoinfo.html" 
title="Visit Britain, your official guide to Britain" border="0" />
<a href="logoinfo.html">[D]</a>

Tables

Tables are what you need to learn to see from a totally new angle when you deal with accessible web sites. Due to browser bugs and layouts with rules of print design being used in web design, tables have been abused as layout techniques for a long time now. This is by far not over as a lot of designs cannot be achieved completely by using Cascading Stylesheets.

This is why you need to differentiate between Data Tables (the actual tables) and Display Tables (the hack we use to work around browser problems).

Generally a table is a matrix of data which shows a connection between some headers and rows or cells of content.

For the sighted user, it is a very efficient way of display and is pretty self-explanatory, for a blind user it can be a nightmare, if is not done correctly.

Example

My Day
Time Task Real happening
8:00 - 9.00 AM Stand up, have some food Overslept, re-heated coffee
9:00 - 10.00 AM Travel to the office Tube got stuck, waited for 40 minutes without any explanation
10:00 - 11.00 AM Check emails I'm still in the tube, swearing silently
12:00 - 1.00 PM Phone Conference Arrived at the office.
1.00 - 1.30 PM Write Minutes into an email, define action items. Tried to find the people of the phone conference, only to find out that the conference was cancelled.
1.30 - 2.00 PM Have a healthy lunch break, get some sun and food. After realising that the good food places around the office are closed, grabbed a sandwich and ate it while being rained upon.

This is pretty understandable for a sighted user. A blind user on the other hand would get the same information like this:

My Day Time Task Real happening 8:00 - 9.00 AM Stand up, have some food Overslept, re-heated coffee 9:00 - 10.00 AM Travel to the office Tube got stuck, waited for 40 minutes without any explanation 10:00 - 11.00 AM Check emails I'm still in the tube, swearing silently 12:00 - 1.00 PM Phone Conference Arrived at the office. 1.00 - 1.30 PM Write Minutes into an email, define action items. Tried to find the people of the phone conference, only to find out that the conference was cancelled. 1.30 - 2.00 PM Have a healthy lunch break, get some sun and food. After realising that the good food places around the office are closed, grabbed a sandwich and ate it while being rained upon.

This was the reason why some new HTML elements and attributes had to be introduced to tell screen readers what the connection between the headers and the cells is.

Data tables

To create a table that is understandable for screen readers, you need to add some new tags and attributes. First up, the summary. This is an attribute of the table tag, which gets read out to the user before the real data begins. The user also has the option to skip the table after he hears the summary.

Next you can add a caption to show sighted users also what the table is about.

Unlike the commonly known Layout or Display Tables, a Data Table needs TH elements next, these are the table headers, the elements that explain what the other table cells under or next to these headers are about.

To link these headers to the TD elements they explain, you can use two methods.

The easiest method is adding a SCOPE attribute to the TH that describes which cells are connected to it. SCOPE can have the following values:

col
All following cells in this column (vertical)
row
All following cells in this row (horizontal)
rowgroup
All cells in a rowgroup, you have to define rowgroups via THEAD, TBODY and TFOOTER
colgroup
All cells in a colgroup, you have to define colgroups via COLGROUP and COLS.

In day to day projects we will only need col and row, complex tables might need colgroup and rowgroup though (like a bill could need THEAD TBODY and TFOOTER).

Example with SCOPE

<table summary="What I did today" border="1">
<caption>My Day</caption>
<tr>
	<th scope="col">Time</th>
	<th scope="col">Task</th>
	<th scope="col">Real happening</th>
</tr>
<tr>
	<th scope="row">8:00 ­ 9.00 AM</th>
	<td>Stand up, have some food</td>
	<td>Overslept, re­heated coffee</td>
</tr>
<tr>
	<th scope="row">9:00 ­ 10.00 AM</th>
	<td>Travel to the office</td>
	<td>Tube got stuck, waited for 40 minutes without 
	any explanation</td>
</tr>
<tr>
	<th scope="row">10:00 ­ 11.00 AM</th>
	<td>Check emails</td>
	<td>I'm still in the tube, swearing silently</td>
</tr>
<tr>
	<th scope="row">12:00 ­ 1.00 PM</th>
	<td>Phone Conference</td>
	<td>Arrived at the office.</td>
</tr>
<tr>
	<th scope="row">1.00 ­ 1.30 PM</th>
	<td>Write Minutes into an email, define action items.
	</td>
	<td>Tried to find the people of the phone conference, 
	only to find out that the conference was cancelled.
	</td>
</tr>
<tr>
	<th scope="row">1.30 ­ 2.00 PM</th>
	<td>Have a healthy lunch break, get some sun and food.
	</td>
	<td>After realising that the good food places around 
	the office are closed, grabbed a sandwich and ate it 
	while being rained upon.</td>
</tr>
</table>

SCOPE is the easier way, but some older screen readers won't be able to cope with it. A more complex, but more reliable way is to use ID and headers, each TH gets and ID and each TD gets a HEADERS attribute that lists the IDs this cell should get connected to.

Example with ID and HEADERS

<table summary="What I did today" border="1">
<caption>My Day</caption>
<tr>
	<th>Time</th>
	<th id="task">Task</th>
	<th id="real">Real happening</th>
</tr>
<tr>
	<th id="time8to9">8:00 ­ 9.00 AM</th>
	<td headers="task time8to9">Stand up, have some 
	food</td>
	<td headers="real time8to9">Overslept, 
	re­heated coffee</td>
</tr>
<tr>
	<th id="time9to10">9:00 ­ 10.00 AM</th>
	<td headers="task time9to10">Travel to the 
	office</td>
	<td headers="task time9to10">Tube got stuck, waited for 
	40 minutes without any explanation</td>
</tr>
<tr>
	<th id="time10to11">10:00 ­ 11.00 AM</th>
	<td headers="task time10to11">Check emails</td>
	<td headers="task time10to11">I'm still in the tube,
	 swearing silently</td>
</tr>
<tr>
	<th id="time12to13">12:00 ­ 1.00 PM</th>
	<td headers="task time12to13">Phone 
	Conference</td>
	<td headers="task time12to13">Arrived at the 
	office.</td>
</tr>
<tr>
	<th id="time13to1330">1.00 ­ 1.30 PM</th>
	<td headers="task time13to1330">Write Minutes into an 
	email, define action items.</td>
	<td headers="task time13to1330">Tried to find the 
	people of the phone conference, only to find out that the 
	conference was cancelled.</td>
</tr>
<tr>
	<th id="time1330to14">1.30 ­ 2.00 PM</th>
	<td headers="task time1330to14">Have a healthy lunch 
	break, get some sun and food.</td>
	<td headers="task time1330to14">After realising that 
	the good food places around the office are closed, grabbed a 
	sandwich and ate it while being rained upon.</td>
</tr>
</table>

You can use two more attributes to enhance a table for screen readers, ABBR and AXIS.

ABBR
Allows for an abbreviation of a table header or table cell data. This prevents screen reader users to hear the whole content of the cell, but just get a shorter information to speed up the table scanning process. For example if a header has the content "Contestants winning more than 3 medals" the ABBR could be abbr="3 medal winners" which will speed up the readout of the table immensely. ABBR can also be added to each TD.
AXIS
defines what word will be associated with the TH. Interactive speech systems allow the user to ask questions, and get the data sorted according to these. Let's say for example you have a travel itinerary with expenses. A clever speech system could add all the data of a question like "What did I spend in London on 12th of October". For this, the TH with the date needs an AXIS value of, f.e., "date" and all TH that define spendings an AXIS called, f.e. "money". AXIS is not very much supported to date.

Example with ID, HEADERS and ABBR

<table summary="What I did today" border="1">
<caption>My Day</caption>
<tr>
	<th>Time</th>
	<th id="task">Task</th>
	<th id="real">Real happening</th>
</tr>
<tr>
	<th abbr="before 9" id="time8to9">8:00 ­ 
	9.00 AM</th>
	<td headers="task time8to9">Stand up, have some 
	food</td>
	<td headers="real time8to9">Overslept, re­heated 
	coffee</td>
</tr>
<tr>
	<th abbr="before 10" id="time9to10">9:00 ­ 10.00 
	AM</th>
	<td headers="task time9to10">Travel to the 
	office</td>
	<td abbr="tube failure" headers="task 
	time9to10">Tube got 
	stuck, waited for 40 minutes without any 
	explanation</td>
</tr>
<tr>
	<th abbr="before 11" id="time10to11">10:00 ­ 
	11.00 AM</th>
	<td headers="task time10to11">Check emails</td>
	<td abbr="tube failure" headers="task time10to11">I'm 
	still in the tube, swearing silently</td>
</tr>
<tr>
	<th abbr="before1" id="time12to13">12:00 ­ 
	1.00 PM</th>
	<td headers="task time12to13">Phone Conference</td>
	<td headers="task time12to13">Arrived at the 
	office.</td>
</tr>
<tr>
	<th abbr="before 1 30" id="time13to1330">1.00 ­ 
	1.30 PM</th>
	<td abbr="sum up conference" headers="task 
	time13to1330">Write 
	Minutes into an email, define action items.</td>
	<td abbr="conference was cancelled" headers="task 
	time13to1330">
	Tried to find the people of the phone conference, only 
	to find out that the conference was 
	cancelled.</td>
</tr>
<tr>
	<th abbr="before 2" id="time1330to14">1.30 
	­ 2.00 PM</th>
	<td abbr="lunchbreak" headers="task time1330to14">Have 
	a healthy lunch break, get some sun and food.</td>
	<td abbr="fast snack" headers="task time1330to14">After 
	realising that the good food places around the office 
	are closed, grabbed a sandwich and ate it while being 
	rained upon.</td>
</tr>
</table>

Display tables

Display or Layout tables are a lot easier, all you need to make sure is that you

When you use a layout table make sure that the content of it also makes sense when you read the table without the layout it produces. You can simulate that either via a text browser (LYNX) or via the "disable tables" option in Opera.

HTML

[...] [...] [...]
[...]
[...] [...] [...]
[...]

Source

<table width="500" border="1" cellpadding="0" 
cellspacing="0">
<tr>
	<td width="400">[...]</td>
	<td width="50">[...]</td>
	<td width="50">[...]</td>
</tr>
<tr>
	<td colspan="3">[...]</td>
</tr>
<tr>
	<td rowspan="2">[...]</td>
	<td>[...]</td>
	<td>[...]</td>
</tr>
<tr>
	<td colspan="2">[...]</td>
</tr>
</table>

If you create layouts via tables, be aware of the following:

Forms

General:

1. Each form element needs a label attached to it. This label is connected to the control via an ID (doesn't matter which, ID and name could be the same) and allows screen readers to connect the text with the control and people with bad hand eye coordination to click the label instead of the element.

Without label

Please spam me with your newsletter

<input type="checkbox" name="checkbox" 
id="cb1" /> Please spam me with your newsletter

With label:

<input type="checkbox" name="checkbox" 
id="cb1" /><label for="cb1">Please spam me 
with your newsletter</label>

2. Javascript can only be used to enhance the form functionality, hence the form is not allowed to be submitted via a link, but only via a submit button or image.

Text box:

Each text box needs a label and also a standard value. This value must be stripped on the backend when checking the element for validity. As an extra, we can clear the element via onclick.

<label for="name">Name</label>
<input type="text" name="Name" id="name" 
value="Please enter your name" 
onclick="if(this.value=='Please enter your name'){
this.value=''}" />

The same applies for password, albeit not the clearing, as that would show the password in the source.

Text Area:

Each text area needs a label and also a standard value. This value must be stripped on the backend when checking the element for validity. As an extra, we can clear the element via onclick.

<label for="Message">Message</label>
<textarea name="message" id="Message" 
onclick="if(this.value=='Please enter your message'){
this.value=''}">
Please enter your message</textarea>

Dropdown list

Dropdown lists need a label and the first element HAS to be a valid selection. The old practice of "Choose your option..." or something as useless for screen readers as an option is not allowed.

<label for="languages">Languages</label>
	<select name="Languages" id="languages">
		<option value="English" 
		selected="selected">English</option>
		<option value="French">French</option>
		<option value="Greek">Greek</option>
		<option value="German">German</option>
		<option value="Klingon">Klingon</option>
		<option value="Betazoid">Betazoid</option>
		<option value="Vulcan">Vulcan</option>
	</select>

To enhance the dropdown, we can use optgroup to sort the options into groups:

<label for="languages">Languages</label>
	<select name="Languages" id="languages">
		<optgroup label="terrestrial">
			<option value="English"
			 selected="selected">English</option>
			<option value="French">French</option>
			<option value="Greek">Greek</option>
			<option value="German">German</option>
		</optgroup>
		<optgroup label="extraterrestrial">
			<option value="Klingon">Klingon</option>
			<option value="Betazoid">Betazoid
			</option>
			<option value="Vulcan">Vulcan</option>
		</optgroup>
	</select>

Select boxes are not allowed to send off the data or check which option was set via onchange, as this is not possible to surpress without a mouse.

Radio buttons and Checkboxes

Radio buttons and checkboxes all need a label and can and should be grouped via the fieldset tag.

HTML

Connection speed
Mail format

Source

<fieldset>
	<legend>Connection speed</legend>
	<input type="radio" name="connection" id="2t" 
	value="slow" />
	<label for="2t">Two tins and some wire</label> 
	<input type="radio" name="connection" id="56k" 
	value="56k" />
	<label for="56k">56k</label> 
	<input type="radio" name="connection" id="dsl" 
	value="dsl" />
	<label for="dsl">DSL</label> 
	<input type="radio" name="connection" 
	id="speedy" value="speedy" />
	<label for="speedy">Speedy</label> 
</fieldset>
<fieldset>
	<legend>Mail format</legend>
	<input type="checkbox" name="htmlmail" 
	id="htmlmail" />
	<label for="htmlmail">Send me HTML mail</label> 
	<input type="checkbox" name="spam" id="spam" />
	<label for="spam">I am highly interested in low 
	mortgage rates.</label> 
</fieldset>

Links

Recommended Reading