HTML Tabellenelement Anleitung

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Das <table>-Element in HTML wird zur Anzeige tabellarischer Daten verwendet. Man kann es sich als eine Möglichkeit vorstellen, Daten zu beschreiben und anzuzeigen, die in einer Tabellenkalkulationssoftware Sinn ergeben würden. Im Wesentlichen: Spalten und Zeilen. In diesem Artikel werden wir uns ansehen, wie man sie verwendet, wann man sie verwendet und alles andere, was man wissen muss.

Ein sehr grundlegendes Beispiel

Hier ist eine sehr einfache Demo von Tabellendaten

Es handelt sich um Daten, die über mehrere Achsen hinweg nützlich sind. Stellen Sie sich vor, Sie fahren mit dem Finger über eine Zeile (horizontal), um eine einzelne Person und relevante Informationen über sie zu sehen. Oder eine Spalte hoch und runter (vertikal), um ein Gefühl für die Vielfalt oder das Muster der Daten an diesem Punkt zu bekommen.

Kopf und Körper

Eine Sache, die wir im sehr grundlegenden Beispiel oben nicht getan haben, ist semantisch anzuzeigen, dass die erste Zeile der Kopf der Tabelle war. Das hätten wir wahrscheinlich tun sollen. Die gesamte erste Zeile enthält keine Daten, es sind lediglich die Titel der Spalten. Wir können dies mit dem <thead>-Element tun, das die erste <tr> umschließen würde (es könnte so viele Zeilen umschließen, wie für Header-Informationen erforderlich sind).

Dieses HTML würde so aussehen

Wenn Sie <thead> verwenden, darf kein <tr> ein direktes Kind von <table> sein. Alle Zeilen müssen entweder innerhalb von <thead>, <tbody> oder <tfoot> liegen. Beachten Sie, dass wir hier auch alle Datenzeilen in <tbody> eingeschlossen haben.

Zusammen mit <thead> und <tbody> gibt es <tfoot> zum Umschließen von Tabellenzeilen, die den Fußbereich der Tabelle angeben. Wie <thead> ist es am besten geeignet, semantisch anzuzeigen, dass es sich nicht um Datenzeilen, sondern um Zusatzinformationen handelt.

Noch vor HTML5 musste das <tfoot>-Element nach <thead> und vor <tbody> stehen! Man könnte meinen, es wäre das Letzte vor dem Ende von <table>, aber das war nicht der Fall. Jetzt in HTML5 ist es genau umgekehrt, es muss nach dem <tbody> kommen, wie man es wahrscheinlich erwarten würde.

Es kann zum Beispiel verwendet werden, um den Header bei einer visuell sehr hohen/langen Tabelle zu wiederholen, wo es einfacher sein kann, die Spaltentitel unten als oben zu sehen. Obwohl Sie es nicht unbedingt so verwenden müssen.

Die Zellen: td und th

Die einzelnen Zellen einer Tabelle sind immer eines von zwei Elementen: <td> oder <th>. Sie können alles in eine Tabellenzelle legen, was Sie möchten, aber dies sind die Elemente, die sie zu einer Tabellenzelle machen. <th>-Elemente sind „tabellarische Überschriften“ und <td>-Elemente sind „tabellarische Daten“.

Mit unserer bestehenden einfachen Demo sind die oberste Zeile alle Überschriften. Keine Daten, nur Titel für die Daten. Alle anderen Zeilen sind Daten. Also

<th>-Elemente sind nicht unbedingt auf die Verwendung innerhalb von <thead> beschränkt. Sie kennzeichnen lediglich Header-Informationen. Sie könnten also beispielsweise am Anfang einer Zeile im <tbody> verwendet werden, falls dies relevant wäre. Einen solchen Fall werden wir später behandeln.

Grundlegendes Styling

Die meisten Tabellen, die Sie jemals sehen werden, verwenden Farben und Linien, um verschiedene Teile der Tabelle zu unterscheiden. Rahmen sind sehr häufig. Standardmäßig sind alle Tabellenzellen um 2px voneinander entfernt (über das User-Agent-Stylesheet), so:

Beachten Sie den leichten zusätzlichen Abstand zwischen der ersten Zeile und dem Rest. Dies wird durch den standardmäßigen border-spacing verursacht, der auf <thead> und <tbody> angewendet wird und sie etwas auseinanderdrückt. Dies sind keine Margins, sie kollabieren nicht. Sie können diesen Abstand steuern wie folgt

table {
  border-spacing: 0.5rem;
}

Aber viel häufiger ist es, diesen Abstand zu entfernen. Diese Eigenschaft wird komplett ignoriert und der Abstand wird aufgehoben, wenn Sie dies tun

table {
  border-collapse: collapse;
}

Nur ein wenig Padding, Ränder und das Linksbündig-Ausrichten dieser <th>-Elemente reicht weit aus, um eine einfache, gestylte Tabelle zu erstellen

Zellen verbinden

Es gibt zwei wichtige Attribute, die für jedes Tabellenzellenelement (<th> oder <td>) verwendet werden können: colspan und rowspan. Sie akzeptieren jede positive Ganzzahl 2 oder größer. Wenn ein td einen colspan von 2 hat (d.h. <td colspan="2">), bleibt es eine einzelne Zelle, nimmt aber horizontal den Platz von zwei Zellen in einer Zeile ein. Dasselbe gilt für rowspan, aber vertikal.

Sie müssen ein bisschen Kopfrechnen betreiben, wenn Sie mit verbundenen Zellen arbeiten. Colspan ist ziemlich einfach. Jede Tabellenzelle ist "eins" wert, es sei denn, sie hat ein colspan-Attribut, dann ist sie so viele wert. Addieren Sie die Werte für jede Tabellenzelle in dieser Tabellenzeile, um den Endwert zu erhalten. Jede Zeile sollte genau diesen Wert haben, sonst erhalten Sie ein ungeschicktes Tabellenlayout, das kein Rechteck bildet (die längste Zeile ragt heraus).

