web-dev-qa-db-de.com

Kombination einer Tabelle und einer hierarchischen Liste in HTML

Ich arbeite an der Neugestaltung eines alten Tool-Sets und schaue, wie ich einige Informationen sowohl präsentativ als auch semantisch besser darstellen kann.

Die Daten sind zwar in der Natur hierarchisch, verfügen jedoch über Eigenschaften, die für Benutzer leicht sichtbar sein müssen. Das gewünschte Layout ist ähnlich wie unten.

Seq     Item Name         Min  Max  - Anything under here isn't shown
 1      Identifier         1    1     (Required)
 2      Name               1    1
  2.1    First Name        1    1
  2.2    Middle Name       -    -     (Optional but unlimted)
  2.3    Last Name         1    1
 3      Age                -    1     (Optional)

Im Moment ist dies eine ganze Tabelle, und das Eingreifen für die Sequenznummer (Seq) wird durch das Einfügen zusätzlicher Tabellenzellen erreicht, um die Art nach rechts zu verschieben.

Meine Herausforderung besteht darin, herauszufinden, wie diese Informationen effektiv angezeigt werden können.

Zuallererst sind dies tabellarische Daten? Ich würde nein sagen, da die Hierarchie wichtig ist und die "Spalten" lediglich Attribute des Elements in jeder "Zeile" sind.

Wenn es nicht tabellarisch ist, was ist es und wie würde das getan? Ich würde persönlich behaupten, dass dies eine Menge verschachtelter UL-Listen ist - die Sequenznummer ist optional und nicht immer eine Nummer. Wenn es sich um eine Liste von Listen handelt, werden die Unterlisten korrekt eingerückt, aber wie können die kurzen Attribute am besten dargestellt werden?

Wenn es sich um eine Tabelle handelt, wie kann man die semantische Existenz der Hierarchie in der Tabelle am besten darstellen?

19
user764357

Die Herausforderung hierbei besteht darin, dass die Informationen, die Sie darstellen möchten, in einer Hinsicht tabellarisch sind (es handelt sich um eine Gruppe von Elementen mit identisch beschrifteten Attributen) und in einer anderen Hierarchie (Elemente haben übergeordnete Elemente). 

Leider gibt es keinen verschachtelten Gruppierungsmechanismus für Tabellenzeilen in HTML: tbody kann zum Gruppieren von Zeilen verwendet werden, aber das Verschachteln ist illegal (außer bei einer Zwischenvariable table innerhalb einer td, die ziemlich schrecklich ist).

Damit haben Sie zwei Möglichkeiten:

  1. Repräsentieren Sie die Informationen mit verschachtelten Listen, und verwenden Sie CSS, damit das Ergebnis wie eine Tabelle aussieht.

  2. Stellen Sie die Informationen als Tabelle dar und verlassen Sie sich auf Attribute irgendeiner Art, um ihre hierarchischen Beziehungen darzustellen.

Hier einige Beispiele, wie Sie diese Entscheidungen implementieren können:

Verwenden verschachtelter Listen (naiver Ansatz):

<ul>
  <li>
    <dl>
      <dt>Seq</dt> <dd>1</dd>
      <dt>Item Name</dt> <dd>Identifier</dd>
      <dt>Min</dt> <dd>1</dd>
      <dt>Max</dt> <dd>1</dd>
    </dl>
  </li>
  <li>
    <dl>
      <dt>Seq</dt> <dd>2</dd>
      <dt>Item Name</dt> <dd>Name</dd>
      <dt>Min</dt> <dd>1</dd>
      <dt>Max</dt> <dd>1</dd>
    </dl>
    <ul>
      <li>
        <dl>
          <dt>Seq</dt> <dd>2.1</dd>
          <dt>Item Name</dt> <dd>First Name</dd>
          <dt>Min</dt> <dd>1</dd>
          <dt>Max</dt> <dd>1</dd>
        </dl>
      </li>
      <li>
        <dl>
          <dt>Seq</dt> <dd>2.2</dd>
          <dt>Item Name</dt> <dd>Middle Name</dd>
          <dt>Min</dt> <dd>-</dd>
          <dt>Max</dt> <dd>-</dd>
        </dl>
      </li>
      <li>
        <dl>
          <dt>Seq</dt> <dd>2.3</dd>
          <dt>Item Name</dt> <dd>Last Name</dd>
          <dt>Min</dt> <dd>1</dd>
          <dt>Max</dt> <dd>1</dd>
        </dl>
      </li>
    </ul>
  </li>
  <li>
    <dl>
      <dt>Seq</dt> <dd>3</dd>
      <dt>Item Name</dt> <dd>Age</dd>
      <dt>Min</dt> <dd>-</dd>
      <dt>Max</dt> <dd>1</dd>
    </dl>
  </li>
