web-dev-qa-db-ja.com

HTMLでテーブルと階層リストを組み合わせる

私はレガシーツールセットの再設計に取り組んでおり、表示と意味の両方でいくつかの情報をより適切に表示する方法を検討しています。

データは本質的に階層構造になっていますが、ユーザーにすぐに見えるようにする必要があるプロパティがあります。望ましいレイアウトは以下のようになります。

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)

現時点ではこれは1つのテーブル全体であり、シーケンス(Seq)番号のインデントは、追加のテーブルセルを挿入してすべてを右側にバンプすることによって実現されます。

私が抱えている課題は、この情報を効果的に表示する方法を見つけることです。

まず、この表形式のデータですか?階層が重要であり、「列」は各「行」の項目の属性にすぎないため、「いいえ」と言います。

それが表形式でない場合、それは何であり、どのように実行されますか?これはネストされたULリストのセットであると個人的に主張します-シーケンス番号はオプションであり、常にではありません数。リストのセットの場合、サブリストは正しくインデントされますが、短い属性を提示する最良の方法は何ですか?

それがテーブルの場合、テーブル内の階層のセマンティックの存在を提示する最良の方法は何ですか?

21
user764357

ここでの課題は、表現する情報が、ある面では表形式であり(同じラベルの属性を持つアイテムのセットです)、別の階層では(アイテムには親がある)ことです。

残念ながら、HTMLのテーブル行にはネストされたグループ化メカニズムはありません: tbody を使用して行をグループ化できますが、ネストは無効です(中間のtableを除く) td、これはかなり恐ろしいことです)。

そのため、次の2つの選択肢があります。

  1. 何らかのネストされたリストで情報を表現し、CSSを使用して結果をテーブルのように見せます。

  2. 情報をテーブルとして表現し、ある種の属性に依存して、その階層関係を表現します。

これらの選択を実装する方法の例をいくつか示します。

ネストされたリストの使用(ナイーブアプローチ):

<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>

これは情報の階層的な側面を処理しますが、最終的には何度も繰り返すことになり、結果を表形式で表示するためにCSSのいくつかのフープをジャンプする必要があります。 :first-childを適切に使用することで実行できる可能性がありますが、最終的には、表ではない方法でテーブルとして提示したいものをマークアップする方法がなくなり、その結果、自分でそれを形に戻すより多くの仕事を与えてください。

また、アイテム間の関係の真の表形式の性質をマークアップで明示的ではなく暗黙的にします-レンダリングされた出力を参照せずに、これらのアイテムが常に同じ数と種類の属性を持つことは明らかではありません。

ネストされたリストの使用(「賢い」アプローチ):

<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>

ここでは、 説明リスト を使用して2つのことを説明しています。

  1. ヘッダー/詳細関係。 「アイテム名」、「識別子」など.

  2. 親/子関係。 「名前」ユニットと「名」ユニット。

確かにコンパクトですが、残念ながら各ヘッダーとその詳細要素間の特定の関係はせいぜい暗黙的なものであり、情報を表形式で視覚的に整理するための追加のスタイリングがないと、実際に何が表現されているかをレンダリングしたときに、それがさらにわかりにくくなります。

tableを使用する

<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>

ここで、親子関係は data-parent 属性(必要に応じてJavaScriptを介してアクセスできます)によって明示的に記述されており、class=level-{n}属性は、 CSSで使用:

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

結局のところ、それは個人的な好みと利便性の問題ですが、<table>アプローチは、「CSSなしで合理的に見えますか?」経験則は、上記のネストされたリストのいずれのアプローチよりもはるかに優れています。

22
Zero Piraeus

テーブルを使用し、tdタグに カスタムデータ属性 を追加して、それを表示します。

<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>

次に、jQueryを使用して、テーブルの各セル値のパディングを設定します。

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

jsFiddle で動作することを確認してください。

8
Alex Filipovici

これをHTMLで表現するには、2つの賢明な方法があると思います。

  • tableを使用し、自然言語で関係/階層を明示的にする
  • セクション化要素を使用する(HTML 4.01を使用する場合は、見出し)

tableには、階層を説明する列があります

この関係を定義するためのマークアップがない場合は、テキストを使用する必要があります。視覚的表現が明確な場合は、このテキストを視覚的に非表示にして、スクリーンリーダー/テキストブラウザーのユーザーのみがアクセスできるようにすることができます。

