Tabellen mit HTML & CSS

Schwierigkeiten & Lösungen

HTML-Tabellen werden auf Webseiten nicht nur zur Darstellung von Listen verwendet, sondern vor allem zur Layout-Gliederung (unsichtbare Tabellen) Die Matrix-Struktur einer Tabelle passt nicht ganz konfliktfrei in die strenge Baum-Struktur des Document Object Model (DOM).
CSS Cascading Style Sheets
HTML-Tabelle Standard-Elemente von Tabellen
Ankündigung Spalten-Definition am Beginn der Tabelle
Zusammenfassung Zellen aus Spalten und Zeilen kombinieren
CSS-Vererbung Für Tabellen gelten eigene Regeln
CSS-Klassen & Unterklassen Kombination von Klasse und HTML-Element
Individuelle CSS-Klassen Kombination von id-Attribut und Klasse
Spalten-Formatierung CSS-Trick für alle Browser
Pseudo-Tabellen Nachbau von Tabellen mit CSS-Boxen
DOM-Methoden Tabellen Live erzeugen und verändern
Verwandte Themen Live Aufbau und Sortierung von Tabellen mit Javascript
Links Ausgewählte Links zum Thema 'Tabellen @ CSS'

Standard HTML-Tabelle

Die Demo-Tabelle rechts enthält die wichtigsten Elemente einer HTML-Tabelle.
Sehen sie unterhalb den HTML-Quellcode mit Erläuterungen.
Von dieser Grund-Struktur sind viele Varianten möglich.

Aus dem Quelltext erkennt man, dass die Objekt-Hierarchie in der Reihenfolge <table> → <tr> → <td> läuft. Die einzelnen Zellen <td> sind Tochter-Elemente ihrer Zeile <tr>. Ein Element <tc> für 'Spalte' gibt es nicht !
caption
th1th2th3
r1 c1r1 c2r1 c3
r2 c1r2 c2r2 c3
Rechts der HTML-Code (vereinfacht) der oben gezeigten Demo-Tabelle.

Jede Tabelle wird durch ein das <table>-Element definiert.
Hier wird mit CSS die Breite der gesamten Tabelle festgelegt. Ohne Definition der Breite ergibt sich diese aus der Summe der Spalten-Breiten.

Das optionale Element <caption> bezeichnet eine Tabellen-Überschrift und wird selten verwendet.

Mit dem optionalen Element ↓ <colgroup> wird Anzahl und Breite der folgenden Spalten angekündigt.

Danach folgen die einzelnen Zeilen <tr> (table row) als direkte Tochter-Elemente von <table>. Alle Zeilen werden automatisch vertikal zentriert.

Die meisten Tabellen zeigen in der ersten Zeile die Spalten-Überschriften an. Als Tochter-Elemente der ersten <tr>-Zeile werden <th>-Element (table header) eingesetzt. Der Inhalt wird automatisch zentriert und fett gesetzt.

Danach folgen alle anderen Zeilen der Tabelle. Jede Zeile <tr> hat Tabellen-Zellen <td> (table data) als Tochter-Elemente, und zwar genau eines je Spalte.
<table style="width:90%;">
<caption>caption</caption>
<colgroup span="3">
<col style="width:33%;" / >
</colgroup>
<tbody>
<tr>
<th> th1 </th>
<th> th2 </th>
<th> th3 </th>
</tr>
<tr>
<td> r1 c1 </td>
<td> r1 c2 </td>
<td> r1 c3 </td>
</tr>
<tr>
<td> r2 c1 </td>
<td> r2 c2 </td>
<td> r2 c3 </td>
</tr>
</tbody>
</table>
<tbody>
Ein oder mehrere <tbody>-Elemente sind optional, z.B. zur Gliederung einer Tabelle in (unterschiedlich formatierte) Teilbereiche.
Ein <tbody>-Element wird von allen gängigen Browsern automatisch erzeugt, auch wenn keines im HTML Quelltext enthalten ist.