<ul>

Dies behandelt den hierarchischen Aspekt der Informationen, aber am Ende wiederholen Sie sich viel und müssen einige Bereiche im CSS durchgehen, um das Ergebnis in Tabellenform anzuzeigen. Es ist wahrscheinlich mit vernünftiger Verwendung von :first-child möglich, aber das Endergebnis ist, dass Sie alles unternommen haben, um etwas hervorzuheben, das Sie als Tabelle auf eine nicht tabellarische Weise präsentieren möchten und als Ergebnis mehr Arbeit erhalten es wieder in form bringen.

Es macht auch die wirklich tabellarische Natur der Beziehungen zwischen den Elementen implizit und nicht explizit im Markup. Ohne Bezug auf die gerenderte Ausgabe ist es nicht klar, dass diese Elemente immer die gleiche Anzahl und Art von Attributen haben.

Verwenden verschachtelter Listen ("cleverer" Ansatz):

<dl>
  <dt>
    <ul> <li>Seq</li> <li>Item Name</li> <li>Min</li> <li>Max</li> </ul>
  </dt>
  <dd>
    <ul> <li>1</li> <li>Identifier</li> <li>1</li> <li>1</li> </ul>
  </dd>
  <dd>
    <dl>
      <dt>
        <ul> <li>2</li> <li>Name</li> <li>1</li> <li>1</li> </ul>
      </dt>
      <dd>
        <ul> <li>2.1</li> <li>First Name</li> <li>1</li> <li>1</li> </ul>
      </dd>
      <dd>
        <ul> <li>2.2</li> <li>Middle Name</li> <li>-</li> <li>-</li> </ul>
      </dd>
      <dd>
        <ul> <li>2.3</li> <li>Last Name</li> <li>1</li> <li>1</li> </ul>
      </dd>
    </dl>
  </dd>
  <dd>
    <ul> <li>3</li> <li>Age</li> <li>-</li> <li>1</li> </ul>
  </dd>
</dl>

Hier verwenden wir Beschreibungslisten , um zwei Dinge zu beschreiben:

  1. Die Kopf/Detail-Beziehung zwischen z. 'Artikelname' und 'Kennung' usw.

  2. Die Eltern-Kind-Beziehung zwischen z. die 'Name' Einheit und die 'Vorname' Einheit.

Es ist sicherlich kompakter, aber leider ist die spezifische Beziehung zwischen den einzelnen Kopfzeilen und ihren Detailelementen im besten Fall implizit. Ohne zusätzliches Styling zum visuellen Organisieren der Informationen in Tabellenform ist es noch weniger offensichtlich, wenn sie gerendert wird, was tatsächlich dargestellt wird.

table verwenden:

<table>
  <thead>
    <tr>
      <th>Seq</th> <th>Item Name</th> <th>Min</th> <th>Max</th>
    </tr>
  </thead>
  <tbody>
    <tr id=100>
      <td>1</th> <th>Identifier</th> <td>1</td> <td>1</td>
    </tr>
    <tr id=200>
      <th>2</th> <th>Name</th> <td>1</td> <td>1</td>
    </tr>
    <tr id=210 data-parent=200 class=level-1>
      <th>2.1</th> <th>First Name</th> <td>1</td> <td>1</td>
    </tr>
    <tr id=220 data-parent=200 class=level-1>
      <th>2.2</th> <th>Middle Name</th> <td>-</td> <td>-</td>
    </tr>
    <tr id=230 data-parent=200 class=level-1>
      <th>2.3</th> <th>Last Name</th> <td>1</td> <td>1</td>
    </tr>
    <tr id=300>
      <th>3</th> <th>Age</th> <td>-</td> <td>1</td>
    </tr>
  </tbody>
