在HTML中组合表和分层列表

20 html css html-table wcag wcag2.0

我正在努力重新设计一个遗留工具集,我正在研究如何在表现和语义上更好地显示一些信息.

数据本质上是分层的,但具有需要用户容易看到的属性.所需的布局类似于下面.

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)
Run Code Online (Sandbox Code Playgroud)

目前,这是一个完整的表,并且Seq通过插入额外的表格单元来实现对顺序()数字的交叉处理.

我面临的挑战是如何有效地显示这些信息.

首先是这个表格数据?我会说不,因为层次结构很重要,而'列'只是每个'行'中项目的属性.

如果它不是表格,它是什么以及如何做?我个人认为这是一组嵌套UL列表 - 序列号是可选的,并不总是一个数字.如果它是一组列表,那将正确缩进子列表,但是呈现短属性的最佳方式是什么?

如果它是一个表,那么在表中呈现层次结构的语义存在的最佳方法是什么?

Zer*_*eus 21

这里的挑战是,您想要表示的信息在一个方面是表格式的(它是一组具有相同标记属性的项目),而在另一个层次结构中(项目具有父项).

不幸的是,HTML中的表行没有嵌套的分组机制:tbody可以用来对行进行分组,但嵌套它是非法的(除了table在a中有一个中间td,这非常可怕).

这有两个选择:

  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>
Run Code Online (Sandbox Code Playgroud)

这会处理信息的层次结构方面,但是你最终会重复自己,并且必须跳过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>
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用描述列表来描述两件事:

  1. 例如'Item Name'和'Identifier'之间的标题/细节关系等.

  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>
Run Code Online (Sandbox Code Playgroud)

这里,父/子关系由data-parent属性显式描述(如果需要可以通过javascript访问),并且class=level-{n}属性提供了CSS可以使用的钩子:

.level-1 > th {
  padding-left: 1em;
}
Run Code Online (Sandbox Code Playgroud)

最终这是个人偏好和方便的问题,但我认为这种<table>方法更好,因为它满足了"没有CSS它看起来合理吗?" 经验法则比上面的嵌套列表方法要好得多.

  • @MattSach HTML5中的[不再是真的](http://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.id). (8认同)

Ale*_*ici 7

我会通过使用表并向标记添加自定义数据属性来呈现它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>
Run Code Online (Sandbox Code Playgroud)

然后,在jQuery的帮助下,在表中设置每个单元格值的填充:

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

看到它在jsFiddle上工作.

  • 为什么不通过css进行填充?您可以将单元格匹配到填充槽 td:first-child[data-indent="1"] 或 td:first-child[data-indent="2"] 并应用所需的填充。 (2认同)
  • 但是我能看到的,问题是你失去了层次结构的语义. (2认同)

Lar*_*ert 2

我认为你应该使用一张桌子。诚然,层次结构更重要,但也可以通过手动写下第一列来显示。但属性 min、max 和项目名称无法像在表格中那样轻松地在列表中显示。我的意见:使用表格并手动提供 seq 列!