Search code examples
htmlhtml-table

Table headers inside main table header in HTML


How can I achieve this kind of table:

enter image description here

Inside the Schedule column, there are sub columns (Jan, Feb and so on).

I tried <th></th> inside a <th></th>

But it is not working.

See my fiddle: http://jsfiddle.net/TAJzY/1/


Solution

    • The solution is colspan="" and rowspan="":
      • Use colspan="12" on the "Schedule/Milestone of Activities" cell.
        • And remove the 12 empty trailing cells in the same <tr> row.
      • Use rowspan="2" on the "Estimated Budget" cell.
        • And remove the single empty initial <th> cell from the <tr> below.
    • Don't forget to use explicit <thead>, <tbody>, and optional <tfoot> sections.
      • While you can use HTML tables without explicit sections, styling HTML tables with CSS is a lot easier and effective this way, and you can use techniques like thead { position: sticky; } for Excel-style "frozen" rows which are otherwise very difficult - or just tedious - to implement otherwise.

    Step 1:

    First, make a table, without any splitting/merging of cells, so you have something like this (click the "Run code snippet" button below to see the table):

    table { border: 1px outset #bbb; }
    table > * > tr > * { border: 1px inset #bbb; }
    
    thead { background-color: #7ACABD; text-align: center; }
    tbody { background-color: #e0fffa; }
    tfoot { background-color: #39c4ae' }
    <table>
        <thead>
            <tr>
                <th>Estimated Budget</th>
                <th>Schedule/Milestone of Activities</th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
            </tr>
            <tr>
                <th></th>
                <th>Jan</th>
                <th>Feb</th>
                <th>Mar</th>
                <th>Apr</th>
                <th>May</th>
                <th>Jun</th>
                <th>Jul</th>
                <th>Aug</th>
                <th>Sep</th>
                <th>Oct</th>
                <th>Nov</th>
                <th>Dec</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>$123</td>
                <td>j</td>
                <td>f</td>
                <td>m</td>
                <td>a</td>
                <td>m</td>
                <td>j</td>
                <td>j</td>
                <td>a</td>
                <td>s</td>
                <td>o</td>
                <td>n</td>
                <td>d</td>
            </tr>
             <tr>
                <td>$456</td>
                <td>j</td>
                <td>f</td>
                <td>m</td>
                <td>a</td>
                <td>m</td>
                <td>j</td>
                <td>j</td>
                <td>a</td>
                <td>s</td>
                <td>o</td>
                <td>n</td>
                <td>d</td>
            </tr>
        </tbody>
        </table>

    Step 2:

    Then make the "Schedule/Milestone of Activities" cell span all 12 remaining columns (of the 13 total) with colspan="12" - which also means removing the empty trailing <th></th> elements in the same <tr> as those are now represented by the <th colspan="12"> cell:

    table { border: 1px outset #bbb; }
    table > * > tr > * { border: 1px inset #bbb; }
    
    thead { background-color: #7ACABD; }
    tbody { background-color: #e0fffa; }
    tfoot { background-color: #39c4ae' }
    <table>
        <thead>
            <tr>
                <th>Estimated Budget</th>
                <th colspan="12">Schedule/Milestone of Activities</th>
            </tr>
            <tr>
                <th></th>
                <th>Jan</th>
                <th>Feb</th>
                <th>Mar</th>
                <th>Apr</th>
                <th>May</th>
                <th>Jun</th>
                <th>Jul</th>
                <th>Aug</th>
                <th>Sep</th>
                <th>Oct</th>
                <th>Nov</th>
                <th>Dec</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>$123</td>
                <td>j</td>
                <td>f</td>
                <td>m</td>
                <td>a</td>
                <td>m</td>
                <td>j</td>
                <td>j</td>
                <td>a</td>
                <td>s</td>
                <td>o</td>
                <td>n</td>
                <td>d</td>
            </tr>
             <tr>
                <td>$456</td>
                <td>j</td>
                <td>f</td>
                <td>m</td>
                <td>a</td>
                <td>m</td>
                <td>j</td>
                <td>j</td>
                <td>a</td>
                <td>s</td>
                <td>o</td>
                <td>n</td>
                <td>d</td>
            </tr>
        </tbody>
        </table>

    Step 3:

    To make the "Estimated Budget" cell span those 2 rows in <thead> add rowspan="2" and also remove the empty initial <th></th> in the second <tr> (as that empty <th> cell's "slot" is now taken by the <th rowspan="2"> from the previous row).

    Like so:

    table { border: 1px outset #bbb; }
    table > * > tr > * { border: 1px inset #bbb; }
    
    thead { background-color: #7ACABD; }
    tbody { background-color: #e0fffa; }
    tfoot { background-color: #39c4ae; }
    
    /* Right-align budget numbers in the first column: */
    table > tbody > tr > td:first-child { text-align: right; }
    <table>
        <thead>
            <tr>
                <th rowspan="2">Estimated Budget</th>
                <th colspan="12">Schedule/Milestone of Activities</th>
            </tr>
            <tr>
                <th>Jan</th>
                <th>Feb</th>
                <th>Mar</th>
                <th>Apr</th>
                <th>May</th>
                <th>Jun</th>
                <th>Jul</th>
                <th>Aug</th>
                <th>Sep</th>
                <th>Oct</th>
                <th>Nov</th>
                <th>Dec</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>$123</td>
                <td>j</td>
                <td>f</td>
                <td>m</td>
                <td>a</td>
                <td>m</td>
                <td>j</td>
                <td>j</td>
                <td>a</td>
                <td>s</td>
                <td>o</td>
                <td>n</td>
                <td>d</td>
            </tr>
             <tr>
                <td>$456</td>
                <td>j</td>
                <td>f</td>
                <td>m</td>
                <td>a</td>
                <td>m</td>
                <td>j</td>
                <td>j</td>
                <td>a</td>
                <td>s</td>
                <td>o</td>
                <td>n</td>
                <td>d</td>
            </tr>
        </tbody>
        </table>