Any way to synchronize table column widths with HTML + CSS?

Viewed 37473

I have a number of tables with the same columns and it would look a lot nicer if they shared the same column widths. Is such a thing possible? Putting them in the same table with some rows with no borders between them isn't an option.

Edit: Yeah I'm aware I can fix the widths myself but I was hoping for something that would tie in to the browser's column width algorithm but simply tied two or more tables together for the purpose of doing that layout.

I didn't think such a thing was possible but I thought I'd check just in case.

9 Answers

If you're not too picky about which column widths the browser comes up with, as long as they're the same across different tables, you can use the CSS table-layout property (supported by all major browsers) in combination with a table width:

table {
    table-layout: fixed;
    width: 100%;
}

This causes all columns (without a specified width) to have the same width, regardless of the table content.

It's only possible if you can fix-width the columns. If you can set a fixed width then some css like this should work:

td {
    width: 25%;
}

You can customize each columns width like this:

<table>
  <tr>
    <td class="col1">...</td>
    <td class="col2">...</td>
  </tr>
</table>
...
<table>
  <tr>
    <td class="col1">...</td>
    <td class="col2">...</td>
  </tr>
</table>

and then specify the widths like this:

.col1 {
   width: 25%;
}
.col2 {
   width: 75%;
}

Here's a small JavaScript I made to resize cells to make them equal width in all tables on a page.

function resizeTables()
{
    var tableArr = document.getElementsByTagName('table');
    var cellWidths = new Array();

    // get widest
    for(i = 0; i < tableArr.length; i++)
    {
        for(j = 0; j < tableArr[i].rows[0].cells.length; j++)
        {
           var cell = tableArr[i].rows[0].cells[j];

           if(!cellWidths[j] || cellWidths[j] < cell.clientWidth)
                cellWidths[j] = cell.clientWidth;
        }
    }

    // set all columns to the widest width found
    for(i = 0; i < tableArr.length; i++)
    {
        for(j = 0; j < tableArr[i].rows[0].cells.length; j++)
        {
            tableArr[i].rows[0].cells[j].style.width = cellWidths[j]+'px';
        }
    }
}

window.onload = resizeTables;

To expand on Ken's answer, you can also specify the exact widths in pixels:

td { width: 250px }

or ems (width of the letter m):

td { width: 32em }

or ex or pt or whatever (well...actually %, pt, px, em, ex might be it). If you need your columns to be different widths, then the easy way is to give the table cells classes:

<table><tr>
    <td class="col1">...</td><td class="col2">...</td>...
</tr></table>

and assign column widths to the classes:

td.col1 { width: 48em }
td.col2 { width: 200px }
...

It should be sufficient to assign column widths to the first row in each table. [edit: looks like I've been scooped on that while I was writing]

You could probably also go crazy with the CSS 2 sibling selector, and write something like

tr > td:first-child { width:48em } /* first column */
tr > td:first-child + td { width: 200px } /* second column */
tr > td:first-child + td + td { width: 5% } /* third column  */
...

but if you have more than a few columns, that could get ugly. And if you're using some sort of template system or script to generate these tables, I'm sure it'll be easier/clearer to just put the class="col#" attribute on each cell in your template once.

I'm almost shocked that no one has suggested column groups! With it you can give a column a specific class, width, and other helpful properties. And since it's HTML 4.01 it's supported by all browsers that support the doctype.

You can sync the column widths by combining the tables (as suggested by @Stefanvds), but using a tbody + th for each:

table {
  border-collapse: collapse;
}

table thead,
table tbody {
  border-bottom: solid;
}

table tbody th {
  text-align: left;
}
<table>
  <thead>
    <tr> <th> ID <th> Measurement <th> Average <th> Maximum
  <tbody>
    <tr> <td> <th scope=rowgroup> Cats <td> <td>
    <tr> <td> 93 <th scope=row> Legs <td> 3.5 <td> 4
    <tr> <td> 10 <th scope=row> Tails <td> 1 <td> 1
  <tbody>
    <tr> <td> <th scope=rowgroup> English speakers <td> <td>
    <tr> <td> 32 <th scope=row> Legs <td> 2.67 <td> 4
    <tr> <td> 35 <th scope=row> Tails <td> 0.33 <td> 1
</table>

Source: Example in the HTML spec itself

Related