Rowspan ist ähnlich, es ist nur etwas schwieriger und erfordert einen größeren gedanklichen Sprung, da Spalten nicht wie Zeilen gruppiert sind. Wenn ein Tabellenelement ein rowspan-Attribut hat, erstreckt es sich vertikal über zwei Zeilen. Das bedeutet, dass die Zeile darunter +1 zu ihrer Tabellenzellenanzahl erhält und eine Tabellenzelle weniger benötigt, um die Zeile zu vervollständigen.

Es kann schwierig sein, sich das im Kopf vorzustellen, aber wir sind Entwickler hier, wir schaffen das =).

Oft werden diese Attribute auf sehr einfache Weise verwendet, z. B. um einige verwandte Tabellenüberschriften zu verbinden

So breit wie nötig... Oder den Container füllen... Oder darüber hinaus

Das Tabellenelement selbst ist ungewöhnlich in seiner Breite. Es verhält sich wie ein Block-Level-Element (z.B. <div>), da jede Tabelle, wenn man eine nach der anderen platziert, in eine eigene Zeile umbricht. Aber die tatsächliche Breite der Tabelle ist nur so breit wie nötig.

Wenn die Textmenge in der breitesten Zeile der Tabelle nur 100px breit ist, wird die Tabelle 100px breit sein. Wenn die Textmenge (auf einer Zeile) breiter als der Container wäre, wird sie umbrochen.

Wenn Text jedoch nicht umbrochen werden soll (d.h. white-space: nowrap;), sprengt die Tabelle gerne den Container und wird breiter. Tabellenzellen werden ebenfalls nicht umbrochen, so dass die Tabelle auch breiter wird, wenn zu viele nicht hineinpassen.

Zweiachsige Tabellen

Manchmal ist es sinnvoll, wenn tabellarische Daten zwei Achsen haben. Wie eine Kreuzreferenzsituation. Eine Multiplikationstabelle ist ein Beispiel dafür

Ich würde in dieser Situation ein <thead> weglassen, obwohl diese erste Zeile komplett eine Überschrift ist. Sie ist nicht wichtiger als die vertikale Spalte der Überschriften, daher fühlt es sich seltsam an, diese oberste Zeile allein zu gruppieren. Erstellen Sie einfach eine Zeile mit allen <th> und jede nachfolgende Zeile mit der ersten Zelle nur als <th>.

Wann Tabellen verwendet werden sollten

Es ist ein guter Zeitpunkt, eine Pause einzulegen und das wann von Tabellen zu diskutieren. Vielleicht haben Sie den allgemeinen Rat gehört: Tabellen sind für tabellarische Daten (siehe den ersten Satz dieses Blogbeitrags). Der Test „Würde das in einer Tabellenkalkulation Sinn ergeben?“ ist normalerweise angemessen.

Welche Arten von Dingen sind in Tabellen angebracht? Hier sind einige: ein Plan-/Preis-/Funktionsvergleich, Bowling-Ergebnisse, ein internes Raster mit Mitarbeiterdaten, Finanzdaten, ein Kalender, das Nährwertinformationsfeld, ein Logikrätsellöser usw.

Manchmal hört man: Tabellen sind unsemantisch. Das stimmt nicht – sie kennzeichnen semantisch tabellarische Daten. Tabellen sind die richtige Wahl, wenn dies der Fall ist.

Wann Tabellen nicht verwendet werden sollten

Ein ungeeigneter Einsatz für Tabellen ist das Layout. Das mag kontraintuitiv erscheinen. Auf den ersten Blick könnte die Funktionsweise von Tabellen sie ideal für das Layout erscheinen lassen. Einfach zu steuern, extrem logisch, vorhersehbar und überhaupt nicht fragil.

Es gibt jedoch einige erhebliche Probleme bei der Verwendung von Tabellen für das Layout. Erstens bedeuten HTML-Tags etwas. Wie wir bereits besprochen haben, beschreiben Tabellenelemente semantisch tabellarische Daten. Sie für etwas anderes zu verwenden, ist ein Verstoß gegen die semantische Pflicht. Sie werden keine Geldstrafe per Post erhalten, aber Sie erhalten nicht so viel Wert aus Ihrem HTML, wie Sie könnten.

Über Semantik zu sprechen ist manchmal etwas schwierig (einige Lesetipps: 1, 2, 3, 4, 5), also sprechen wir über etwas, worüber wir uns alle im Allgemeinen einig sind (auch wenn wir nicht so gut darin sind, wie wir es gerne wären): Websites sollten barrierefrei sein. Ein Teil der Barrierefreiheit sind Screenreader. Screenreader lesen Tabellen von oben nach unten, von links nach rechts. Das bedeutet, dass die Reihenfolge, in der Ihre Website präsentiert wird, durch die Tabellenstruktur bestimmt wird, die wiederum durch visuelle Entscheidungen und nicht durch Barrierefreiheitsentscheidungen bestimmt wird. Ganz zu schweigen davon, dass ein Screenreader sogar den Beginn tabellarischer Daten ankündigen könnte, was schlimmer als nutzlos wäre.

Apropos Quelltextreihenfolge, das beeinflusst mehr als nur die Zugänglichkeit. Stellen Sie sich ein Layout mit einer "Sidebar links" vor. Eine Tabelle würde vorschreiben, dass diese Tabelle zuerst in der Quelltextreihenfolge steht, was zwar schlecht für die Zugänglichkeit ist, aber wahrscheinlich auch schlecht für SEO, da möglicherweise Ihr Nebeninhalte über den primären Inhalt gestellt werden.

