嵌套表格的语义和表头

4

我有一个表格,其中的元素可以具有具有相同属性的子元素,例如:

ITEM    ATTRIBUTE 1    ATTRIBUTE 2
item    value          value
 sub    value          value
 sub    value          value
item    value          value

我已经创建了这样的标记:

<table>
    <thead>
        <tr>
            <th>ITEM</th>
            <th>ATTRIBUTE 1</th>
            <th>ATTRIBUTE 2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>item</td>
            <td>value</td>
            <td>value</td>
        </tr>
        <tr>
            <td colspan=3>
                <table>
                    <tbody>
                        <tr>
                            <td>sub</td>
                            <td>value</td>
                            <td>value</td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
        <tr>
            <td>item</td>
            <td>value</td>
            <td>value</td>
        </tr>
    </tbody>
</table>

我的问题如下:

  • 这是最好的语义化解决方案吗?
  • 还有其他更合适的方法吗?如果有,哪种方法是推荐的?
  • 表头是负责两个表格的还是我需要创建一个新的表头(也许使用嵌套表格并设置visibility: hidden)?

是的,终于获得了75个声望值,可以开始所谓的悬赏了。哦,我失去了在任何地方发表评论的可能性。嗯。 - lampshade
我会避免嵌套表格,因为它会在单元格中插入一个新表格,这不是你想要的。如果你只有一层关系,为什么不保持表格平面,并使用CSS来识别项目与子项目。<tr class="item">...</tr><tr class="subitem">...</tr> - kalhartt
@kalhartt 是的,但这并不反映子项的语义含义,是吗?我也考虑过这个问题,但这只会产生视觉上的差异。 - lampshade
如果您适当地为类设置样式,它将在视觉上得到反映,并且使用任何DOM操作器解析关系也很容易。您希望如何反映其含义? - kalhartt
@kalhartt 我的意思是,它传输子项是父项的子级或更多的子集,并且它们不在同一“级别”。 - lampshade
4个回答

4

这是最好的语义化解决方案吗?

不是的。虽然将元素 A 嵌套在另一个元素 B 中可以用于表示 A 是 B 的子元素,但这并不是你在这里要做的:你将表格嵌套在完全不同的行中,因此在 A 和 B 之间没有父子关系的暗示。

通过创建一个跨越表格中所有列的单元格,然后在其中构建另一个具有相同列数的表格,你实际上还在说“这些是某些与外部表格中的列无关的其他列”。

您可以通过为上面示例中的单元格添加边框来查看列之间隐含的(缺乏)关系:

Rendered table

显然,您可以使用 CSS 来修复它,但未经样式化的一段 HTML 的呈现通常是其语义的良好指南。

是否有更适合的方法?如果有,哪种方法被推荐?

在 HTML 中,没有标准的方法来表示行之间的层次关系。不过,从我对一个类似问题给出的答案中借鉴,您可以使用额外的类、id 和 data- 属性来实现它:

<table>
    <thead>
        <tr>
            <th>ITEM</th>
            <th>ATTRIBUTE 1</th>
            <th>ATTRIBUTE 2</th>
        </tr>
    </thead>
    <tbody>
        <tr id=100>
            <td>item</td>
            <td>value</td>
            <td>value</td>
        </tr>
        <tr id=110 data-parent=100 class=level-1>
            <td>sub</td>
            <td>value</td>
            <td>value</td>
        </tr>
        <tr id=200>
            <td>item</td>
            <td>value</td>
            <td>value</td>
        </tr>
    </tbody>
</table>

在未经样式修饰的呈现中,父子关系是不可见的(在我看来没有其他方法可以做到这一点,除非添加额外的内容),但有足够的钩子可以添加所需的CSS:

.level-1 > td:first-child {
    padding-left: 1em;
}

...导致了这个:

渲染后的表格

通过一些javascript,你也可以使用iddata-parent属性来设置当悬停在一个行上时,其父行被突出显示的效果。

表头负责两个表格还是我需要创建一个新的表头?

在您提出的解决方案中,创建一个跨越所有列的单元格,然后在其中构建另一个表格意味着表头单元格与“子级”行的单元格之间没有隐含的关系。显然,我上面提出的解决方案没有这个问题。


你在开头的两段描述了我的担忧,而我的(间接)问题似乎已经被回答了 - 不幸的是:“HTML中没有标准的方法来表示表格行之间的层次关系。” - lampshade
好的解决方案,但是如果我想使用模板来渲染表格,这个解决方案会不会出现问题? - me_digvijay
@DigvijayYadav 怎么做到呢?如果有超过两个级别,一行需要知道它在层级中的深度,但是如果必要的话(如果只有两个级别,只需知道有一个父级即可),提供数据的任何内容都可以轻松跟踪。在任何合理的模板语言中,其余部分都是微不足道的。 - Zero Piraeus

1
这是W3C的建议:
在当前情况下,想要确保对于表格中标题不在第一行/列的辅助技术的一致支持的人们可能希望使用复杂表格的技巧H43:使用id和headers属性将数据单元格与标题单元格关联在数据表格中。对于标题在第一列或第一行的简单表格,我们建议使用th和td元素。
你可以查看这篇文章:构建语义化HTML表格的最佳方法 希望这能帮助你找到答案。

0

我认为将子元素放在单独的表格中是错误的做法。嵌套表格不像嵌套列表,它们没有相同的语义层次结构。如果所有内容都列出了相同的信息,则似乎应该将所有内容放在同一个表格中。

例如,如果您的表格具有标题

REGION    POPULATION     AREA

那么你可以有item1 = Earth,item2 = France,item3 = Paris...,如果France是Earth的子项或者Paris是France的子项并不重要;你最好将所有内容都放在一个表格中,而不是尝试在CSS样式中进行父/子关系。

如果你的表格真的没有人知道父/子关系就无法理解,你能否举个例子来说明表格数据,这样我就能更好地了解如何构建它?


0

谈论语义需要我们花费更多的时间,而不是为您的问题找到答案。

但是对于整个问题,this link应该会对您有所帮助。该页面包含您可能感兴趣的所有信息。有趣的是,与w3c编写的普通“声明性”规范不同,它在这个上下文中有关于问题的“建议性”写作。您可以从一开始就阅读。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接