あなたのケースでは、「サブアイテム」である行の関係を説明する列を追加できます:

<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>

各行はid(Seqまたはアイテム名の値)を取得できるため、この行をリンクできます{数字で始まるid値はHTML 4.01では許可されていません。 id="seq-2.1"のようなものを使用できます}。アイテムが別のアイテムの子である場合、親アイテムの行にリンクできます。

このようにして、人間に対して明確にします。この関係の特定のセマンティクスは機械可読ではありませんが、マシンはこれらの行が接続されていることを確認します。関係の意味を明確にするために、ここでリンクタイプ(rel値)を使用できます。 HTML 4.01では自分で値を作成できますが、HTML5では最初に registered にする必要があります。

セクション要素/見出し

tableを使用する代わりに、HTMLのアウトラインを利用できます。 {次の例では HTML5のセクション化要素 を使用しています。 HTML 4.01を使用している場合は、セクション要素をdivに置き換えるか、要素をまったく追加せず、見出しのみを使用してください。}

各セクション(見出しで紹介)はアイテムを表します。見出しのアウトライン(セクション要素のネスト)は、アイテムの階層を表します。

全体の構造を確認する例を次に示します。

 <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>

sectionには、プロパティのdlを含めることができます。

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

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

</section>

コンテンツの実際の意味に応じて、アイテム名に code element を使用できます(たとえば、マークアップ言語の要素を記述する場合など)、および/または dfn element (以下のコンテンツがそのアイテムの定義である場合)。

3
unor

私の提案は、階層構造を維持するためにネストされた順序付きリストを使用し、次に各行の「列」を表す説明リストを使用することです。

たとえば、最初の行の説明リストは次のようになります。

<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>

(すべての行に表示されないようにするために)CSSを使用して説明用語を非表示にし、レイアウトを調整して表のようにする必要があります。

この形式の欠点は、すべての行の列見出しを複製することです。しかし、意味的には、これが最も理にかなっていると思います。また、コンテンツがスクリーンリーダーにとってより意味のあるものになるはずです。

CSSで最初に試みたのは、CSSがどのように機能するかを理解できるようにするためです。これはおそらくあまりよくできていませんが、少なくとも何かを始めるのに役立ちます。

CodePenリンク

2

更新:どういうわけか、意味的に階層をマークアップするために、IDと「ヘッダー」属性の使用を追加しました。

これは間違いなく表形式のデータです(「リスト」の定義を実際にプッシュして、ULまたはDL here!)を使用して正当化する必要があります)。

私は良いアプローチはそれらの関連する行を一緒にグループ化するために異なるtbodyを使用することだと思います(ここで使用したこのようなもの http://www.w3.org/TR/2012/WD-html5-20120329/the-table -element.html#the-table-element 「数独パズルをマークアップするために使用されるテーブル」を参照)

<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>

次に、次のようなものを使用できます。

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

実際のところ、tbodyを使用して行をグループ化し、単一の行をそのままにすることができると思います

<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

テーブルを使うといいと思います。確かに、階層はより重要ですが、最初の列を手動で書き留めて表示することもできます。しかし、属性min、max、およびitem nameは、テーブルのようにリストに簡単に表示できませんでした。私の意見:テーブルを使用し、seq列を手動で指定してください!

2
Lars Ebert

なぜ両方ではない?ツリーグリッドは、階層にも準拠する表形式のデータを表すのに適した方法です。

これは そのような例の1つ です。

ただし、Extjsを2つの非常に大規模なプロジェクトで使用した場合、私自身は、大規模なアプリケーションを作成する場合は、Extjsを使用しないことをお勧めします。 1回限りのグリッドでは問題ないかもしれませんが、個人的には実装が不十分であり、プロジェクトのサイズが大きくなるにつれて面倒になる可能性があります。ただし、非常に機能が豊富であるため、 examples panel を使用すると、グリッド(テーブル)についてさらに役立つアイデアが得られる場合があります。

「ユーザーはどのような質問に答えようとしているのですか?」と常に自問する必要があることに注意してください。次に、「どのグラフィックデバイスがその質問に答えるための最も明確で最も単純な道を提供するのですか?」と自問します。

これらの質問で私を本当に助けた1つの本は ダッシュボードの設計書 でした。ダッシュボードを作成していない場合でも、適切なUI要素(データに関して)を選択するときに私を容易にするUXの手法と理論がたくさんあります。

お役に立てば幸い...

0
Homer6