</table>

Hier werden die Parent/Child-Beziehungen explizit durch das Attribut data-parent beschrieben (auf das bei Bedarf über Javascript zugegriffen werden kann), und ein class=level-{n}-Attribut stellt einen Hook bereit, der vom CSS verwendet werden kann:

.level-1 > th {
  padding-left: 1em;
}

Letztendlich geht es um persönliche Vorlieben und Bequemlichkeit, aber ich denke, der <table>-Ansatz ist einfach deshalb einfach besser, weil er das zufriedenstellt "sieht es ohne CSS vernünftig aus?" Faustregel viel besser als die oben genannten Ansätze verschachtelter Listen.

20
Zero Piraeus

Ich würde es präsentieren, indem Sie eine Tabelle verwenden und benutzerdefinierte Datenattribute zu den td-Tags hinzufügen:

<table id="myTable" class="table">
    <tr>
        <td data-indent="0">1</td>
        <td data-indent="0">Test</td>
        <td data-indent="0">Test 1</td>
    </tr>
    <tr>
        <td data-indent="1">1.1</td>
        <td data-indent="1">Another</td>
        <td data-indent="0">Test 1.1</td>
    </tr>
    <tr>
        <td data-indent="2">1.1.1</td>
        <td data-indent="3">Another</td>
        <td data-indent="0">Test 1.1.1</td>
    </tr>
        <tr>
        <td data-indent="2">1.1.2</td>
        <td data-indent="3">Another one</td>
        <td data-indent="0">Another test 1.1.2</td>
    </tr>
    <tr>
        <td data-indent="0">2</td>
        <td data-indent="0">Test</td>
        <td data-indent="0">Test 2</td>
    </tr>
</table>

Legen Sie dann mit Hilfe von jQuery die Auffüllung jedes Zellenwerts in Ihrer Tabelle fest:

$("td")
    .css("padding-left", function (index) {
    return 10 * parseInt($(this).data("indent")) + "px";
});

Sehen Sie, wie es auf jsFiddle funktioniert.

7
Alex Filipovici

Ich denke, es gibt zwei sinnvolle Möglichkeiten, dies in HTML darzustellen:

  • verwenden Sie ein table und machen Sie die Beziehung/Hierarchie mit natürlicher Sprache explizit
  • verwenden Sie Sectioning-Elemente (bzw. Überschriften, wenn Sie HTML 4.01 verwenden)

table mit einer Spalte zur Erläuterung der Hierarchie

Wenn für die Definition dieser Beziehung kein Markup vorhanden ist, sollten Sie Text verwenden. Wenn die visuelle Darstellung eindeutig ist, können Sie diesen Text visuell ausblenden, sodass nur Benutzer von Bildschirmleseprogrammen/Textbrowsern darauf zugreifen können.

In Ihrem Fall könnten Sie eine Spalte hinzufügen, die die Beziehung von Zeilen erläutert, die "Unterelemente" sind:

<table>

  <tr>
    <th>Seq</th> 
    <th>Relation</th> <!-- or some clever better label -->
    <th>Item Name</th>
    <th>Min</th>
    <th>Max</th>
  </tr>

  <!-- … -->

  <tr id="2">
    <td>2</td>
    <td></td> <!-- "parent", "root", "container", empty -- whatever makes sense for your case -->
    <td>Name</td>
    <td>1</td>
    <td>1</td>
  </tr>

  <tr id="2.1">
    <td>2.1</td>
    <td>child of <a href="#2">Name</a></td>
    <td>First Name</td>
    <td>1</td>
    <td>1</td>
  </tr>

</table>

Jede Zeile könnte ein id (mit dem Wert Seq oder Item Name) erhalten, so dass diese Zeile verknüpft werden kann {beachte, dass id Werte, die mit einer Ziffer beginnen, in HTML 4.01 nicht zulässig sind; Sie könnten dort etwas wie id="seq-2.1"} verwenden. Wenn ein Element einem anderen Element untergeordnet ist, können Sie eine Verknüpfung zur Zeile des übergeordneten Elements herstellen.