Könnten Sie die SEO-Probleme beheben, indem Sie semantische Tags innerhalb der Tabellen-Tags verwenden? Vielleicht etwas, aber jetzt verwenden Sie doppelt so viel HTML. Wenn Sie wirklich die Layout-Fähigkeiten einer Tabelle benötigen, aber semantische Tags verwenden möchten, lesen Sie den nächsten Abschnitt. Wenn Sie irgendwie absolut darauf angewiesen sind, Tabellen-Tags für das Layout zu verwenden, verwenden Sie das ARIA role="presentation" auf der Tabelle, um dies anzuzeigen.

Während ich dies in der zweiten Hälfte des Jahres 2013 schreibe, sind Tabellen als Layout-Wahl weitaus weniger verbreitet und sogar ansprechend geworden. Wir sehen viel mehr den Einsatz von fester und absoluter Positionierung, die man innerhalb einer Tabelle nicht machen kann. Wir sehen Flexbox als großartig an und sind kurz vor dem Mainstream-Einsatz. Wir sehen, wie das Grid-Layout wächst. Wir sehen, wie Inline-Block wirkungsvoll eingesetzt wird. Wir sehen, wie die Fragilität von Floats in alten Zeiten verblasst.

Moderne Websites verwenden Tabellen selten für das Layout. Der letzte Rückzugsort sind HTML-E-Mails. Die Landschaft dessen, was E-Mails rendert, ist superweit. Es ist alles, womit wir im Web zu tun haben, plus die Welt der nativen Apps auf Mobil- und Desktop-Betriebssystemen, neuen und alten. Man kann progressive Verbesserungen für E-Mails vornehmen, aber das Layout selbst gilt immer noch als am sichersten in Tabellen erstellt. Das wird durch die Tatsache untermauert, dass die großen E-Mail-Dienste immer noch Vorlagen als Tabellen anbieten.

Semantische Elemente sich wie eine Tabelle verhalten lassen

CSS verfügt über Eigenschaften, um jedes gewünschte Element so zu verhalten, als wäre es ein Tabellenelement. Sie müssen sie im Wesentlichen wie eine Tabelle strukturieren, und es wird derselben Abhängigkeit von der Quellreihenfolge unterliegen wie eine Tabelle, aber Sie können es tun. Ich mache es auch nicht schlecht, es ist manchmal wirklich nützlich. Wenn dieser Layout-Stil ein Problem löst und keine negativen Reihenfolge-Auswirkungen hat, verwenden Sie ihn.

Verwenden Sie keine Inline-Stile, aber zum besseren Verständnis sehen Sie hier, wie das funktionieren würde

<section style="display: table;">
  <header style="display: table-row;">
    <div style="display: table-cell;"></div>
    <div style="display: table-cell;"></div>
    <div style="display: table-cell;"></div>
  </header>
  <div style="display: table-row;">
    <div style="display: table-cell;"></div>
    <div style="display: table-cell;"></div>
    <div style="display: table-cell;"></div>
  </div>
</section>

Ein praktischer Trick hier ist, dass Sie das table-row-Element nicht einmal benötigen, wenn Sie nicht möchten. Eine Reihe von display: table-cell;-Elementen, die Kinder eines display: table;-Elements sind, verhalten sich so, als wären sie alle in einer Zeile.

Sie ändern immer die Anzeigeeigenschaft des Elements, um das tabellenartige Verhalten zu erhalten. Hier sind die Werte

display: table                /* <table>     */
display: table-cell           /* <td>        */
display: table-row            /* <tr>        */
display: table-column         /* <col>       */
display: table-column-group   /* <colgroup>  */
display: table-footer-group   /* <tfoot>     */
display: table-header-group   /* <thead>     */

Beachten Sie, dass es keine <th>-Alternative gibt. Das hat nur semantischen Wert. Ansonsten verhält es sich genau wie ein <td>, daher ist es nicht nötig, es in CSS zu replizieren.

Es gibt auch display: inline-table;, was ziemlich interessant ist. Erinnern Sie sich, wir haben oben darüber gesprochen, wie seltsam die Breiten von Tabellenelementen sind. Sie sind nur so breit, wie sie sein müssen, brechen aber in neue Zeilen um. Es ist fast so, als wären es Inline-Block-Elemente, die zufällig umbrechen. Dies macht sie buchstäblich zu Inline-Block-Elementen, ohne den Zeilenumbruch.

Wenn Sie viel mehr über die Verwendung semantischer Elemente, aber auch über tabellenartiges Layout erfahren möchten, lesen Sie das Buch Everything You Know About CSS Is Wrong!

Ich war nie ein großer Fan dieses Titels, da er suggeriert, dass die Verwendung dieses tabellenartigen Layouts der richtige Weg ist und jede andere Layout-Technik, die Sie verwenden, der falsche Weg ist. Aber wie ich bereits sagte, kann dies ungeheuer nützlich sein, und ich bin froh, dass es in CSS enthalten ist. Seien Sie sich nur bewusst, dass egal welche Art von Elementen Sie verwenden, um ein tabellenbasiertes Layout zu erstellen, es immer noch denselben Problemen unterliegt (hauptsächlich der Abhängigkeit von der Quellreihenfolge).

Es gibt einige Elemente oben, die wir noch nicht behandelt haben. Werfen wir einen Blick auf alle HTML-Tabellen-bezogenen Elemente. Wissen Sie was, wir könnten genauso gut eine Tabelle verwenden, um das zu tun