Tipp: Verwenden sie selbst ein <tbody>-Element, wenn sie → DOM-Methoden anwenden wollen. Insbesondere mit dem M$IE-Browser lassen sich die Zeilen nur als childNodes von <tbody> adressieren.
CSS-Stylesheet:
Die Standard Ausrichtung von Zellen ist text-align:center; vertical-align:middle;
In diesem Web ist es erwünscht, dass alle Zellen der zahlreichen Tabellen links oben ausgerichtet sind. Daher ist die rechts gezeigte Zeile in der Stylesheet-Datei enthalten. Diese einmalige zentrale Festlegung wirkt auf alle Reihen aller Tabellen aller Seiten dieses Webs.
Opera-Browser ignorieren diese Anweisung leider.

Eine Zeile aus der Stylesheet-Datei pstrainer.css für alle Seiten dieses Webs:

tr {vertical-align:top;}

Ankündigung mit <colgroup>

Die Ausmaße einer Tabelle sind für einen Browser erst nach Verarbeitung des gesamten Quelltextes einer Tabelle <table>..</table> erkennbar.
Erst danach sind Daten über Anzahl und Breite der Spalten verfügbar, das muss auf jede Zelle der Tabelle angewendet werden. Daher werden Tabellen meist in mehreren Durchgängen verarbeitet.
Man kann viel Zeit sparen, wenn Anzahl und möglichst auch Breite der Spalten schon frühzeitig angekündigt werden. Dazu dient das <colgroup>-Element von HTML.
Es ist optional, sollte jedoch in jeder Tabelle unmittelbar nach dem Beginn des <table>-Elements enthalten sein - Solche Webseiten laden schneller !
Für jede Spalte wird genau ein <col>-Element eingefügt.
Die Breite wird mit dem style-Attribut und seiner Eigenschaft width festgelegt. Dabei sind verschiedene Einheiten wählbar: mm, cm, pt, %.
Das Element <col> wird ohne Endmarke </col> verwendet. Schreiben sie es daher am besten → XHTML-kompatibel in der abgeschlossenen Form <col />.
Wenn bei der Platz-Aufteilung Breite 'übrig bleibt', dann wird sie auf alle <col /> ohne eigene Definition der Breite aufgeteilt.
Beispiel: Tabelle mit 2 gleich breiten Spalten:
<table>
<colgroup>
<col style="width:50%;" />
<col style="width:50%;" />
</colgroup>
<!-- Zeilen & Spalten -->
</table>
Mehrere gleich breite Spalten kann man mit einer einzigen Definition zusammenfassen. (Beispiel rechts).
Mehrere <colgroup>-Elemente können hintereinander geschaltet werden, um alle Spalten einer Tabelle zu beschreiben.
In manchen Fällen wird dieses praktische Attribut vom M$IE-Browser ohne Warnung ignoriert. Der Browser-Hersteller bestimmt die Formatierung, nicht die/der EntwicklerIn...
Ankündigung von 5 gleich breiten Spalten:
<colgroup span="5">
<col style="width:20%;" />
</colgroup>
Wenn der Inhalt einer Tabellen-Zelle (z.B. ein Bild) größer ist als der vorgesehene Platz, dann wird diese Spalte und Zeile vergrößert - Außer wenn sie das durch die CSS-Eigenschaft table-layout ausdrücklich verboten haben. Meistens passiert unkontrolliertes Breiten-Wachstum nur in einer einzigen Zelle.
In diesem Fall ist es besser, nur diese Zelle zu begrenzen, und bei größeren Inhalten Rollbalken (scrollbars) anzuzeigen.
Begrenzung mit CSS-Eigenschaft overflow ( ♦ Details)
Einbettung des Inhalts in einen Innen-Rahmen <iframe> ( ♦ Details)
Leider ist im HTML-Standard nicht vorgesehen, im <col>-Element zusätzlich zur Breite auch andere Spalten-Eigenschaften festzulegen. Das lässt sich durch Verwendung von CSS-Klassen (nächster Absatz) umgehen.
(Details zur ↓ CSS-Vererbung).
Alle derzeit gängigen Browser unterstützen das Attribut class für ganze Spalten. Damit lassen sich Tabellen einfach und sparsam formatieren.
Die verwendeten CSS-Klassen (hier demo ) müssen vorher in einem zentralen Stylesheet oder einem <style>-Element der Webseite definiert werden.
In der jeweiligen CSS-Klasse können alle üblicherweise benötigten Spalten-Eigenschaften (Breite, Farben, Schrift, Ausrichtung, ..) zusammengefasst und bei Bedarf bequem geändert werden.
Festlegung von CSS-Klassen für ganze Spalten:
<colgroup>
<col class="demo" />
<col />
</colgroup>