Auf diese Weise stellen Sie für den Menschen klar, dass Maschinen immer noch erkennen, dass diese Zeilen verbunden sind, obwohl die spezifische Semantik dieser Beziehung nicht maschinenlesbar ist. Sie können hier einen Verknüpfungstyp (rel value) verwenden, um die Bedeutung der Beziehung explizit zu verdeutlichen. In HTML 4.01 könnten Sie selbst einen Wert erstellen, in HTML5 müssten Sie zuerst registered angeben.

elemente/Überschriften aufteilen

Anstatt ein table zu verwenden, können Sie auch die HTML-Gliederung verwenden. {Das folgende Beispiel verwendet HTML5-Elemente . Wenn Sie HTML 4.01 verwenden, ersetzen Sie einfach die Schnittelemente durch div (oder gar kein Element) und verwenden Sie nur Überschriften.}

Jeder Abschnitt (eingeleitet durch eine Überschrift) repräsentiert einen Gegenstand. Die Gliederung der Überschriften (bzw. Verschachtelung der Schnittelemente) repräsentiert die Hierarchie Ihrer Elemente.

Hier ist ein Beispiel, um die gesamte Struktur zu sehen:

 <article>

   <h1><!-- heading for the whole data --></h1>

   <section class="item" id="1">
     <h2>Identifier</h2>
   </section>

   <section class="item" id="2">
     <h2>Name</h2>

     <section class="item" id="2.1">
       <h3>First Name</h3>
     </section>

     <section class="item" id="2.2">
       <h3>Middle Name</h3>
     </section>

     <section class="item" id="2.3">
       <h3>Last Name</h3>
     </section>

   </section>

   <section class="item" id="3">
     <h2>Age</h2>
   </section>

 </article>

Jedes section kann ein dl für die Eigenschaften enthalten:

<section class="item" id="3">
  <h2>Age</h2>

  <dl>
    <dt>Min</dt>
    <dd>1</dd>
    <dt>Max</dt>
    <dd>1</dd>
  </dl>

</section>

Abhängig von der tatsächlichen Bedeutung Ihres Inhalts können Sie das code -Element für die Elementnamen verwenden (z. B. wenn es Elemente einer Auszeichnungssprache beschreibt) und/oder das - dfn Element , wenn der folgende Inhalt eine Definition dieses Elements ist.

3
unor

Mein Vorschlag wäre, verschachtelte geordnete Listen zu verwenden, um Ihre hierarchische Struktur beizubehalten, und dann Beschreibungslisten, um die "Spalten" für jede Zeile darzustellen.

Die Beschreibungsliste für die erste Zeile könnte beispielsweise wie folgt aussehen:

<dl>
  <dt>Item Name</dt>
  <dd>Identifier</dd>
  <dt>Min</dt>
  <dd>1</dd>
  <dt>Max</dt>
  <dd>1</dd>
  <dt>Notes</dt>
  <dd>(Required)</dd>
</dl>

Sie müssen CSS verwenden, um die Beschreibungsbegriffe auszublenden (da sie nicht in jeder Zeile angezeigt werden sollen) und um das Layout an eine Tabelle anzupassen.

Der Nachteil dieses Formats besteht darin, dass Sie die Spaltenüberschriften in jeder einzelnen Zeile duplizieren. Aber semantisch ist das meiner Meinung nach am sinnvollsten und sollte den Inhalt auch für einen Screenreader sinnvoller machen.

Ich habe einen ersten Versuch mit CSS gemacht, damit Sie eine Vorstellung davon bekommen, wie es funktionieren könnte. Das ist wahrscheinlich nicht sehr gut gemacht, aber zumindest gibt es etwas, mit dem man anfangen kann.

CodePen Link

2

UPDATE: Ich habe die Verwendung von IDs und "Header" -Attribut hinzugefügt, um die Hierarchie irgendwie semantisch zu markieren.

Das sind definitiv tabellarische Daten (Sie sollten die Definition von "Liste" wirklich drücken, um eine UL oder DL hier zu rechtfertigen!).