ElementWas es ist
<table>Die Tabelle selbst
<caption>Die Beschriftung für die Tabelle. Wie eine figcaption für eine Figur.
<thead>Der Tabellenkopf
<tbody>Der Tabellenkörper
<tfoot>Der Tabellenfuß
<tr>Eine Tabellenzeile
<th>Eine Tabellenzelle, die eine Überschrift ist
<td>Eine Tabellenzelle, die Daten enthält
<col>Eine Spalte (ein inhaltsloses Element)
<colgroup>Eine Spaltengruppe

Es gibt überraschend wenige Attribute, die spezifisch für Tabellen sind. Natürlich können Sie Klasse und ID und alle typischen globalen Attribute verwenden. Früher gab es ziemlich viele, aber die meisten davon waren spezifisch für das Styling und daher veraltet (da dies die Aufgabe von CSS ist).

AttributElement(e) gefunden aufWas es bewirkt
colspanth, tdErweitert eine Zelle, um so breit wie 2 oder mehr Zellen zu sein
rowspanth, tdErweitert eine Zelle, um so hoch wie 2 oder mehr Zellen zu sein
spancolSorgt dafür, dass die Spalte für 2 oder mehr Spalten gilt
sortierbarTabelleZeigt an, dass die Tabelle das Sortieren ermöglichen sollte. UPDATE: Mir wurde gesagt, dass dies aufgrund mangelnder Implementierungen aus der Spezifikation entfernt wurde.
headerstdLeerzeichen-separierte Zeichenkette, die den IDs der für die Daten relevanten <th>-Elemente entspricht
scopethrow | col | rowgroup | colgroup (Standard) – spezifiziert im Wesentlichen die Achse der Überschrift. Standard ist, dass eine Überschrift eine Spalte überschreibt, was typisch ist, aber eine Zeile könnte auch mit einer Überschrift beginnen, wobei Sie diese Überschrift auf die Zeile oder Zeilengruppe beschränken würden.

Veraltete Attribute

Verwenden Sie keine dieser Eigenschaften. Sie sind veraltet. Auch wenn sie heute in einigen Browsern funktionieren mögen, besteht die Möglichkeit, dass sie in Zukunft nicht mehr funktionieren.

Veraltetes AttributWas stattdessen verwendet werden sollte
alignVerwenden Sie stattdessen die Eigenschaft float.
valignVerwenden Sie stattdessen die Eigenschaft vertical-align.
charDie richtige Antwort ist, text-align: "x"; zu verwenden, wobei x das Zeichen ist, an dem ausgerichtet werden soll, aber es ist noch nirgendwo implementiert. Dieses Attribut wird jedoch auch nicht unterstützt, also kein großer Verlust.
charoffSiehe oben
bgcolorVerwenden Sie stattdessen die Eigenschaft background.
abbr„Erwägen Sie, den Zelleninhalt mit einem eigenständigen abgekürzten Inhalt zu beginnen oder den abgekürzten Inhalt als Zelleninhalt zu verwenden und den langen Inhalt als Beschreibung der Zelle zu verwenden, indem Sie ihn in das title-Attribut setzen.“
axisVerwenden Sie stattdessen das Attribut scope.
borderVerwenden Sie stattdessen die Eigenschaft border.
cellpaddingVerwenden Sie stattdessen die Eigenschaft padding.
cellspacingVerwenden Sie stattdessen die Eigenschaft border-spacing.
frameVerwenden Sie stattdessen die Eigenschaft border.
rulesVerwenden Sie stattdessen die Eigenschaft border.
summaryVerwenden Sie stattdessen das <caption>-Element.
widthVerwenden Sie stattdessen die Eigenschaft width.

Der Tabellenstapel

Es gibt eine implizite vertikale Stapelung von Tabellenelementen, genau wie bei jedem HTML-Eltern- > Nachfahren-Szenario. Es ist wichtig, dies in Tabellen zu verstehen, da es besonders verlockend sein kann, Dinge wie Hintergründe auf die Tabelle selbst oder Tabellenzeilen anzuwenden, nur um dann festzustellen, dass der Hintergrund einer Tabellenzelle diesen "überschreibt" (er liegt eigentlich nur darüber).

So sieht das aus (mit der 3D-Funktion von Firefox in seinen Entwicklertools)

Wichtige Stilregeln für Tabellen

Die meisten CSS-Eigenschaften können auf Tabellenelemente angewendet werden. font-family funktioniert beispielsweise auf Tabellen genauso wie auf jedes andere Element. Und die Regeln der Kaskade gelten. Wenden Sie font-family auf die Tabelle an, aber eine andere font-family auf die Tabellenzelle, gewinnt die Tabellenzelle, da dies das tatsächliche Element mit dem Text darin ist.

Diese Eigenschaften sind entweder einzigartig für Tabellenelemente oder sie verhalten sich einzigartig auf Tabellenelementen.

