views:

666

answers:

5

Simple (I hope), HTML question.

Let's say I have a column group that spans 3 columns. But it also spans 9 rows. But in actuality, I want there to be 3 levels of columns (so basically, 3 columns, split across 9 rows). The only objectives really are:

a) avoid embedding tables (for various reasons) b) keep the sections modular. c) allow for styling of the semantically modular areas.

So in the end, I would have something visually like:

   | col 1  | col 2 | col 3 |
   | row 1  | row 1 | row 1 |
   | row 2  | row 2 | row 2 |
   | row 3  | row 3 | row 3 |

   | col 4  | col 5 | col 6 |
   | row 4  | row 4 | row 4 |
   | row 5  | row 5 | row 5 |
   | row 6  | row 6 | row 6 |

   | col 7  | col 2 | col 3 |
   | row 7  | row 7 | row 7 |
   | row 8  | row 8 | row 8 |
   | row 9  | row 9 | row 9 |

I was able to get the column groups to work to keep the 3 columns together, but an attempt to add "rowspan" failed.Trying to wrap the row groups in tr tags was no good at all. and as far as i an tell, there is no real "rowgroup" tag.

Update:

After getting feedback, I realized I should give more details on what I have in mind.

I'll use the term quad, super-column, super-row to refer to groups of data. So take this example:

               Quad 1       Quad 2
super-row1 | a | b | c || d | e | f |
super-row2 | 1 | 2 | 3 || 4 | 5 | 6 |
super-row3 | A | B | C || D | E | F |

               Quad 3       Quad 4
super-row4 | g | h | i || j | k | l |
super-row5 | 7 | 8 | 9 || 0 | 1 | 2 |
super-row6 | G | H | I || J | K | L |

For simplicity sake, just imagine that across the top I wrote super-col 1 - 6.

So, the data in quad 1 is all related, and the data in super-row 1 is all related, and the data in super-col 1 is all related. So, using the above data,

'a' has a direct relationship with 'f', 'C', and 'G', but 'f', 'C', and 'G' have no direct relationship with each other.

Another way of thinking about it is Sudoku, where each quad, column, and row contain the set of 1-9, making any of the 81 data points related directly to any other data points it shares a row, column, or quad with, but not to any data points.

Quick update:

One last thing, sorry. It's important that these relationships be grouped semantically in the HTML so that, should someone be using a screen reader or non-traditional browser, they can know where they are in the table at any given point, ie "You are in Quad 1, Super Col 1, Column 4, Super Row 1, Row 1. The data is 'Ohio'."

This makes styling, cross-browser compatibility, accessibility all much easier, as well as an moving around such as AccessKeys, Scope, etc.

+2  A: 

A <table> can have multiple <tbody> children, which represent row groups. I've not used the <colgroup> element before, so I'll leave that for someone else to add, but here is a solution that will allow you to achieve your styling needs whilst keeping it semantic:

<table>
    <tbody>
        <tr>
            <th scope="col">col 1</th>
            <th scope="col">col 2</th>
            <th scope="col">col 3</th>
        </tr>
        <tr>
            <td>row 1</td>
            <td>row 1</td>
            <td>row 1</td>
        </tr>
        <tr>
            <td>row 2</td>
            <td>row 2</td>
            <td>row 2</td>
        </tr>
        <tr>
            <td>row 3</td>
            <td>row 3</td>
            <td>row 3</td>
        </tr>
    </tbody>
    <tbody>
        <tr>
            <th scope="col">col 4</th>
            <th scope="col">col 5</th>
            <th scope="col">col 6</th>
        </tr>
        <tr>
            <td>row 4</td>
            <td>row 4</td>
            <td>row 4</td>
        </tr>
        <tr>
            <td>row 5</td>
            <td>row 5</td>
            <td>row 5</td>
        </tr>
        <tr>
            <td>row 6</td>
            <td>row 6</td>
            <td>row 6</td>
        </tr>
    </tbody>
    <tbody>
        <tr>
            <th scope="col">col 7</th>
            <th scope="col">col 8</th>
            <th scope="col">col 9</th>
        </tr>
        <tr>
            <td>row 7</td>
            <td>row 7</td>
            <td>row 7</td>
        </tr>
        <tr>
            <td>row 8</td>
            <td>row 8</td>
            <td>row 8</td>
        </tr>
        <tr>
            <td>row 9</td>
            <td>row 9</td>
            <td>row 9</td>
        </tr>
    </tbody>
</table>

I based this on information from the HTML 5 spec, but it should be valid HTML 4 as well.

roryf
I thought of doing multiple tbodies, but I wasn't sure if that was semantically the most correct approach, because of the relationship between the various groups of data. I agree completely that it's an easy and efficient method without resorting to nested table hacks, but... the data in each "super-column" is actually all related, so I don't want to separate it from the surrounding (above or below) columns in such a way that I lose that relationship. The data in col 1 row 1 is relevant to the data in col 7 row 9, its just MORE relevant to the data in col 1 row 4 and row 5.
Anthony
A: 

