Demographical values about (...whatever)
Male Female
18-39 yrs. 40-65 yrs 18-39 yrs 40-65 yrs
W. Germany
Bayern 37.5% 48.9% 32.5% 42.8%
Hessen 33.4% 39.3% 29.7% 34.8%
E. Germany
Sachsen 34.8% 43.6% 29.5% 40.7%

Here I nailed down the structure of the table more in depth. Instead of marking up all headers with "male 18-39 years" and "male 40-65 years" and so on, this information was grouped using the colgroup element. I added one row with 2 spanning columns and marked them up as headers "Male" and "Female". Their scope will be scope="colgroup". So "Male" actually refers to the two columns 18-39 yrs. and 40-65 yrs. Same goes for "Female".

This is the markup I used:


<table summary="Here goes the description of the table's purpose and structure, mainly for non-visual media" frame="box">
<caption>Demographical values about (...whatever) </caption>
<!-- Grouping the columns /First *empty*/Second *Male, spanning two columns*/Third *Female, spanning two columns* -->
<colgroup></colgroup>
<colgroup span="2"></colgroup>
<colgroup span="2"></colgroup>
<thead>
<tr>
	<td></td>
	<th colspan="2" scope="colgroup">Male</th>
	<th colspan="2" scope="colgroup">Female</th>
</tr>
<tr>
	<td></td>
	<th scope="col">18-39 <abbr title="Years">yrs.</abbr></th>
	<th scope="col">40-65 yrs</th>
	<th scope="col">18-39 yrs</th>
	<th scope="col">40-65 yrs</th>
</tr>
</thead>
<tbody>
<tr>
	<th colspan="5"><abbr title="Western">W.</abbr> Germany</th>
</tr>
<tr>
	<td scope="row">Bayern</td>
	<td>37.5%</td>
	<td>48.9%</td>
	<td>32.5%</td>
	<td>42.8%</td>
</tr>
<tr>
	<td scope="row">Hessen</td>
	<td>33.4%</td>
	<td>39.3%</td>
	<td>29.7%</td>
	<td>34.8%</td>
</tr>
</tbody>
<tbody>
<tr>
	<th colspan="5"><abbr title="Eastern">E.</abbr> Germany</th>
</tr>
<tr>
	<td scope="row">Sachsen</td>
	<td>34.8%</td>
	<td>43.6%</td>
	<td>29.5%</td>
	<td>40.7%</td>
</tr>
</tbody>
</table>

Previous table example | Back to the article