CSS-EigenschaftMögliche WerteWas es bewirkt
vertical-alignbaseline
sub
super
text-top
text-bottom
middle
top
bottom
%
length (Länge)
Richtet den Inhalt innerhalb einer Zelle aus. Funktioniert besonders gut in Tabellen, obwohl in diesem Kontext nur top/bottom/middle viel Sinn ergeben.
white-spacenormal
pre
nowrap
pre-wrap
pre-line
Steuert, wie Text in einer Zelle umbrochen wird. Einige Daten müssen möglicherweise in einer einzigen Zeile stehen, um sinnvoll zu sein.
border-collapsecollapse
separate
Wird auf die Tabelle angewendet, um zu bestimmen, ob Ränder in sich selbst kollabieren (ähnlich wie Margin-Kollaps, nur bidirektional) oder nicht. Was ist, wenn zwei ineinander kollabierende Ränder widersprüchliche Stile (z. B. Farbe) haben? Die auf diese Elementtypen angewendeten Stile "gewinnen" in der Reihenfolge ihrer "Stärke": Zelle, Zeile, Zeilengruppe, Spalte, Spaltengruppe, Tabelle.
border-spacinglength (Länge)Wenn border-collapse auf separate gesetzt ist, können Sie angeben, wie weit Zellen voneinander entfernt sein sollen. Moderne Version des cellspacing-Attributs. Und apropos, padding ist die moderne Version des cellpadding-Attributs.
widthlength (Länge)Width funktioniert bei Tabellenzellen ungefähr so, wie Sie es erwarten würden, außer wenn es eine Art Konflikt gibt. Wenn Sie zum Beispiel der Tabelle selbst eine Breite von 400px geben und der ersten Zelle einer dreizelligen Zeile eine Breite von 100px zuweisen und die anderen in Ruhe lassen, ist die erste Zelle 100px breit und die anderen beiden teilen sich den restlichen Platz auf. Wenn Sie jedoch allen dreien eine Breite von 10000px geben, bleibt die Tabelle 400px breit und gibt jedem von ihnen ein Drittel des Platzes. Dies setzt voraus, dass white-space oder Elemente wie ein Bild nicht ins Spiel kommen. Dies ist wahrscheinlich ein eigener Beitrag!
borderlength (Länge)Border funktioniert auf jedem der Tabellenelemente und so, wie Sie es erwarten würden. Die Eigenheiten treten auf, wenn Sie die Ränder kollabieren. In diesem Fall haben alle Tabellenzellen nur eine Randbreite zwischen sich, anstatt der zwei, die Sie erwarten würden (border-right an der ersten Zelle und border-left an der nächsten Zelle). Um einen Rand in einer kollabierten Umgebung zu entfernen, müssen beide Zellen "zustimmen", ihn zu entfernen. Wie td:nth-child(2) { border-right: 0; } td:nth-child(3) { border-left: 0; } Andernfalls gewinnt die Quellreihenfolge/Spezifität, welcher Rand an welcher Kante angezeigt wird.
table-layoutauto
fixed
auto ist der Standardwert. Die Breite der Tabelle und ihrer Zellen hängt vom Inhalt ab. Wenn Sie dies auf fixed ändern, werden die Breiten der Tabelle und der Spalten durch die Breiten der Tabellen- und Spaltenelemente oder durch die Breite der ersten Zeile der Zellen festgelegt. Zellen in nachfolgenden Zeilen beeinflussen die Spaltenbreiten nicht, was das Rendern beschleunigen kann. Wenn der Inhalt in nachfolgenden Zellen nicht passt, bestimmt die overflow-Eigenschaft, was passiert.

Diese Liste ist nicht erschöpfend. Es gibt andere CSS-Eigenheiten, die für Tabellen relevant sind. Sie können beispielsweise eine Tabellenzelle nicht relativ positionieren, um sie entweder zu verschieben oder Dinge absolut darin zu positionieren. Es gibt jedoch Wege.

Wenn Ihnen weitere CSS-Eigenheiten bei Tabellen einfallen, teilen Sie diese bitte in den Kommentaren unten mit.

Standardstile / User-Agent-Stylesheet

WebKit macht das hier

table {
    display: table;
    border-collapse: separate;
    border-spacing: 2px;
    border-color: gray
}

thead {
    display: table-header-group;
    vertical-align: middle;
    border-color: inherit
}

tbody {
    display: table-row-group;
    vertical-align: middle;
    border-color: inherit
}

tfoot {
    display: table-footer-group;
    vertical-align: middle;
    border-color: inherit
}

table > tr {
    vertical-align: middle;
}

col {
    display: table-column
}

colgroup {
    display: table-column-group
}

tr {
    display: table-row;
    vertical-align: inherit;
    border-color: inherit
}

td, th {
    display: table-cell;
    vertical-align: inherit
}

th {
    font-weight: bold
}

caption {
    display: table-caption;
    text-align: -webkit-center
}

Ich habe auch jedes Element in den Chrome Dev Tools inspiziert, die jetzt auf Blink basieren, und es ist immer noch dasselbe.

Es ist jedoch lustig. Sicherlich ist der Text in <th>-Elementen standardmäßig zentriert (text-align: center;). Aber das steht nicht im UA-Stylesheet. Keine große Sache, aber eher mysteriös und lässt einen fragen, welche anderen mysteriösen Dinge beim Rendering passieren.

Das UA-Stylesheet für Tabellen unterscheidet sich von Browser zu Browser. Zum Beispiel haben Tabellenzellen in Firefox (hier ist 3.6s UA Stylesheet, aber das gilt auch in v23) dies

td { 
  display: table-cell;
  vertical-align: inherit;
  text-align: inherit; 
  padding: 1px;
}

Am auffälligsten ist der 1px-Abstand, den WebKit nicht hat. In den meisten Fällen ist das sicherlich keine große Sache, aber es ist anders. Darum geht es bei CSS-Resets (und verwandten Projekten): die Unterschiede zu beseitigen. Also schauen wir uns das mal an.

Standard-Tabellenstile zurücksetzen

Der weltweit beliebteste CSS-Reset, der Meyer Reset, macht dies mit Tabellen

table, caption, tbody, tfoot, thead, tr, th, td {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}

Es wird auf die gleiche Weise im HTML5 Reset und im HTML5 (Doctor) Reset Stylesheet gemacht.

Es gibt jedoch eine Alternative zu CSS-Resets: Normalize.css. Die Philosophie ist etwas anders. Anstatt alle Stile auf Null zu setzen, werden bekanntermaßen inkonsistente Stile explizit auf einen vernünftigen Standardwert gesetzt. Mein allgemeiner Rat zur Verwendung von Normalize.css lautet: Entfernen Sie nichts daraus. Wenn es darin enthalten ist, muss es zur Konsistenz dienen. Aber fühlen Sie sich frei, alles darin zu ändern.

