Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have to do a table like this one:

+-------+-------+-------+-------+-------+-------+
|         th 1          | th 2  | th 3  | th 4  |
+-------+-------+-------+-------+-------+-------+
|       |       |       | td 1  | td 2  | td 3  |
|       |       | th 7  +-------+-------+-------+
|       |       |       | td 4  | td 5  | td 6  |
|       | th 6  +-------+-------+-------+-------+
|       |       |       | td 7  | td 8  | td 9  |
|       |       | th 8  +-------+-------+-------+
|       |       |       | td 10 | td 11 | td 12 |
| th 5  +-------+-------+-------+-------+-------+
|       |       |       | td 13 | td 14 | td 15 |
|       |       | th 10 +-------+-------+-------+
|       |       |       | td 16 | td 17 | td 18 |
|       | th 9  +-------+-------+-------+-------+
|       |       |       | td 19 | td 20 | td 21 |
|       |       | th 11 +-------+-------+-------+
|       |       |       | td 22 | td 23 | td 24 |
+-------+-------+-------+-------+-------+-------+

The way I'm doing it right now is

<table>
    <thead>
        <tr>
            <th colspan="3">th 1</th>
            <th>th 2</th>
            <th>th 3</th>
            <th>th 4</th>
        </tr>            
    </thead>
     <tbody>
         <tr>
             <th rowspan="8">th 5</th>
             <th rowspan="4">th 6</th>
             <th rowspan="2">th 7</th>
             <td>td 1</td>
             <td>td 2</td>
             <td>td 3</td>
         </tr>
         <tr>
             <td>td 4</td>
             <td>td 5</td>
             <td>td 6</td>
         </tr>
         <tr>
             <th rowspan="2">th 8</th>
             <td>td 7</td>
             <td>td 8</td>
             <td>td 9</td>
         </tr>
         <tr>
             <td>td 10</td>
             <td>td 11</td>
             <td>td 12</td>
         </tr>
         <tr>
             <th rowspan="4">th 9</th>
             <th rowspan="2">th 10</th>
             <td>td 13</td>
             <td>td 14</td>
             <td>td 15</td>
         </tr>
         <tr>
             <td>td 16</td>
             <td>td 17</td>
             <td>td 18</td>
         </tr>
         <tr>
             <th rowspan="2">th 11</th>
             <td>td 19</td>
             <td>td 20</td>
             <td>td 21</td>
         </tr>
         <tr>
             <td>22</td>
             <td>23</td>
             <td>24</td>
         </tr>
     </tbody>
 </table>

What I want to know is if there is another, cleaner way to construct the same structure, like having the td in tr different than the same in which the th are constructed to have them separated.

I created a jsfiddle if anyone knows a better way to do it. http://jsfiddle.net/mkhuete/ehX7X/1/

share|improve this question

migrated from stackoverflow.com Oct 25 '12 at 22:39

This question came from our site for professional and enthusiast programmers.

2  
Looks fine to me. –  iambriansreed Oct 25 '12 at 21:02
2  
The structure looks OK. Nothing has been said about semantics (i.e., meanings) involved. The question “if there is another way, more clean to construct these same structure, like having the td in tr differents than the same in which the th are constructed to have them separated” just does not parse, still less make sense. –  Jukka K. Korpela Oct 25 '12 at 21:32
    
Because of the clean, it looks clean I like the table "colgroup" tag and maybe this link will help a little too stackoverflow.com/questions/1006089/setting-rowspan-on-colgroup –  caramba Feb 26 '13 at 15:12

2 Answers 2

I can't fault your tags at all. The only problem is that due to your table being quite complex, assistive technology may not be able to figure out the structure of your table.

I was going to recommend using scope but according to W3C there are some inconsistency issues.

The row and col values of the scope attribute are currently supported to a large extent by most current versions of JAWS. However, there are still some problems and WindowEyes support for scope is inconsistent. The same is true for Japanese versions of these screen readers. Versions of JAWS prior to version 5 and older versions of Window-Eyes have inconsistent support for scope.

Using scope would look like this, with scope="col" in all <th> elements in the first row and scope="row" for all other <th> elements.