Ich denke, ein guter Ansatz wäre die Verwendung verschiedener Tbodys, um diese zusammengehörigen Zeilen zu gruppieren (so etwas wurde hier verwendet. Http://www.w3.org/TR/2012/WD-html5-20120329/the-table- element.html # the-table-element siehe "Tabelle, mit der ein Sudoku-Puzzle markiert wird")

<table>
  <thead>
    <tr>
      <th id="seq">Seq</th>
      <th>Item Name</th>
      <th>Min</th>
      <th>Max</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th id="s1" headers="seq">1</th>
      <td>Identifier</td>
      <td>1</td>
      <td>1</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <th id="s2" headers="seq">2</th>
      <td>Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr class="sub">
      <th id="s2_1" headers="seq s2">2.1</th>
      <td>First Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr class="sub">
      <th id="s2_2" headers="seq s2">2.2</th>
      <td>Middle Name</td>
      <td>-</td>
      <td>-</td>
    </tr>
    <tr class="sub">
      <th id="s2_3" headers="seq s2">2.3</th>
      <td>Last Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr class="sub sub">
      <th id="s2_3_1" headers="seq s2 s2_3">2.3.1</th>
      <td>Last Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr class="sub sub">
      <th id="s2_3_2" headers="seq s2 s2_3">2.3.2</th>
      <td>Last Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <th id="s3" headers="seq">3</th>
      <td>Age</td>
      <td>-</td>
      <td>1</td>
    </tr>
  </tbody>
</table>

Dann könnte man so etwas verwenden:

table { border-collapse: collapse; }
tbody { border-bottom:1px solid #000; }
tbody .sub td { padding-left: 10px; }

Ich glaube, Sie können nur mit tbody Zeilen zusammenfassen und einzelne Zeilen in Ruhe lassen 

<tr>
  <td>1</td>
  <td>Identifier</td>
  <td>1</td>
  <td>1</td>
</tr>
<tbody>
  <tr>
    <td>2</td>
    <td>Name</td>
    <td>1</td>
    <td>1</td>
  </tr>
  <tr class="sub">
    <td>2.1</td>
    <td>First Name</td>
    <td>1</td>
    <td>1</td>
  </tr>
  ...
</tbody>
<tr>
  <td>3</td>
  <td>Age</td>
  <td>-</td>
  <td>1</td>
</tr>
2
Coluccini

Ich denke, du solltest einen Tisch benutzen. Die Hierarchie ist zwar wichtiger, kann aber auch durch manuelles Schreiben der ersten Spalte angezeigt werden. Die Attribute min, max und item name konnten jedoch nicht so einfach in einer Liste wie in einer Tabelle angezeigt werden. Meine Meinung: Verwenden Sie eine Tabelle und geben Sie die Spalte für die Reihenfolge manuell ein!

2
Lars Ebert

Warum nicht beide? Ein Baumraster ist eine gute Möglichkeit, tabellarische Daten darzustellen, die auch einer Hierarchie entsprechen.

Dies ist ein solches Beispiel .

Da ich Extjs jedoch für zwei sehr große Projekte verwendet habe, empfehle ich persönlich, sich davon fernzuhalten, wenn Sie eine große Anwendung erstellen. Es mag zwar für ein einmaliges Netz gut sein, aber ich persönlich finde, dass es schlecht implementiert ist und mit zunehmender Größe des Projekts umständlicher werden kann. Es ist jedoch sehr reich an Funktionen, daher können Sie im -Beispielfenster weitere Ideen zu Rastern (Tabellen) finden, die Ihnen helfen könnten.

Denken Sie daran, dass Sie sich immer fragen sollten: "Welche Fragen versuchen meine Benutzer zu beantworten?" Fragen Sie sich dann: "Welche grafischen Geräte bieten den klarsten und einfachsten Weg, um diese Frage zu beantworten?"

Ein Buch, das mir bei diesen Fragen wirklich geholfen hat, war das Dashboard-Design-Buch . Obwohl Sie möglicherweise kein Dashboard erstellen, verfügt es über viele UX-Techniken und -Theorien, die es mir bei der Auswahl des entsprechenden UI-Elements (in Bezug auf Daten) erleichtert haben.

Hoffentlich hilft das...

0
Homer6