这里的挑战在于,您想要表示的信息一方面是表格形式(它是一组具有相同标签属性的项目),另一方面是分层的(项目具有父项)。
不幸的是,在 HTML 中,没有针对表格行的嵌套分组机制:tbody
可用于分组行,但是嵌套它是非法的(除非在 td
中使用一个中间的 table
,这非常糟糕)。
那么您就有两个选择:
使用某种类型的嵌套列表来表示信息,并依赖 CSS 来使结果看起来像一个表。
将信息表示为表格,并依赖某些属性来表示其分层关系。
以下是如何实现这些选择的一些示例:
使用嵌套列表(天真的方法):
<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>
在这里,我们使用 定义列表 来描述两个事物:
例如,“项目名称”和“标识符”之间的标题/详细信息关系。
例如,“名称”单元和“名字”单元之间的父/子关系。
这种方法确实更加紧凑,但不幸的是,每个标题及其详细元素之间的具体关系充其量只是隐含的,如果没有额外的样式来以表格方式视觉组织信息,那么渲染后所代表的内容将更加不明显。
使用一个 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也能看起来合理”的经验法则。