<table>
    <thead>
        <tr>
            <th colspan="3" scope="col">th 1</th>
            <th scope="col">th 2</th>
            <th scope="col">th 3</th>
            <th scope="col">th 4</th>
        </tr>            
    </thead>
    <tbody>
        <tr>
            <th rowspan="8" scope="row">th 5</th>
            <th rowspan="4" scope="row">th 6</th>
            <th rowspan="2" scope="row">th 7</th>
            <td>td 1</td>
            <td>td 2</td>
            <td>td 3</td>
        </tr>
        <tr>
            <td>td 4</td>
            <td>td 5</td>
            <td>td 6</td>
        </tr>
        <tr>
            <th rowspan="2" scope="row">th 8</th>
            <td>td 7</td>
            <td>td 8</td>
            <td>td 9</td>
        </tr>
        <tr>
            <td>td 10</td>
            <td>td 11</td>
            <td>td 12</td>
        </tr>
        <tr>
            <th rowspan="4" scope="row">th 9</th>
            <th rowspan="2" scope="row">th 10</th>
            <td>td 13</td>
            <td>td 14</td>
            <td>td 15</td>
        </tr>
        <tr>
            <td>td 16</td>
            <td>td 17</td>
            <td>td 18</td>
        </tr>
        <tr>
            <th rowspan="2" scope="row">th 11</th>
            <td>td 19</td>
            <td>td 20</td>
            <td>td 21</td>
        </tr>
        <tr>
            <td>td 22</td>
            <td>td 23</td>
            <td>td 24</td>
        </tr>
    </tbody>
</table>

JSFiddle for scope method

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.

Let me just start off by saying this is a complete pain in order to be completely accessibly and scope will probably be fine in most cases. Here is the table using the id/header method (shudder):

<table>
    <thead>
        <tr>
            <th colspan="3" id="th1">th 1</th>
            <th id="th2">th 2</th>
            <th id="th3">th 3</th>
            <th id="th4">th 4</th>
        </tr>            
    </thead>
    <tbody>
        <tr>
            <th rowspan="8" id="th5" headers="th1">th 5</th>
            <th rowspan="4" id="th6" headers="th1 th5">th 6</th>
            <th rowspan="2" id="th7" headers="th1 th5 th6">th 7</th>
            <td headers="th2 th5 th6 th7">td 1</td>
            <td headers="th3 th5 th6 th7">td 2</td>
            <td headers="th4 th5 th6 th7">td 3</td>
        </tr>
        <tr>
            <td headers="th2 th5 th6 th7">td 4</td>
            <td headers="th3 th5 th6 th7">td 5</td>
            <td headers="th4 th5 th6 th7">td 6</td>
        </tr>
        <tr>
            <th rowspan="2" id="th8" headers="th1 th5 th6">th 8</th>
            <td headers="th2 th5 th6 th8">td 7</td>
            <td headers="th3 th5 th6 th8">td 8</td>
            <td headers="th4 th5 th6 th8">td 9</td>
        </tr>
        <tr>
            <td headers="th2 th5 th6 th8">td 10</td>
            <td headers="th3 th5 th6 th8">td 11</td>
            <td headers="th4 th5 th6 th8">td 12</td>
        </tr>
        <tr>
            <th rowspan="4" id="th9" headers="th1 th5">th 9</th>
            <th rowspan="2" id="th10" headers="th1 th5 th9">th 10</th>
            <td headers="th2 th5 th9 th10">td 13</td>
            <td headers="th3 th5 th9 th10">td 14</td>
            <td headers="th4 th5 th9 th10">td 15</td>
        </tr>
        <tr>
            <td headers="th2 th5 th9 th10">td 16</td>
            <td headers="th3 th5 th9 th10">td 17</td>
            <td headers="th4 th5 th9 th10">td 18</td>
        </tr>
        <tr>
            <th rowspan="2" id="th11" headers="th1 th5 th9">th 11</th>
            <td headers="th2 th5 th9 th11">td 19</td>
            <td headers="th3 th5 th9 th11">td 20</td>
            <td headers="th4 th5 th9 th11">td 21</td>
        </tr>
        <tr>
            <td headers="th2 th5 th9 th11">td 22</td>
            <td headers="th3 th5 th9 th11">td 23</td>
            <td headers="th4 th5 th9 th11">td 24</td>
        </tr>
    </tbody>
</table>

JSFiddle for id/headers

What is comes down to in the end in my opinion is an accessible solution that is also maintainable in the back end. Realistically JAWS and WindowEyes will eventually fix up their bugs and using scope will be fine even for tables as complex as this. Unless you expect many users to use assistive technologies and require strict adherence to WCAG, go with scope. Markup needs to be beautiful too :)

There is also the <colgroup> element which is relevant but support for it isn't great currently.

share|improve this answer
    
Thanks! it's an interesting approach, thanks for helping me –  mkhuete Mar 10 '13 at 8:33

Plan it out on paper with percentages, and then take it row by row in an editor, inserting the content as you go. Otherwise you can't do it at all. And the more cells and custom rowspan/colspan you use with coding non-CSS table design, the time taken to code it all increases exponentially.

share|improve this answer
    
The author has already sketched the layout, and the rowspan and colspan attributes are already correct. Furthermore, the question is about semantics, not layout. –  200_success Apr 15 at 16:44

protected by 200_success Apr 15 at 16:44

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.