Zentrieren beliebiger Objekte

   
Zentrieren mit variabler Objekt-Breite:
100   200   300   400
Klicken sie, um die Breite bei unveränderter Zentrierung zu ändern.
Das beschriebene Verhalten kann dazu verwendet werden, um auch solche Objekte zu zentrieren, die auf das align-Attribut oder die CSS text-align-Eigenschaft nicht reagieren (hier ein <iframe>-Innenrahmen).
So funktioniert dieser Trick:
Erzeugen sie eine Hilfs-Tabelle (1 Zeile, 3 Spalten) und kündigen sie nur die Breite der mittleren Zelle an. Die beiden Rand-Zellen erhalten automatisch je 50% der übrig bleibenden Breite.
Der Rand der Hilfs-Tabelle (hier blau) wird natürlich mit border=0px; nicht angezeigt.
Hilfs-Tebelle zentriert jedes Objekt:
<colgroup>
<col /><col style="width:300px;" /><col />
</colgroup>
Die Live-Demo zeigt, dass die Breiten-Aufteilung auch dann erhalten bleibt, wenn die Objekt-Breite geändert wird.

Zusammenfassung von Zellen

Die Tabelle rechts zeigt, wie sich mehrere Zellen zusammenfassen lassen. Die Zellen können sich über mehrere Spalten, mehrere Zeilen oder beides erstrecken.

