mitmario.dev

Tabellen richtig strukturieren

HTML Im Browser 3 Min Lesezeit 3 BeispieleLektion 2 von 4

Die Tabelle aus der letzten Lektion funktioniert. Für alles, was größer ist als drei Zeilen, fehlen ihr aber noch ein paar Angaben.

Überschrift und Bereiche

Mit Überschrift und Bereichen
<table>
  <caption>Kochzeiten der Wochenrezepte</caption>

  <thead>
    <tr>
      <th>Gericht</th>
      <th>Dauer</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Linsensuppe</td>
      <td>30 Minuten</td>
    </tr>
    <tr>
      <td>Ofengemüse</td>
      <td>45 Minuten</td>
    </tr>
  </tbody>
</table>

caption ist die Überschrift der Tabelle. Sie gehört als erstes Kind direkt hinter das öffnende table, vor alles andere. An einer anderen Stelle ist sie ungültig, und anders als beim tbody denkt sich der Browser hier nichts dazu. Steht sie hinter den Zeilen, bleibt sie im DOM auch dahinter. Steht sie sogar in einem thead, holt er sie dort heraus und lässt einen leeren thead zurück. Beides ist nicht das, was du gemeint hast, und beim Hinschauen merkst du es nicht: Dargestellt wird die caption immer über der Tabelle.

Warum nicht einfach eine h3 darüber? Weil die Verbindung fehlt. Die caption gehört zur Tabelle, und ein Screenreader liest sie vor, sobald der Nutzer die Tabelle betritt. Bei mehreren Tabellen auf einer Seite ist das der Unterschied zwischen „Tabelle mit drei Spalten“ und „Kochzeiten der Wochenrezepte, Tabelle mit drei Spalten“.

thead fasst die Kopfzeilen zusammen, tbody die Datenzeilen. Beides ändert an der Darstellung nichts, macht aber drei Dinge möglich: Beim Drucken langer Tabellen wiederholen Browser die Kopfzeile auf jeder Seite. Beim Stylen kannst du Kopf und Daten getrennt ansprechen. Und beim Lesen des Codes sieht man sofort, wo die Daten beginnen.

Ein Hinweis, der irritiert, wenn man ihn zum ersten Mal sieht: Der Browser fügt tbody von sich aus ein, auch wenn du es weglässt. In den Tabellen der letzten Lektion steht kein einziges, im fertigen Dokument haben sie trotzdem eins. Kein Fehler, den er stillschweigend gerade biegt: Das Start-Tag von tbody darf man laut Standard weglassen, der Browser setzt dann nur ein, was ohnehin gemeint war. Beim div im p ist das anders, dort war der Code wirklich falsch.

Ansehen kannst du dir das hier allerdings nicht. Was der Browser gebaut hat, steht in keinem der drei Reiter, dafür muss man das Dokument selbst fragen. Wie das geht, kommt in Abschnitt 11.

Die Summenzeile

Mit Summenzeile
<table>
  <caption>Einkauf für die Woche</caption>

  <thead>
    <tr>
      <th>Posten</th>
      <th>Preis</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Linsen</td>
      <td>2,40 Euro</td>
    </tr>
    <tr>
      <td>Suppengrün</td>
      <td>1,80 Euro</td>
    </tr>
  </tbody>

  <tfoot>
    <tr>
      <th>Summe</th>
      <td>4,20 Euro</td>
    </tr>
  </tfoot>
</table>

tfoot ist der Fußbereich, typischerweise für Summen oder Zwischenergebnisse. Beachte die Zeile darin: Die Beschriftung „Summe“ ist ein th, der Betrag ein td. Auch hier gilt wieder, dass th beschriftet und td den Wert trägt.

tfoot gehört ans Ende, hinter den tbody. Früher war es genau umgekehrt, da musste es davor stehen, und in altem Code findest du es deshalb noch oben. Dargestellt wird es so oder so unten.

scope: Spalte oder Zeile

scope sagt, wofür eine Kopfzelle gilt
<table>
  <caption>Kochzeiten nach Portionsgröße</caption>

  <thead>
    <tr>
      <th scope="col">Gericht</th>
      <th scope="col">2 Portionen</th>
      <th scope="col">4 Portionen</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <th scope="row">Linsensuppe</th>
      <td>25 Minuten</td>
      <td>30 Minuten</td>
    </tr>
    <tr>
      <th scope="row">Ofengemüse</th>
      <td>40 Minuten</td>
      <td>45 Minuten</td>
    </tr>
  </tbody>
</table>

Sobald eine Tabelle Kopfzellen sowohl oben als auch links hat, wird die Zuordnung mehrdeutig. Gilt „Linsensuppe“ für die Zeile oder für die Spalte? Ein Mensch sieht es sofort, ein Screenreader muss raten.

scope="col" sagt: Diese Kopfzelle beschriftet die Spalte unter sich. scope="row" sagt: Sie beschriftet die Zeile rechts von sich. Damit liest ein Screenreader die Zelle mit 30 Minuten korrekt als „Linsensuppe, 4 Portionen, 30 Minuten“ vor.

Bei einer schlichten Tabelle mit nur einer Kopfzeile ist scope verzichtbar, da rät niemand falsch. Sobald es Kopfzellen in beiden Richtungen gibt, gehört es dazu. Es kostet zwei Wörter pro Zelle und ist der Unterschied zwischen einer benutzbaren und einer unbenutzbaren Tabelle.

Zum Mitnehmen

caption steht als erstes Kind direkt hinter dem öffnenden table-Tag. Woanders ist sie ungültig, und anders als beim tbody denkt sich der Browser hier nichts dazu. Angezeigt wird sie trotzdem oben, deshalb fällt der Fehler beim Hinschauen gar nicht auf.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

Was in dieser Lektion steckt

  • Artikel mit 3 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.