I think the easiest is to skip the colgroup-element all together and go with simple class styling instead:

<table>
    <tr class="colgroup1">
        <th>col1</th><th>col2</th><th>col3</th>
    </tr>
    <tr class="colgroup1">
        <td>row1</td><td>row1</td><td>row1</td>
    </tr>
    <tr class="colgroup1">
        <td>row2</td><td>row2</td><tr>row2</td>
    </tr>
    <tr class="colgroup2">
        <th>col4</th><th>col5</th><th>col6</th>
    </tr>
    <tr class="colgroup2">
        <td>row3</td><td>row3</td><td>row3</td>
    </tr>
    <tr class="colgroup2">
        <td>row4</td><td>row4</td><td>row4</td>
    </tr>
    <tr class="colgroup3">
        <th>col7</th><th>col8</th><th>col9</th>
    </tr>
    <tr class="colgroup3">
        <td>row5</td><td>row5</td><td>row5</td>
    </tr>
    <tr class="colgroup3">
        <td>row6</td><td>row6</td><td>row6</td>
    </tr>
</table>

Then, you can target the different colgroups easily in CSS:

.colgroup1 th {
   // Styles here
}

.colgroup2 th {
   // Styles here
}


.colgroup3 th {
   // Styles here
}

// Same for tds.

Edit: I like how Rory Fitzpatrick uses multiple table bodies. If that is indeed valid, then I'd go with that solution and just put a class name on each table body tag. The CSS will remain the same

PatrikAkerstrand
I thought about going this route as well. The problem, as I mentioned on my comment to Rory, is that I don't just want to group them for style purposes, but also for relational purposes. To be more specific:The data is basically in a sort of matrix. The example I used was for simplicity, but it's actually more complex. Imagine the example times 5, where there would be 3 columns in each group, and 5 column groups. Each quad then would have data, and the data is relevant to any data other data in the super-column or super-row and to it's quad. Data one row down and one quad over is unrelated.
Anthony
+7  A: 

Given that <colgroup> is the only semantic method of grouping columns and <tbody> is the only semantic means of grouping rows, I'd recommend sticking with something simple:

<table>
    <colgroup id="colgroup1">
        <col id="colA" />
        <col id="colB" />
    </colgroup>
    <colgroup id="colgroup2">
        <col id="colC" />
        <col id="colD" />
    </colgroup>
    <tbody id="rowgroup1">
        <tr>
            <th>A</th>
            <th>B</th>
            <th>C</th>
            <th>D</th>
        </tr>
        <tr id="row1">
            <td>A1</td>
            <td>B1</td>
            <td>C1</td>
            <td>D1</td>
        </tr>
        <tr id="row2">
            <td>A2</td>
            <td>B2</td>
            <td>C2</td>
            <td>D2</td>
        </tr>
    </tbody>
    <tbody id="rowgroup2">
        <tr>
            <th>A</th>
            <th>B</th>
            <th>C</th>
            <th>D</th>
        </tr>
        <tr id="row3">
            <td>A3</td>
            <td>B3</td>
            <td>C3</td>
            <td>D3</td>
        </tr>
        <tr id="row4">
            <td>A4</td>
            <td>B4</td>
            <td>C4</td>
            <td>D4</td>
        </tr>
    </tbody>
</table>

This will allow you to style quads while still maintaining a clean, semantic structure. I'm not sure how much flexibility you'll have in styling, but you do have some options:

<style type="text/css">
    table { border-collapse:collapse; font-family:sans-serif; font-size:small; }
    td, th { border:solid 1px #000; padding:2px 10px; text-align:center; }
    th { background-color:#000; color:#fff; font-size:x-small; }
    colgroup { border:solid 3px #000; }
    tbody { border:solid 3px #000; }
</style>
Brandon Gano
I second this answer. The tbody tag IS the equivalent of a rowgoup. It just so happens that that there are three types of rowgroups (thead, tbody, and tfoot). Additionally the underestimated axis attribute can be added to the cells to "tags" same quadrant cells together. <td axis="quad1">. These may then be CSS selected with "table td[axis=quad1]".
Borgar
+1  A: 

If I remember correctly, the <colgroup> tag doesn't work properly in any browser (well, Opera maybe). I'd avoid it at all costs.

If I were you, I'd just make a simple table where each <td> represents a "quad", then make a table within that cell for the rest of the data.

nbv4
+1  A: 

The semantically correct way is nested tables, actually. Your example has a 2x2 table of quads and each quad is a 3x3 table of values. There's nothing semantically wrong with using a nested table for this. Don't get confused over the anti-nested-html-table crowd. That has to do with using nested tables for page layout.

Using nested tables also gives you more control over CSS styling. Using cols and colgroups only gives you very limited styling control. The only CSS properties you can set on a col or colgroup are border, background, with and visibility.

Sander Marechal