Solche Tabellen werden erfolgreich zur Layout-Gliederung eingesetzt:
Man teilt die Webseite (oder einen Teil davon) in eine passende Anzahl von Zellen, fasst einige davon zusammen und legt Höhe bzw. Breite fest. Solche Tabellen werden oft ohne Rahmen border verwendet. Sie dienen als 'unsichtbare Tabellen' zur Aufnahme aller gewünschten Inhalte.
Diese Gliederungs-Methode ist schnell und vor allem sehr sicher. Sie funktioniert bestens mit allen Browsern, auch mit sehr betagten Versionen. Profi-Webseiten für großes Publikum (z.B. Suchmaschinen, Zeitungen, Webs globaler Unternehmen, etc. sind daher fast immer so aufgebaut.
Nummerierung der Zeilen (r) und Spalten (c) bei Zusammenfassung von Zellen:

r1 c1r1 c2
r2 c1 r2 c2 r2 c3
r3 c1 r3 c3
r4 c1r4 c3
r5 c3
Der HTML-Quelltext zeigt, wie mehrere Zellen mit Hilfe der Attribute colspan und rowspan zusammengefasst werden.

Beachten sie, dass jede Zelle unabhängig von allen anderen individuell formatiert werden kann: Rahmen, Ausrichtung, Hintergrund, Schrift, Bilder, Farbe, .. Das ist Voraussetzung für die Verwendung zur Layout-Gliederung.

Mit Tricks kann man auch nicht-rechteckige Bereiche vortäuschen:
Man zerlegt z.B. eine haken-förmige Grafik und fügt je einen Teil in die Zellen r1c1, r1r2 und r2c1 ein. Die 3 Teile passen am Bildschirm exakt zusammen und sehen aus wie eine einzige Grafik.

Erraten sie, wie die beiden Spalten dieses Kapitels jeweils unterschiedlich im Verhältnis 1:2, 2:1 und 1:1 aufgeteilt werden ?
Die letzte Zeile zeigt den Trick: Diese Tabelle enthält 6 Spalten, die unterschiedlich zusammengelegt wurden.
HTML-Code einer Standard-Tabelle:
<table>
<colgroup span="3">
  <col style="width:33%;" />
</colgroup>
<tr>
  <td>r1c1</td><td colspan="2">r1c2</td>
</tr>
<tr>
  <td>r2c1</td><td rowspan="2">r2c2</td><td>r2c3</td>
</tr>
<tr>
  <td>r3c1</td><td>r3c3</td>
</tr>
<tr>
  <td colspan="2" rowspan="2">r4c1</td><td>r4c3</td>
</tr>
<tr>
  <td>r5c3</td>
</tr>
</table>

Zellen-Anzahl:

Wenn eine Tabelle s Spalten und r Zeilen hat, dann müssen genau s*t Zellen <td> definiert werden.
Zusammengefasste Zellen decken dementsprechend mehrere Positionen ab. Fehlende oder überschüssige Zellen ergeben Fehler und sollten unbedingt vermieden werden, auch wenn manche Browser versuchen, trotzdem eine halbwegs brauchbare Tabelle anzuzeigen.

Leere Zellen:

Zellen sollten niemals leer bleiben <td></td>, obwohl sie solche Fälle mit der CSS-Eigenschaft empty-cells lösen können.
Füllen sie leere Zellen mit dem 'geschützten' Leerzeichen
<td>&nbsp;</td><td>&#xA0;</td>
( Unicode U+00A0).
123456

CSS-Vererbung bei Tabellen

Normalerweise vererbt ein Eltern-(parent)-Element seine style-Eigenschaften auf alle Tochter-(child)-Elemente. In den child-Elementen muss man nur jene style-Eigenschaften angeben, die dort geändert werden sollen. Das gilt leider nicht für Tabellen. Die CSS-Vererbung wird hier stark eingeschränkt. Außerdem bestehen beträchtliche Unterschiede zwischen Browsern und Versionen, die Dokumentation ist spärlich.
Alle folgenden Angaben sind experimentell gewonnen, daher ohne Gewähr und evtl. überholt, wenn neue Browser-Versionen verfügbar werden.
Die folgenden Angaben enthalten nur jene Eigenschaften, die experimentell bei allen gängigen Browsern auf alle Zellen unterhalb des genannten Elements vererbt wurden. Sinnvoll gesetzte Eigenschaften sind rot gesetzt.

von einem parent-Element oberhalb <table> :
background-color, color, font-family, font-size, font-weight, text-align

von <table> 
background-color, border-collapse, color, font-family, font-size, font-weight, text-align

von <col> 
background-color, font-family (nur als style, nicht als class), width

von <tr> 
background-color, color, font-family, font-size, font-weight, height (nur als style, nicht als class), text-align
Dabei zeigen sich u.a. folgende Probleme:

Die Text-Ausrichtung text-align kann nicht nach <col>-Spalten angegeben werden.
Das wäre wichtig, denn alle Elemente einer Spalte sind normalerweise gleich ausgerichtet, z.B. Text linksbündig oder Zahlen rechtsbündig.
Man müsste text-align für jede ! einzelne Zelle angeben !
M$IE wird ausnahmsweise gelobt: Dieser Browser vererbt die Ausrichtung von <col> an alle Zellen der Spalte.
Auf dieser Seite finden sie einen ↓ CSS-Trick zur Umgehung des Problems.

Ein Zellen-Gitter kann nicht zentral vorgegeben werden.
Wenn in <table> ein Rand border definiert wird, dann gilt das für den Rahmen um die gesamte Tabelle, nicht für die darin enthaltenen Zellen. Manche Browser können ganze Spalten oder Zeilen hübsch umrahmen, niemals jedoch ein Gitter über alle Zellen, obwohl man das in der Praxis viel öfter benötigt.

Die zahlreichen anderen CSS-Eigenschaften können nicht unabhängig für jede Tabelle gesetzt werden, jedenfalls nicht durch Vererbung, z.B. die wichtigen Außen- und Innenränder margin und padding.
Abhilfe:
Verwendung von CSS-Klassen und Unterklassen ( class-Attribbute )
Moderne Browser der aktuellen Versionen unterstützen die Verwendung von CSS-Klassen auch in <col>-Elementen.

CSS-Klassen und Unterklassen

Diese Methode wird im Web von PS-Trainer angewendet.
Man kann einen einzigen Klassen-Namen (hier monotab) für alle Tabellen eines bestimmten Layout-Typs angeben.

Alle Tabellen <table class="monotab"> auf beliebigen Seiten des gesamten Webs werden nach diesen Vorschriften formatiert. Eine Änderung im CSS-Quellcode wirkt sich unmittelbar auf alle Tabellen dieses Typs aus und verursacht keinerlei zusätzliche Arbeit.

Jede Webseite kann mehrere (beliebig viele) Tabellen <table class="monotab"> enthalten.

Auf den einzelnen Webseiten werden keine HTML <style>-Elemente benötigt.

Die zentrale StyleSheet-Datei muss mit jeder einzelnen Webseite verbunden werden:
<link rel=stylesheet type="text/css" href="tabellen.css" />
Diese Zeile ist jedoch für alle Webseiten gleich und wird am besten durch das Web-Editor Programm automatisch in den <head> jeder Webseite eingefügt.
CSS-Quellcode in einer zentralen StyleSheet-Datei:
.monotab {
background-color:#FFF;
border-color:#666;
border-style:solid;
border-width:1px;
font-family:'Courier New',Courier,mono;
font-size:10pt;
padding-left:5px; padding-right:5px;
}
.monotab table {
border-collapse:collapse;
}
.monotab td {
border-color:#666;
border-style:solid;
border-width:1px;
padding-left:5px; padding-right:5px;
padding-top:0px; padding-bottom:0px;
}
.monotab th {
border-color:#666;
border-style:solid;
border-width:1px;
padding-top:0px; padding-bottom:0px;
text-align:center;
}
Aufbau der CSS-Klassen:
Zunächst wird monotab als 'alleinstehende' CSS-Klasse definiert. So ist es möglich, monotab auch für beliebige andere Elemente anzuwenden, z.B. Live:
  <span class="monotab">  
Tipp: Achten sie auf den Punkt (nur) bei der Definition vor dem Klassen-Namen.

Danach folgt die Definition der sub-Klasse
.monotab table {}
Sie kommt überall zur Anwendung, wo sich ein Element <table class="monotab"> befindet. Aus einem unbekannten Grund wird diese sub-Klasse ganz oder weitgehend ignoriert, daher müssen die Eigenschaften als style-Attribut zusätzlich angegeben werden:
<table class="monotab" style="border-collapse:collapse;">

Zuletzt die wichtigste sub-Klasse .monotab td für alle Elemente <td>, die sich innerhalb von <table class="monotab"> befinden. Die Angabe von class und style für jede einzelne Zelle kann entfallen bzw. ist nur mehr dort notwendig, wo eine Zelle vom monotab-Stil abweichen soll.

Wenn man die Spalten-Ausrichtung in den <col>-Elementen definiert (nur bei M$IE oder mit Trick), dann ist ein weiterer sub-Style für <th> sinnvoll, allenfalls auch noch für <caption>
Alle weiteren Tabellen-Typen werden in eigenen CSS-Klassen und sub-Klassen angelegt. Die oben gezeigten Demo-Tabellen sind übrigens monotab-formatiert.

Individuelle CSS-Unterklassen

Die id-Attribute können ebenfalls dazu verwendet werden, einzelne Tabellen mit einem vordefinierten Layout-Typ zu formatieren. Gegenüber der oben angeführten Methode von CSS-Klassen und Unterklassen gibt es jedoch einige Nachteile:
Man benötigt HTML <style>-Elemente auf jeder einzelnen Webseite.
Allfällige Änderungen müssen auf jeder einzelnen Webseite ausgeführt werden.
id-Attribute müssen eindeutig sein, d.h. sie dürfen auf jeder Webseite nur einmal vorkommen.
Immerhin ist es möglich, mit der gleichen CSS-Definition mehrere Tabellen zu erfassen, z.B. mit #t1,#t2,#t3 td{. . . }
Man benötigt dafür weder ein HTML <link>-Element noch eine zentrale StyleSheet-Datei.

Die individuell definierte Klasse kommt überall dort zur Anwendung, wo sich Elemente <td> innerhalb von <table id="t1"> befinden. Die Angabe von class und style für jede einzelne Zelle kann entfallen bzw. ist nur mehr dort notwendig, wo eine Zelle vom gemeinsamen Stil der Tabelle abweichen soll.

Alle modernen Browser unterstützen CSS-Unterklassen, M$IE ab Version 7.
CSS-Quellcode in jeder einzelnen HTML-Webseite:
<style type="text/css" media="screen">
#t1 table{
background-color:#FFF;
border-collapse:collapse;
font-family:'Courier New',Courier,mono;
font-size:10pt;
}
#t1 td{
border-color:#666;
border-style:solid;
border-width:1px;
padding-left:5px; padding-right:5px;
padding-top:0px; padding-bottom:0px;
}
</style>