Normalize macht das nur für Tabellen

table {
  border-collapse: collapse;
  border-spacing: 0;
}

Ich muss mich hier etwas tiefer in die Begründung einarbeiten, denn es scheint ungewöhnlich...

  1. Ich bin ein Fan von border-collapse: collapse, weil der Abstand zwischen den Zellen normalerweise sehr unangenehm ist, aber der Standard in jedem mir bekannten Browser ist border-collapse: separate;, so dass keine Normalisierung erforderlich ist.
  2. Wenn border-collapse auf collapse gesetzt ist, spielt border-spacing keine Rolle.
  3. Tabellenzellen-Elemente müssen normalisiert werden (z.B. Firefox Padding-Unterschied), aber das ist nicht vorhanden.

Keine riesige Sache.

Das ist die Art von Sache, die ich wahrscheinlich normalerweise tun würde

table {
  border-collapse: collapse;
  width: 100%;
}
th, td {
  padding: 0.25rem;
  text-align: left;
  border: 1px solid #ccc;
}

„Implizite“ Elemente und nicht geschlossene Tags

Schau dir dieses ziemlich umständliche Stück HTML an

<table>
  <col>
  <tr>
    <td>Cell
</table>

Das mag seltsam aussehen, aber es ist gültig. Was passiert hier?

  • Der <col>-Tag ist einfach eines dieser inhaltslosen Elemente, das nie einen schließenden Tag benötigt. Wie <br> / <br />
  • Das <td>-Element muss unter bestimmten Umständen nicht geschlossen werden: „Der End-Tag darf weggelassen werden, wenn ihm unmittelbar ein <th>- oder <td>-Element folgt oder wenn in seinem Elternelement keine weiteren Daten vorhanden sind.“
  • Das fehlende schließende </tr>-Tag ist die gleiche Geschichte: „Das End-Tag darf weggelassen werden, wenn dem <tr>-Element unmittelbar ein <tr>-Element folgt oder wenn das übergeordnete Tabellengruppen-Element (<thead>, <tbody> oder <tfoot>) keinen weiteren Inhalt hat.“

Wenn wir die gerenderte Tabelle im Browser inspizieren, können wir sehen, dass die Tags, denen ihre schließenden Tags fehlten, mit schließenden Tags angezeigt werden. Diese werden automatisch für uns hinzugefügt. Aber es gibt auch einige brandneue Elemente darin

Eine Sache, die man beachten sollte, ist, dass das <col> automatisch in ein <colgroup> eingeschlossen wird. Selbst wenn wir dies tun würden

<table>
  <col>
  <colgroup>
    <col>
  </colgroup>
  <tr>
    <td>Cell
    <td>Cell
</table>

Dann

colgroup:first-child {
  background: red;
}

Man würde denken, die zweite Zelle wäre rot, nicht die erste, weil die "erste" Colgroup nur die zweite Zelle betrifft. Aber beim Rendern werden beide Spalten in eine Colgroup eingeschlossen, so dass der CSS-Selektor die erste auswählt.

Das <tbody>-Element ist ebenfalls impliziert. Wenn Sie keine von tbody, thead oder tfoot verwenden, wird das gesamte Innere der Tabelle in tbody eingeschlossen. Wenn Sie ein thead verwenden, wird die gesamte Tabelle darin eingeschlossen, bis ein tbody gefunden wird, dann wird das thead automatisch geschlossen, wenn Sie es nicht tun, und der Rest in tbody eingeschlossen (ebenfalls optional zu schließen). Wenn ein tfoot gefunden wird, können Sie sich vorstellen, was passiert (obwohl Sie sich erinnern sollten, dass tfoot vor tbody kommen sollte).

Sie können diese Elemente tatsächlich in CSS-Selektoren verwenden, obwohl Sie sie nicht in Ihrem tatsächlichen HTML platziert haben. Ich würde es wahrscheinlich nicht empfehlen, einfach weil das seltsam und verwirrend ist und das Styling von Tag-Selektoren ohnehin meist nicht ratsam ist.

Eine Tabelle zu keiner Tabelle machen

Es kann eines Tages eine Situation eintreten, in der Sie ein Tabellenelement zwingen müssen, sein tabellenartiges Layout-Verhalten nicht zu zeigen und sich eher wie ein reguläres Element zu verhalten.

Der Trick besteht im Wesentlichen darin, die Anzeigeeigenschaft der Tabellenzellen zurückzusetzen

th, td {
  display: inline;
}

Wir können eine Tabelle ziemlich schnell ent-tabellisieren

Nur um sicherzugehen, würde ich das Ganze zurücksetzen. Ich fühle mich einfach besser, wenn ich weiß, dass die Elternelemente auch mitmachen und nicht verrückt spielen.

table, thead, tbody, tfoot, tr, td, th, caption {
  display: block;
}

Dies ist hauptsächlich im responsiven Design nützlich, wo das traditionelle Tabellenlayout auf großen Bildschirmen Sinn ergibt, aber auf kleineren Bildschirmen erhebliche Änderungen erfordert, um sinnvoll zu sein. Dazu gibt es unten einen ganzen Abschnitt.

Tabellen-Barrierefreiheit

Wir haben bereits über die Probleme bei der Verwendung von Tabellen für Layout und Barrierefreiheit gesprochen. Aber vorausgesetzt, Tabellen werden korrekt für tabellarische Daten verwendet, gibt es immer noch einige Bedenken hinsichtlich der Barrierefreiheit.

