Camping_RIDER: Semantik bei diagonal geteilter Eckzelle

Aloha ;)

Man kennt aus Printdarstellungen dort, wo Tabellen sowohl je eine Zeilen- als auch einen Spaltentitel[1] tragen, den Fall der diagonal geteilten Zelle in der linken oberen Ecke, in der rechts oben über dem Trennstrich eine zusätzliche Beschriftung für die Spaltentitel und links unten darunter die für die Zeilentitel steht:

Vorschaubild zu einer Tabellendarstellung wie beschrieben; die Zelle im linken oberen Eck ist geteilt, rechts über dem Schrägstrich die Spaltenbeschriftung "Eigenschaft", darunter die Zeilenbeschriftung "Stadt", dann tabellarisch beispielhafte Daten (mit Spaltentitel Bundesland, Einwohner, Kfz-Kennzeichen) zu drei deutschen Städten (München, Düsseldorf, Buxtehude als Zeilentitel).

Mir ist völlig klar, dass diese linke obere Eckzelle nicht zwingend beschriftet sein muss. Meist bietet es sich eher an, dort einen allgemeineren Titel für die Tabelle (im obigen Fall z.B. „Städte und ihre Eigenschaften“) unterzubringen oder die Zelle sogar komplett leer zu lassen, da sich die Spalten und Zeilen für gewöhnlich aus dem Kontext auch selbst erklären und nicht zwingend einer Beschriftung bedürfen.

Trotzdem habe ich mich gefragt: Ist eine solche Darstellung wie im obigen visuellen Beispiel bei sinniger Semantik mit HMTL überhaupt möglich - und wenn ja, wie?

Grundsatz-Konflikt: dreigeteilte Grundstruktur der HTML-Tabelle

Tabellen sind in HTML ja so definiert, dass sie in drei Bereiche unterteilt sind - THEAD, TBODY und TFOOT. Diese Struktur legt imho nahe, dass nach dem Sinn der Spec die Dinge, die im THEAD liegen, von ihrer semantischen Bedeutung her die Dinge beschriften sollen, die im TBODY liegen. Demnach wäre - im obigen Beispiel - in der Zelle links nur die Beschriftung „Stadt“ nötig, denn damit wäre ja die erste Spalte zu beschriften.

Klar, HTML ermöglicht durchaus ja auch weitere Titel in der Zeile (TH im TBODY), die sind aber Teil des Tabellenkörpers und - zumindest meinem Gefühl nach - aufgrund der übergeordneten dreiteiligen Struktur eher nachrangig, die Spaltentitel sind durch Platzierung im THEAD höherrangig - und demnach wäre dann im THEAD zunächst die Spalte zu beschriften, also kein vorgesehener Platz für eine Beschriftung der Spaltentitel.

Die als Beispiel gezeigte Tabelle hat im Kontrast dazu - zumindest visuell - gleichberechtigte Spalten- und Zeilentitel, die auch je eine eigene Beschriftung in der Eckzelle bekommen.

Okay, ich könnt jetzt natürlich, um diese Gleichberechtigung zu erzwingen, auch die Spaltenüberschriften in den TBODY zwängen - aber ob das etwas besser macht?

Ist eine solche Tabelle also mit der HTML-Tabelle eigentlich semantisch überhaupt nicht darstellbar, weil sie eine ganz andere als die vorausgesetzte Grundstruktur hat?

Wie ich das bisher gelöst hätte und warum das nicht gut ist

Bisher habe ich in solchen Fällen die Spaltenüberschrift in der Eckzelle links oben oft zweckentfremdet und dort beides reingeschrieben, mit Trennstrich, oder in Absätzen mit unterschiedlichem Alignment, also z.B. "Stadt / Eigenschaft" - oder eben auch mal leer gelassen.