Strategie:

In vielen Fällen ist es möglich, die verschiedenen CSS-Selektoren in mehreren Varianten anzuordnen. Ordnen sie die Selektoren immer nach fallender Selektivität.

Ein Selektor, welcher nur wenige Elemente eines Dokuments betrifft, sollte am Anfang stehen.
Ein Selektor, welcher viele Elemente eines Dokuments betrifft, sollte am Ende stehen.

CSS Verkettungs-Operatoren

CSS kennt einige Operatoren, welche die Verkettung von Selektoren bezeichnen. Als Selektor kann der Name eines HTML-Elements oder eines id-Attributs dienen.

Für das Verständnis einiger Begriffe sind Grundkenntnisse des Document Object Model (DOM) notwendig.
Alle Elemente einer Webseite werden in einem hierarchischen Baum angeordnet. parent ist ein beliebiges Element, welches darin verschachtelte Unter-Elemente (childNodes) hat.
Mit Hilfe dieser Operatoren kann jede einzelne Spalte einer Tabelle identifiziert und individuell formatiert werden. Das mag mühsam erscheinen, funktioniert aber in der Praxis gängiger Browser.
OperatorBedeutung
s1 s2alle s2 unterhalb von s1
s2:first-childalle s2, welche firstChild sind
s1 > s2alle s2 genau eine Ebene unterhalb s1
s1 * s2alle s2 mehr als eine Ebene unterhalb s1
s1 + s2 ein in der gleichen Ebene auf s1 direkt folgendes s2
Diese Operatoren sind wenig bekannt, wahrscheinlich weil sie von M$IE erst ab Version 7 beherrscht werden. Das spielt jedoch für die Anwendung auf Tabellen-Spalten keine Rolle, da M$IE alle Style-Angaben der <col>-Elemente verwendet.
Beispiel (3-spaltige Tabelle)
Im <style>-Element (im <head> der HTML-Datei) wird ein individueller style für jede Spalte der Tabelle definiert.