Es gibt einige großartige Artikel dazu da draußen

Zebra-Tabellen

Wenn Sie keine Hintergrundfarbe auf die Tabellenzellen-Elemente setzen, können Sie sie auf die Tabellenzeilen selbst setzen. Am einfachsten können Sie also Folgendes tun

tbody tr:nth-child(odd) {
  background: #eee;
}

Wir verwenden den tbody im Selektor, da es unwahrscheinlich ist, dass Sie Header- und Footer-Zeilen gestreift haben möchten. Setzen Sie auch die geraden Zeilen, wenn Sie spezifisch sein möchten, anstatt das durchscheinen zu lassen, was darunter liegt.

Wenn Sie Browser unterstützen müssen, die :nth-child() nicht verstehen (ziemlich alt), können Sie jQuery dafür verwenden.

Studien scheinen zu zeigen, dass Zebra-Striping im Allgemeinen eine gute Idee ist.

Hervorheben von Zeilen und Spalten

Das Hervorheben einer bestimmten Zeile ist ziemlich einfach. Sie könnten einer Zeile speziell dafür einen Klassennamen hinzufügen

<tr class="highlight">
  ...
</tr>

Das Hervorheben einer Spalte ist etwas kniffliger. Eine Möglichkeit ist die Verwendung des <col>-Elements, das uns erlaubt, Stile für Zellen festzulegen, die in dieser Spalte erscheinen. Es ist seltsam, sich das vorzustellen, denn die Zellen, die von <col> betroffen sind, sind eigentlich keine Nachkommen davon. Der Browser weiß einfach irgendwie, was Sie meinen.

Eine Tabelle mit vier Spalten in jeder Zeile hätte vier <col>-Elemente

<table>
  <col>
  <col>
  <col>
  <col>

  <thead>
     ...

</table>

Dann könnten Sie eine bestimmte hervorheben, wie z.B.

col:nth-child(3) {
  background: yellow; 
}

Dies ist jedoch selten nützlich. Wenn Sie den Hintergrund eines Zeilenelements oder Tabellenzellenelements festlegen, übertrifft dieser immer den Hintergrund eines Spaltenelements. Unabhängig von der Spezifität.

Es ist wahrscheinlich besser, jedem einzelnen Tabellenzellenelement einen Klassennamen zu geben, der zufällig mit der Spaltenposition in der Zeile übereinstimmt. Wie z.B.

td:nth-child(2),
th:nth-child(2){
  background: yellow;
}

Hervorheben von Spalte/Zeile/Zelle beim Hover

Zellenhervorhebung ist sehr einfach. Sie können es direkt in CSS tun

td:hover { /* th:hover also if you wish */
  background: yellow;
}

Zeilenhervorhebung ist genauso einfach. Sie können den Hintergrund für Tabellenzeilen festlegen, und er wird angezeigt, solange Sie keinen Hintergrund für die Tabellenzellen festlegen.

tbody tr:hover {
  background: yellow;
}

Wenn Sie einen Hintergrund für die Tabellenzellen festlegen, können Sie immer einfach tr:hover td, tr:hover th { } verwenden, was immer noch ziemlich einfach ist.

Spaltenhervorhebung ist schwieriger. Sie können col:hover nicht verwenden, da diese Spalten keine tatsächlichen Elemente sind, die Pixelplatz auf dem Bildschirm einnehmen, über die Sie schweben könnten. Die einzige Option ist JavaScript.

Ich habe es hier in Vanilla JavaScript geschrieben, nur zum Spaß

Es funktioniert so

  1. Sammeln Sie alle Zellen
  2. Verknüpfen Sie ein mouseover- und mouseout-Ereignis mit all diesen Zellen
  3. Wenn das mouseover-Ereignis ausgelöst wird, ermitteln Sie die Position der Zelle in der Zeile.
  4. Durchlaufen Sie alle Zeilen und fügen Sie jeder Zelle in dieser Zeile, die dieser Position entspricht, eine Hervorhebungsklasse hinzu.
  5. Wenn das mouseout-Ereignis ausgelöst wird, entfernen Sie die Hervorhebungsklasse von allen Zellen.

Und hier habe ich sowohl Zeilen- als auch Spaltenhervorhebung kombiniert. Ich habe jQuery verwendet, um alles auf 12 Zeilen Code zu bringen (das reine JavaScript war ziemlich anstrengend).

Es ist dasselbe Konzept, es ist nur viel einfacher, Elementkollektionen zu erstellen und nach Indizes in jQuery zu suchen und auszuwählen.

Schön gestaltete Tabellen

Etwas Tiefe, visuell unterschiedliche Header und ein Terminal, das dem Header entspricht.


Wenn die Tabelle im Hover-Zustand ist, bleiben nur die hervorgehobenen Zeilen mit dunklem Text, die anderen verblassen. Beachten Sie auch hier: Die abgerundeten Ecken der Tabelle selbst sind nur möglich, wenn Sie border-collapse: separate; haben.


Hier ist noch eine, bei der die nicht überfahrenen Zeilen buchstäblich verschwimmen


Twitter Bootstrap hat ein sehr minimalistisches Tabellen-Styling


Dieser hat als Bonus sogar Tastatursteuerung!


Ich versuche, eine Sammlung gut gestalteter Tabellen als Referenz zu führen. Wenn Sie also welche haben, lassen Sie es mich wissen. Hong Kiat hat auch eine Blogpost-Sammlung.

Wo das Sortieren von Tabellen recht kompliziert sein kann, kann die Tabellensuche recht einfach sein. Fügen Sie ein Suchfeld hinzu, und wenn der Wert darin Text irgendwo in einer Zeile übereinstimmt, zeigen Sie diese an und blenden Sie die anderen aus. Mit jQuery könnte das so einfach sein wie

