Question

I have a table where elements can have child elements with the very same attributes, like:

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

From this I've created a markup like this:

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

My questions are now:

  • Is this the best semantic solution?
  • Is another approach better suited? If so, which is the recommended way?
  • Is the table header in charge for both tables or do I have to create a new one (maybe with visibility: hidden for the nested table?
Was it helpful?

Solution

Is this the best semantic solution?

Not really. While the act of nesting an element A within another element B can be used to indicate that A is a child of B, that isn't what you're doing here: you're nesting the table within a completely different row, so there's no implication of a parent-child relationship between A and B.

By creating a cell that spans all the columns in the table and then building another table inside that with the same number of columns, you're also effectively saying "these are some other columns, that don't relate to the ones in the outer table".

You can see the implied (lack of) relationship between the columns by adding a border to the cells in your example above:

Rendered table

Obviously you can fix that with CSS, but the unstyled rendering of a piece of HTML is often a good guide to its semantics.

Is another approach better suited? If so, which is the recommended way?

There's no standard way to represent hierarchical relationships between rows of a table in HTML. Cribbing from an answer I gave to a similar question, though, you can do it with extra classes, ids and data- attributes:

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

The parent-child relationship won't be visible in an unstyled rendering (there's no other way you could make it so without adding extra content, as far as I can see), but there are enough hooks to add the CSS required:

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

... which results in this:

Rendered table

With a little javascript, you could also use the id and data-parent attributes to set things up so that e.g. hovering over a row causes its parent to be highlighted.

Is the table header in charge for both tables, or do I have to create a new one?

In your proposed solution, creating a single cell that spans all columns and then building another table inside it means that there's no implied relationship between the header cells and those of your "child" row. Obviously my suggested solution above doesn't have that problem.

OTHER TIPS

This is W3C's recommendation:

At the current time, those who want to ensure consistent support across Assistive Technologies for tables where the headers are not in the first row/column may want to use the technique for complex tables H43: Using id and headers attributes to associate data cells with header cells in data tables. For simple tables that have headers in the first column or row we recommend the use of the th and td elements.

you can lock at this post: Best way to construct a semantic html table

hope that will help you to get your answer

Talking about semantics requires us to have more time than to find an answer for your question.

But for a whole point, this link should help you. That page contains all the information you may be interested in. Interestingly unlike normal 'declarative' spec w3c writes, it has 'suggestive' writing about the question in this context. You may wish to read right from the start.

I think putting the children in a separate table is the wrong way to go. Nested tables are not like nested lists; they don't carry that same semantic hierarchy. It seems everything should be within the same table if it all lists the same information.

For example, if your table had the headers

REGION    POPULATION     AREA

then you could have item1 = Earth, item2 = France, item3 = Paris... and it wouldn't really matter if France were a child of Earth or if Paris were a child of France; you'd still be better off keeping it all in one table and not trying to do a parent/child relationship other than in CSS styling.

If your table is really not comprehensible without someone knowing that parent/child relationship, could you give an example of the table data so I can better understand how to structure it?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top