Im vorliegenden Fall (nicht an diesem Minimalbeispiel) sind die konkreten Spaltentitel aber user-generated content und das Bedürfnis, diese noch einmal mit einer Beschriftung zu versehen ist da - und mir gefällt die "Stadt / Eigenschaft"-Lösung nicht, auch, weil sie semantisch falsch ist (semantisch beschriftet diese TH ja die Spalte, und in der kommen eben nur Städte, keine Eigenschaften vor.

Meine Überlegung

Ich habe ein wenig experimentiert, ob ich das semantisch nicht besser hinbekomme und habe sowas wie eine Lösung gefunden (es geht mir im Pen nicht um das CSS, das ich einfach nur irgendwie reingedengelt habe damit die Tabelle auch visuell zeigt was sie vermitteln soll, sondern um das HTML, um die semantische Struktur).

Ganz gut gefällt mir, dass in dieser Lösung die Spaltenbeschriftung und die Zeilenbeschriftung je in relativ eindeutiger Relation zu den Spalten-/Zeilentiteln stehen:

Für die Spaltentitel ist die Spaltenbeschriftung die erste Zelle mit Inhalt in dieser Zeile (und in den anderen Zeilen steht in dieser 2. Spalte kein originärer, eigener Inhalt, auf den sich die Beschriftung beziehen könnte) und für die Zeilentitel ist die Zeilenbeschriftung die erste Zelle in dieser Spalte (und in den anderen Spalten steht in dieser 2. Zeile kein originärer eigener Inhalt, auf den sich die Beschriftung beziehen könnte).

Überhaupt nicht gefallen mir die leeren TH-Elemente und der Umstand, dass mein herbeigeredeter "klarer Zusammenhang", siehe Absatz drüber, gar nicht so stark ist, immerhin würden die Colspan/Rowspan ja auch einen Zusammenhang suggerieren, das Argument ist also nicht ohne Schwachstellen.

Trotzdem interessiert mich eure Meinung (zur semantischen Grundsatzproblematik): Wie findet ihr meinen neuen Lösungsansatz? Ist das Quatsch? Gibts darin No-Gos, die ich übersehe? Seht ihr bessere Lösungsmöglichkeiten? Ist es letztlich eine unlösbare Aufgabe weil HTML-Tabellen so einfach nicht funktionieren und nicht jede Print-Tabelle sinnvoll als HTML-Tabelle umgesetzt werden könnte?

Ihr braucht euch nicht verkünsteln, wenn euer Rat lautet "nimm keine TABLE, sondern custom elements mit WAI-ARIA" verstehe ich das auch ohne konkret funktionierendes Beispiel 😉 Mich interessieren vor allem eure Meinungen und Standpunkte zum Thema.

Grüße,

RIDER

--
Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Albers-Zoller
# Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[

  1. Wording: Ich versuche hier konsequent zwischen "Spaltentitel" als "Beschriftung für eine Spalte" und "Spaltenbeschriftung" für den "Titel der Spaltentitel" zu unterscheiden (und entsprechend für Zeilen), sonst wirds noch verwirrender. ↩︎

akzeptierte Antworten

  1. Lieber Camping_RIDER,

    mir fällt da nur eine entsprechende Extrazeile darüber und eine Extraspalte links dazu ein.

    Tabelle mit einem Titel für die Spaltenbeschriftungen und einem Titel für die Zeilenbeschriftungen

    Liebe Grüße

    Felix Riesterer

    1. Aloha ;)

      mir fällt da nur eine entsprechende Extrazeile darüber und eine Extraspalte links dazu ein.

      Tabelle mit einem Titel für die Spaltenbeschriftungen und einem Titel für die Zeilenbeschriftungen

      Stimmt, das wäre auch eine Option. Nachteil: die "leeren" THs oben links im Eck bleiben, ähnlich wie bei meiner Lösung. Semantisch ist die Idee aber vielleicht tatsächlich eindeutiger.

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Albers-Zoller
      # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
  2. Hallo Janosch,

    in einer Tabelle wie im Beispiel würde ich auf die "Eigenschaften" Überschriftenzelle verzichten.

    Aber um deine Überlegung nicht einfach abtropfen zu lassen: Sowas ist schon sinnvoll, wenn es eine echte Tabelle ist und keine verkappte Liste, d.h. wenn die Spaltenüberschriften nicht für sich stehen können, wie z.B in:

           Jahr |
    Stadt       |   2000   2010   2020
    ------------+-------------------------
        München |    
           Köln |
      Buxtehude |
    

    mit irgendwelchen Zahlen drin, bspw. SelfHTML-Abrufe. Deinen Ansatz finde ich – sofern die semantische Anwendbarkeit gegeben ist – grundsätzlich ganz gut, aber ein bisschen muss hinzu:

    <table>
      <caption>Selfhtml-Abrufe</caption>
      <thead>
        <tr>
          <th scope="row" colspan="2">Jahr</th>
          <th scope="col" rowspan="2">2000</th>
          <th scope="col" rowspan="2">2010</th>
          <th scope="col" rowspan="2">2020</th>
        </tr>
        <tr>
          <th scope="col" colspan="2">Stadt</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th scope="row" colspan="2">München</th>
          <td>2.100.000</td><td>2.305.036</td><td>585.036</td>
        </tr>
        <tr>
          <th scope="row" colspan="2">Düsseldorf</th>
          <td>400.000</td><td>510.685</td><td>118.685</td>
        </tr>
        <tr>
          <th scope="row" colspan="2">Buxtehude</th>
          <td>31.103</td><td>35.103</td><td>21.744</td>
        </tr>
      </tbody>
    </table>
    
    • die "Jahr" Zelle hat ebenfalls colspan=2, eine leeres th Element finde ich unnötig bis falsch
    • die Scope-Angaben sind hier essenziell, damit Assistenztechnik ansatzweise klarkommt.

    Ob das hinreichend ist, weiß ich auch nicht.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Janosch, hallo Rolf,

             Jahr |
      Stadt       |   2000   2010   2020
      ------------+-------------------------
          München |    
             Köln |
        Buxtehude |
      

      Bei einer Tabelle in dieser Form hat die erste Spalte die Überschrift "Jahr Stadt". Was liest da ein Screenreader vor?

      Ich würde folgende Form wählen:

                  |        Jahr
            Stadt | 2000 | 2010 | 2020
      ------------+-------------------------
          München |      |      |
             Köln |      |      | 
        Buxtehude |      |      |
      

      und Stadt und Jahr in th mit row- bzw. colspan legen, die Jahreszahlen und evtl. auch die Städtenamen dann in th.

      Gruß
      Jürgen

      1. Hallo JürgenB,

        Bei einer Tabelle in dieser Form hat die erste Spalte die Überschrift "Jahr Stadt".

        Nach meinem Verständnis nicht. Die Scopes sind unterschiedlich. Aber ich verstehe auch nicht allzuviel davon...
        Hast Du das im Screenreader überprüft? Ich kann's nicht.

        Ich dachte, durch die scope-Angaben – insbesondere der row-Scope für das "Jahr" Feld – kriegt der Screenreader das hin.

        Du möchtest also ein Extraheading mit colspan=3 über die Wertespalten legen? Mit anderen Worten: Du findest Janoschs Darstellungsidee eher nicht gut?

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          Bei einer Tabelle in dieser Form hat die erste Spalte die Überschrift "Jahr Stadt".

          Nach meinem Verständnis nicht. Die Scopes sind unterschiedlich. Aber ich verstehe auch nicht allzuviel davon...
          Hast Du das im Screenreader überprüft? Ich kann's nicht.

          ich habe es versucht, bin aber mit VoiceOver nicht klargekommen. Beim Seitevorlesen werden die Felder mit rowspan mehrmals vorgelesen, die Überschriften aber nicht als solche. Beim Navigieren in der Tabelle werden die Überschriften vorgelesen, aber teilweise falsch.

          Für mich wurden deine und meine Version beide verwirrend vorgelesen.

          Ich dachte, durch die scope-Angaben – insbesondere der row-Scope für das "Jahr" Feld – kriegt der Screenreader das hin.

          Ich habe es jetzt ohne scope nicht ausprobiert.

          Du möchtest also ein Extraheading mit colspan=3 über die Wertespalten legen? Mit anderen Worten: Du findest Janoschs Darstellungsidee eher nicht gut?

          Optisch ok, habe ich auf Papier auch so gemacht, aber im HTML finde ich es eher nicht gut.

          Gruß
          Jürgen

          1. Aloha ;)

            Für mich wurden deine und meine Version beide verwirrend vorgelesen.

            ...und meine wäre das dann vermutlich auch, denn ich habe ja genauso colspan und rowspan drin, und das wird deinem Test nach ja auch mit scope nicht geheilt. Sehr interessant!

            Optisch ok, habe ich auf Papier auch so gemacht, aber im HTML finde ich es eher nicht gut.

            Ja, verstehe ich.

            Grüße,

            RIDER

            --
            Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Albers-Zoller
            # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
        2. @@Rolf B

          Du möchtest also ein Extraheading mit colspan=3 über die Wertespalten legen? Mit anderen Worten: Du findest Janoschs Darstellungsidee eher nicht gut?

          Ähm. HTML ist für die Angabe der Struktur da. Die Darstellung ist Sache von CSS! Dass man das immer und immer wieder sagen muss! Aber dass man das auch dir sagen muss‽

          Das Markup von @JürgenB ist genau das, was ich auch vorgeschlagen hätte. Und wenn man Janoschs Darstellungsidee gut findet, dann make it so!

          Die th[colspan]-Zelle nicht an ihrer ursprünglichen Stelle platzieren, sondern dort, wo auch die th[rowspan]-Zelle ist. Ein Element relativ zu einem anderen positionieren, egal wo sich die im DOM befinden – na wenn das mal kein Fall für anchor positioning[1] ist!

          Sieht dann so aus: ☞ Codepen

          Die schräge Trennlinie hab ich mit Maske gemacht wegen der Umschaltung der Farbe bei light und dark mode.[2]

          Die Beschriftungen hab ich unten links bzw. oben rechts platziert. Bei längeren Beschriftungen (hallo, user-generated content!) dürfte es besser sein, die in Dreiecksform zu zwingen. shape-outside könnte behilflich sein.

          🖖 Live long and prosper

          --
          In our chants of “ICE out now”
          Our city’s heart and soul persists
          Through broken glass and bloody tears
          On the streets of Minneapolis

          — Bruce Springsteen, Streets of Minneapolis

          1. TIL about anchor positioning ↩︎

          2. TIL when to wear a mask ↩︎

          1. @@Gunnar Bittersmann

            Sieht dann so aus: ☞ Codepen

            Wenn man da genau hinsieht, stellt man fest, dass der obere Rahmen der „season“-Zelle etwas höher sitzt als der von „captain“ und „first officer“. (Und das sowohl in Firefox als auch in Safari als auch in Chromia.)

            Ein Hack wäre, border-top für thead th zu entfernen und stattdessen für table zu setzen. ☞ Fork

            🖖 Live long and prosper

            --
            In our chants of “ICE out now”
            Our city’s heart and soul persists
            Through broken glass and bloody tears
            On the streets of Minneapolis

            — Bruce Springsteen, Streets of Minneapolis
          2. Aloha ;)

            Die th[colspan]-Zelle nicht an ihrer ursprünglichen Stelle platzieren, sondern dort, wo auch die th[rowspan]-Zelle ist. Ein Element relativ zu einem anderen positionieren, egal wo sich die im DOM befinden – na wenn das mal kein Fall für anchor positioning[1] ist!

            Sieht dann so aus: ☞ Codepen

            Die schräge Trennlinie hab ich mit Maske gemacht wegen der Umschaltung der Farbe bei light und dark mode.[^2]

            Herzlichen Dank! Dieses Beispiel, der Fork dazu und die ergänzenden Hinweise sind extrem hilfreich. Sounds like the way to go!

            Grüße,

            RIDER

            P.S.: Für mein konkretes Problem werde ich vermutlich sogar bei der ursprünglich von Jürgen vorgeschlagenen Darstellung bleiben. Ich finde sie visuell ruhiger als die Geschichte mit dem Schrägstrich, und sie taugt für meine Zwecke fast besser, aber ich finde es super, dass die ursprüngliche Frage nun auch beantwortet ist, und, dass eine vergleichbare visuelle Darstellung zum Print-Bild möglich und mit überschaubarem Aufwand machbar ist!

            --
            Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Albers-Zoller
            # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[

            1. TIL about anchor positioning ↩︎

          3. Hallo Gunnar,

            Dass man das immer und immer wieder sagen muss! Aber dass man das auch dir sagen muss‽

            Es gibt Postings von Dir, da möchte man die Foren-Contenance in die Tonne treten und Dich gleich hinterher.

            Ja, Ankerpositionierung ist nicht in meinem aktiven Wortschatz angekommen. Ich baue nicht täglich drei Webseiten.

            Rolf

            --
            sumpsi - posui - obstruxi
      2. Aloha ;)

        Ich würde folgende Form wählen:

                    |        Jahr
              Stadt | 2000 | 2010 | 2020
        ------------+-------------------------
            München |      |      |
               Köln |      |      | 
          Buxtehude |      |      |
        

        und Stadt und Jahr in th mit row- bzw. colspan legen, die Jahreszahlen und evtl. auch die Städtenamen dann in th.

        Oh, die Variante gefällt mir tatsächlich gut - der nimmt die Essenz von dem, was @Felix Riesterer schon vorgeschlagen hatte, hat aber nicht den Nachteil mit Leerzellen und lässt die Tabelle so schmal wie möglich.

        Danke für den Denkanstoß, in diese Richtung hatte ich gar nicht gedacht!

        Das löst natürlich auch nicht die Frage, wie man so eine diagonal geteilte Überschriftszelle realisieren würde - aber wie bereits eingangs gesagt, vielleicht gibts darauf auch gar keine Antwort, und dieser Ansatz leistet jedenfalls das, was ich konkret brauche.

        Grüße,

        RIDER

        --
        Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Albers-Zoller
        # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
    2. Aloha ;)

      in einer Tabelle wie im Beispiel würde ich auf die "Eigenschaften" Überschriftenzelle verzichten.

      Ja, das Beispiel war auch nur ein Mockup. Mein echter Usecase ist näher an dem, was du schriebst (in dem Sinn, dass die Spaltenüberschriften nicht für sich stehen können, ich schrieb ja davon, dass das user generated content ist, der für sich allein nicht zwingend den Sinn der Tabelle erklärt).

      • die "Jahr" Zelle hat ebenfalls colspan=2, eine leeres th Element finde ich unnötig bis falsch

      Ja, fühle mich damit wie geschrieben auch unwohl - aber ohne die leeren Zellen bzw. in deinem Entwurf sieht das Ergebnis jetzt so aus:

      In diesem Screenshot steht nun "Jahr" oberhalb von "Stadt".

      Visuell ist das natürlich jetzt nicht das selbe und es gibt da eben diese visuelle Bevorzugung der Spaltenüberschriften vor den Zeilenüberschriften.

      Semantischer ist die Version wahrscheinlich als mein Ansatz, wegen der Scope-Angaben, visuell muss man dann eben noch tricksen (wobei ich da jetzt ganz spontan auch keinen erfolgsversprechenden Ansatz wüsste, CSS zur Tabellenformatierung ist ja immer so eine Sache für sich).

      • die Scope-Angaben sind hier essenziell, damit Assistenztechnik ansatzweise klarkommt.

      Herzlichen Dank für den Hinweis auf Scope, das Attribut hatte ich nicht auf dem Schirm (und das ist hier tatsächlich für die Semantik super hilfreich!). Tatsächlich ist das wahrscheinlich schon der wichtigste Aspekt für die Antwort auf meine ursprüngliche Frage, damit lassen sich dann Zweideutigkeiten in egal welcher Variante noch beheben.

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Albers-Zoller
      # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
  3. @@Camping_RIDER

    Tabellen sind in HTML ja so definiert, dass sie in drei Bereiche unterteilt sind - THEAD, TBODY und TFOOT.

    Viergeteilt (wie im Mittelalter). Du hast CAPTION unterschlagen.

    (COLGROUPs zähle ich hier mal nicht mit, da das zur Struktur der Tabelle, aber nicht zum Inhalt beiträgt.)

    🖖 Live long and prosper

    --
    In our chants of “ICE out now”
    Our city’s heart and soul persists
    Through broken glass and bloody tears
    On the streets of Minneapolis

    — Bruce Springsteen, Streets of Minneapolis
    1. Aloha ;)

      Tabellen sind in HTML ja so definiert, dass sie in drei Bereiche unterteilt sind - THEAD, TBODY und TFOOT.

      Viergeteilt (wie im Mittelalter). Du hast CAPTION unterschlagen.

      Stimmt - Danke! Ich hab CAPTION auch voll verdrängt (liegt mit daran, dass ich HTML-Tabellen quasi nie so einsetze, dass eine Caption so richtig Sinn ergibt, also z.B. im Kontext eines gesetzten Fließtexts).

      (COLGROUPs zähle ich hier mal nicht mit, da das zur Struktur der Tabelle, aber nicht zum Inhalt beiträgt.)

      Klar.

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Albers-Zoller
      # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[