var allRows = $("tr");
$("input#search").on("keydown keyup", function() {
  allRows.hide();
  $("tr:contains('" + $(this).val() + "')").show();
});

Hier ist eine Version mit RegExp stattdessen

Und hier ist eine in reinem JavaScript

Tabellen können in flüssigen/responsiven Designs schwierig sein

Ich habe in der Vergangenheit darüber geschrieben, und ich denke, diese Grafik fasst die Erfahrung einer Datentabelle auf einem kleinen Bildschirm ziemlich gut zusammen

Ich habe letztendlich eine Zusammenfassung erstellt, sobald eine Vielzahl interessanter Lösungen auftauchte.

Ganz schnell aber

Hier sind ein paar gestylte Live-Demos mit verschiedenen Ansätzen

Tabellen mit fester Kopfzeile

Das ist noch etwas, worüber ich in der Vergangenheit geschrieben und auch einen kleinen Screencast gemacht habe. Die sind zwar ziemlich alt, aber die Demo funktioniert immer noch.

Die modernste Art, feste Header zu handhaben, ist position: sticky; Hier ist ein Artikel dazu. Ich bin ehrlich gesagt nicht ganz sicher, wie es am besten mit Tabellen verwendet werden sollte. Es funktioniert unter normalen Umständen nicht auf <thead>. Das macht irgendwie Sinn, weil man Tabelleninhalte nicht absolut positionieren kann. Aber es funktioniert auf <th>. Jedenfalls, wenn jemand das herausfinden will, wäre das ein gutes Update für diesen Artikel (oder so etwas).

Hier ist eine Live-Demo eines jQuery-Plugins, das den Trick macht. Ich würde heutzutage wahrscheinlich so etwas wählen, bis sich "sticky" mehr durchsetzt.

Verwendung von Emmet zur Erstellung von Tabellen-Markup

Emmet ist aus vielen Gründen ein großartiges Werkzeug. Einer davon ist das Schreiben von HTML-Abkürzungen und deren Erweiterung zu echtem HTML. Da Tabellen so repetitiv und ausführlich sind, ist Emmet perfekt dafür. Emmet funktioniert auch auf CodePen =)

Einfache vier Zeilen und vier Spalten

table>tr*4>td*4

Fünf Zeilen mit dem Header auf der linken Seite

table>tr*5>th+td*4

Eine Zeile mit Headern oben

table>tr>th*5^tr*3>td*5

Mitarbeiter mit fortlaufenden IDs

table>tr>th{Name}+th{ID}+th{Favorite Color}^tr*3>td{Name}+td{$$$$$}+td{Blue}

Tabelle mit Kopf-, Fuß- und Inhaltsbereich

table>thead>tr>th*5^^tfoot>tr>th*5^^tbody>tr*10>th+td*4

Dasselbe, aber mit Zellinhalt in jeder Zelle

table>thead>tr>th{Header Cell}*5^^tfoot>tr>th{Footer Cell}*5^^tbody>tr*10>th{Row Header}+td{Cell Data}*4

JavaScript generierte Tabellen

JavaScript bietet einige sehr spezifische Methoden für den Umgang mit Tabellen über die HTMLTableElement-API. Louis Lazaris hat kürzlich etwas darüber geschrieben. Sie können es verwenden, um Tabellen mit JavaScript zu erstellen, auf Unterelemente zuzugreifen und Eigenschaften auf sehr spezifische Weise zu ändern. Hier ist die MDN-Seite mit den Details.

Hier ist das in Aktion

Tabellensortierung

Stellen Sie sich eine Tabelle mit zwei Spalten vor. Eine für Mitarbeiter-IDs und eine andere für die E-Mail-Adresse des Mitarbeiters. Für jede Spalte gibt es Überschriften. Es wäre praktisch, auf diese Überschriften klicken zu können und die Tabelle nach den darin enthaltenen Daten zu sortieren. Zum Beispiel numerisch, abwechselnd auf- und absteigend für die IDs und alphabetisch für die E-Mail-Adressen. Darum geht es bei der Tabellensortierung. Die Daten nützlicher machen.

Dies ist ein so häufiger und allgemeiner Bedarf, dass es tatsächlich eine Spezifikation dafür gibt. Legen Sie einfach das sortable-Attribut für die Tabelle fest, und sie wird dies automatisch tun, solange Sie ein paar in der Spezifikation festgelegte Regeln befolgen.

Update Juni 2019: Link entfernt, da er sortierbar nicht mehr erwähnt. Scheint derzeit eine tote Spezifikation zu sein.

Zum Zeitpunkt des Verfassens dieses Artikels kenne ich keine Browser, die die Tabellensortierung nativ unterstützen. Aber es gibt viele Drittanbieteroptionen!

  • tablesorter – jQuery-basiertes „Flexibles clientseitiges Tabellensortieren“
  • sorttable – reines JavaScript
  • tablesort – „eine kleine & einfache Sortierkomponente für Tabellen. Geschrieben in Javascript und ohne Abhängigkeiten“

Was ist mit Tabellensortierskripten und Kleinbuchstaben? Wie auch immer, hier ist eine Demo von tablesorter

Wenn diese Ihnen nicht genügen, hat Codrops 33 verschiedene Tabellensortierskripte zusammengetragen, es gibt also reichlich Auswahl.

Und das sind alles JavaScript-Lösungen. Es ist sicherlich möglich, Daten im Backend zu sortieren und die Tabelle bereits sortiert in HTML anzuzeigen. Dies könnte im Falle von paginierten Tabellen erforderlich sein, bei denen nicht alle Daten direkt im DOM verfügbar sind.

Weitere Informationen