Selektor #t3 wählt aus allen Elementen der Webseite nur jenes mit id="t3" aus.

Der nachfolgende Selektor tr wählt aus allen Elementen der Tabelle die Zeilen aus.

Der nachfolgende Selektor td:first-child bezeichnet das erste <td>-Element eines parent-Knotens. Das betrifft alle Zellen in der ersten Spalte einer Tabelle.

Selektor + td bezeichnet jenes <td>-Element, welches auf das vorher definierte in der gleichen Ebene folgt. Einmalige Anwendung wie gezeigt betrifft daher alle Zellen der 2. Spalte, 2xige Anwendung alle Zellen der 3. Spalte usw.
CSS
<style type="text/css" media="screen">
#t3 tr td:first-child {color:#F00;}
#t3 tr td:first-child + td{text-align:center;}
#t3 tr td:first-child + td + td{text-align:right;}
</style>
HTML-Tabelle
<table id="t3">
<colgroup>
<col style="color:#F00;" />
<col style="text-align:center; />
<col style="text-align:right; />
</colgroup>
<tr>
  <td>abc</td><td>rst</td><td>123</td>
</tr>
<tr>
  <td>def</td><td>uvw</td><td>789</td>
</tr>
</table>
So sieht das gezeigte Beispiel in der Praxis aus:
M$IE<7 ignoriert die CSS-Anweisungen im <style>-Element und verwendet die Anweisungen der <col>-Elemente zur Formatierung der Spalten.
Alle modernen Browser verwenden die Anweisungen im <style>-Block zur Formatierung der Spalten.
aq1
bcrs23
deftuv456
ghijwxyz7890

CSS Pseudo-Tabellen

Angesichts der Schwierigkeiten bei der Formatierung von HTML-Tabellen sind einige EntwicklerInnen auf die Idee gekommen, auf <table> ganz zu verzichten und Tabellen mit einfacheren Elementen wie <div> <span> <img> usw. und massivem Einsatz von CSS-Positionierung nachzubauen.
Das funktioniert ausgezeichnet, allerdings nur in bestimmten Fällen:

Je geringer die Anzahl der zu positionierenden Elemente, desto einfacher ist es, sie als individuelle Boxen mit CSS zu positionieren.
Tabellen mit langen Zahlen-Kolonnen oder mit Listen aus Datenbanken werden natürlich nur mit <table> aufgebaut, meist automatisch durch ein → Perl- oder → PHP-Programm.

Je individueller die Ansprüche, desto eher wird man mit CSS positionieren: Einige Boxen mit komplett unterschiedlichen Formaten, teilweisen Überlagerungen, mit umfließenden Elementen usw. können kaum anders als mit CSS formatieret werden.
Für klassische 'brave' Tabellen mit lauter gleichen Zellen ist <table> weit besser geeignet.

Freie CSS-Positionierung verlangt einen gewissen Spielraum für die zahlreichen Unterschiede zwischen Browsern und Versionen. Wenn die Ränder breit und die Abstände einige 10 Pixel groß sind, dann klappt die CSS-Positionierung ausgezeichnet.
Alle Versuche, Pseudo-Tabellen mit schmalen Rändern in einem Raster aus positionierten Boxen exakt zusammenzupassen sind nach meiner Erfahrung gescheitert und außerdem viel zu mühsam.

Details zur Positionierung von Elementen mit CSS.
style = "position: relative; left: 60px; top: 20px;"
style = "position: relative; left: 170px; top: -20px;"
style = "position:relative; left: 20px; top: -170px;"

Tabellen & DOM-Methoden

Mit DOM-Methoden und Javascript ist es möglich, an jeder beliebigen Stelle einer Webseite eine Tabelle einzufügen, zu verändern oder zu löschen.
Die Tabellen-Daten werden zweckmäßig in mehrdimensionalen → Javascript-Arrays verwaltet.
Die Methode wird in diesem Web öfters dazu verwendet, um Live dynamische Tabellen auf Webseiten zu erstellen und zu → sortieren.
Das Laden von Tabellen-Webseiten kann damit stark beschleunigt werden: Man übersendet nur die Daten und erzeugt die Tabelle erst am Ziel-PC mit dem Browser.
Details dazu unter Javascript / DOM.
M$IE-DOM-Problem:
Ältere M$IE Browser können Tabellen mit DOM-Methoden nur innerhalb von <tbody>-Elementen erzeugen.
In jedem anderen Fall wird die Tabelle von M$IE zwar ohne Fehlermeldung erzeugt, jedoch nicht angezeigt.
Sehr mühsam und nicht (??) dokumentiert.
Test:
Klicken sie diesen Link, um die Tabelle rechts zu löschen und eine neue Tabelle anzulegen.
Diese Tabelle ist im HTML-Quelltext der Webseite angelegt. Durch den DOM-Test sollte sie gelöscht und durch eine neue Tabelle ersetzt werden.
MSIE-margin-Problem:
Ein weiterer Fehler des M$IE Browsers kann mit einigem Aufwand kompensiert werden.
Bei Einbettung einer Tabelle <table> in eine Tabellen-Zelle <td> und Verwendung des CSS-Eigenschaften margin (Außenrand) oder padding (Innenrand) ergeben sich meist Layout-Fehler: Elemente ragen bis zum rechten Rand oder darüber hinaus.
Test:
Die Tabelle rechts sollte mit einem allseitigen Abstand von 30px eingebettet sein.
Alle modernen Browser zeigen das Beispiel korrekt an.
r1c1r1c2
Umgehung:
Man legt eine zusätzliche Tabelle (1 Zeile, 3 Spalten) an, und setzt die gewünschte Tabelle in die mittlere Zelle.
Erste und dritte Spalte der Hilfs-Tabelle werden mit width:30px; auf die gewünschte Breite eingestellt. Die Breite der mittleren Spalte wird nicht festgelegt - sie nimmt dann automatisch die restliche Breite ein.
Die Ränder der Hilfs-Tabelle (hier blau) werden mit border=0px; nicht angezeigt.
Hilfs-Tabelle zur Anzeige einer Tabelle mit Rand-Abstand:
 
r1c1r1c2
 

CSS-Links Ausgewählte Links:

Die CSS-Homepage befindet sich beim W3C-Konsortium.
Tables beim W3C.