39

There are two tables with width 600px and 5 Columns each. But, width has not been set for each column. Here, I want to make columns width must be same in both the tables. You can use CSS or jQuery. And, I dont want to fix the column width manually.

HTML Example:

<table width="600" border="1" cellspacing="0" cellpadding="0">
    <tr>
        <td>hdng 1</td>
        <td>hdng 2</td>
        <td>hdng 3</td>
        <td>hdng 4</td>
        <td>hdng 5</td>
    </tr>
</table>
<table width="600" border="1" cellspacing="0" cellpadding="0">
    <tr>
        <td>content content content</td>
        <td>con</td>
        <td>content content content</td>
        <td>content content content</td>
        <td>content content content</td>
    </tr>
</table>

Any help would be highly appreciated.

Raju Sarvasiddi
  • 411
  • 1
  • 4
  • 7
  • can you make it just one table? Then in the between the tables just Merge the cells so it does not look like a table – Daveo Aug 30 '12 at 05:14
  • Did you want column 2 to be narrower then the other columns? – Daveo Aug 30 '12 at 05:21
  • possible duplicate of [Make 2 tables have the same column sizes](http://stackoverflow.com/questions/1212796/make-2-tables-have-the-same-column-sizes) – Legolas Jan 28 '14 at 09:44

10 Answers10

23

I know this question is a year old, but there is a way to do what you're asking! Inside the table tag, you can use thead and tbody tags to group rows. You can also have multiple tbody tags, which allows you to keep the width the same (as they will be the same table), but style differently as required (or in my case, show and hide).

Example HTML can be found in this answer, copied for retnension https://stackoverflow.com/a/3076790/89211

<table>
    <thead>
        <tr><th>Customer</th><th>Order</th><th>Month</th></tr>
    </thead>
    <tbody>
        <tr><td>Customer 1</td><td>#1</td><td>January</td></tr>
        <tr><td>Customer 1</td><td>#2</td><td>April</td></tr>
        <tr><td>Customer 1</td><td>#3</td><td>March</td></tr>
    </tbody>
    <tbody>
        <tr><td>Customer 2</td><td>#1</td><td>January</td></tr>
        <tr><td>Customer 2</td><td>#2</td><td>April</td></tr>
        <tr><td>Customer 2</td><td>#3</td><td>March</td></tr>
    </tbody>
    <tbody>
        <tr><td>Customer 3</td><td>#1</td><td>January</td></tr>
        <tr><td>Customer 3</td><td>#2</td><td>April</td></tr>
        <tr><td>Customer 3</td><td>#3</td><td>March</td></tr>
    </tbody>
</table>
Relequestual
  • 11,631
  • 6
  • 47
  • 83
  • 3
    The snag I've run into with this method is that I use multiple theads as well, and when printing, it repeats the first one on every page. (I want it to repeat the thead that goes with the current tbody.) – Mark Eirich Feb 04 '14 at 15:11
  • I know it's not necessarily the best solution, but an option would be to print out the tables twice. Once with multiple theads, and the other with actual separate tables, but using a print media query, so the table is only shown when printed (and the other is hidden) – Relequestual Feb 05 '14 at 09:40
  • You can add headers to each `tbody` as well. Use `Header for this tbody's data`. See [Example](https://html.spec.whatwg.org/multipage/tables.html#the-th-element). – CletusW Feb 12 '20 at 20:23
  • 1
    @CletusW I think this is new since I answered. Consider adding it as a new answer =] – Relequestual Feb 13 '20 at 09:23
22

If you want all columns are in the same width, and since you're sure that you'll have exactly five columns in each table, I would suggest:

<table style="table-layout:fixed">
<col style="width:20%" span="5" />
<tr><!--stuffs...--></tr>
</table>
Passerby
  • 9,715
  • 2
  • 33
  • 50
  • 4
    Simply applying `table-layout:fixed` to the `table` worked, and aligned the columns perfectly. – VegaStudios Aug 15 '18 at 17:20
  • 10
    I think this is a misunderstanding of the question; it is looking for the (non-fixed) column widths to be the same across different tables. – Dan Apr 15 '19 at 13:32
8

I ran into this same issue and I found a kind of unclean, but working method.

Using JavaScript, you can momentarily combine both tables to get the desired auto-adjusted column widths and apply these widths to the elements in the two tables. After applying the widths to both tables in rows that aren't going to be removed, you can remove the rows you added to the combination table.

It's easiest if both tables are selectable individually (I just added ids) and if you can group the rows that you add to one table (I used tbody tags) so you can easily remove what you've added.

Hope this helps someone even though it's eight years late for the original post!

//add table 2 to table 1
$("#table1").append($("#table2 tbody").clone(true));

let table1_elems = $("#table1 tr:first td");
let table2_elems = $("#table2 tr:first td");
$(table1_elems).each(function(i) {
    //get the column width from the combined table and apply to both tables
    //(first one seems redundant, but is necessary once rows are removed)
    $(this).width($(this).width());
    $(table2_elems[i]).width($(this).width());
});

//remove the added rows
$("#table1 tbody:last").remove();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1" width="600" border="1" cellspacing="0" cellpadding="0">
    <tr>
        <td>hdng 1</td>
        <td>hdng 2</td>
        <td>hdng 3</td>
        <td>hdng 4</td>
        <td>hdng 5</td>
    </tr>
</table>
<table id="table2" width="600" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td>content content content</td>
            <td>con</td>
            <td>content content content</td>
            <td>content content content</td>
            <td>content content content</td>
        </tr>
    </tbody>
</table>
Duklas
  • 83
  • 1
  • 4
6

You are looking for table-layout:fixed

see example:

http://jsfiddle.net/RsAhk/

Lucas Green
  • 3,951
  • 22
  • 27
3

Table cell width is dependent on its content if the width is not given via style.

By default, most browsers use an automatic table layout algorithm. The widths of the table and its cells are adjusted to fit the content.

If you want to have an exact width to table cells of different tables then first understand the following description.

Table and column widths are set by the widths of the table and col elements or by the width of the first row of cells. Cells in subsequent rows do not affect column widths. Under the "fixed" layout method, the entire table can be rendered once the first table row has been downloaded and analyzed. This can speed up rendering time over the "automatic" layout method, but subsequent cell content might not fit in the column widths provided. Cells use the overflow property to determine whether to clip any overflowing content, but only if the table has a known width; otherwise, they won't overflow the cells.

CSS

table{
    table-layout:fixed; /* same width will be applied to both the tables*/
}
table td {
    width:20%;  /*20% width for 5 td elements*/
} 

for more information https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout

Nilesh Mahajan
  • 3,506
  • 21
  • 34
2

If you know that each table will have exactly 5 columns, applying width: 20% is your best bet:

td {
    width: 20%;
}

But if you can have any number of columns, you can instead write a simple JQuery script to figure out how many columns there are and set the widths accordingly.

Here is a JSFiddle demo. I modified the HTML to add id="first" to the first table, so I could get a concrete reference to it. Then the JavaScript is this:

var num = $("table#first tr:first-child > td").length;
var width = (100 / num) + "%";

$("td").css("width", width);​

Basically it grabs the first row of the #first table and counts the number of columns. Then it finds the corresponding percentage width for that number of columns. Then it applies that width to all <td> elements.

This will work as long as there are no colspan defined on the tds, which would throw off the column count. The columns will be equal since you've defined an explicit width on both tables.

Roddy of the Frozen Peas
  • 14,380
  • 9
  • 49
  • 99
2

We can move all the second table rows to the first table. Then set table cell width style to fix column width. After do this, we can move back the rows to the seconds table. And if the table has images or fonts, you should do the work after they loaded.

/**
* Align two table column width
* @param {HTMLTableElement} table1
* @param {HTMLTableElement} table2
*/
function fixTableCellWidth (table1, table2) {
    // container means `thead` or `tbody`
    const sourceContainers = Array.from(table2.children);
    const sourceTrs = sourceContainers.map(container => Array.from(container.children));
    // move second table rows to first table
    sourceTrs.forEach(trs => {
        trs.forEach(tr => {
            table1.lastElementChild.appendChild(tr);
        });
    });
    // fix table cell width
    Array.from(table1.children).forEach(container => {
        Array.from(container.children).forEach(tr => {
            Array.from(tr.children).forEach(td => {
                if (td.style.width) return;
                const rect = td.getClientRects()[0];
                td.style.width = `${rect.width}px`;
            });
        });
    });
    // move back the second table rows
    sourceTrs.forEach((trs, index) => {
        const container = sourceContainers[index];
        trs.forEach(tr => {
            container.appendChild(tr);
        });
    });
}

// Call `fixTableCellWidth` after ready
document.addEventListener('DOMContentLoaded', () => {
    fixTableCellWidth(document.getElementById('table1'), document.getElementById('table2'));
});
* {
    box-sizing: border-box;
}

table {
    border-collapse: collapse;
}

table td {
    border: 1px solid;
}
First Table:
<table id="table1" width="600" border="1" cellspacing="0" cellpadding="0">
<tbody>
    <tr>
        <td>hdng 1</td>
        <td>hdng 2</td>
        <td>hdng 3</td>
        <td>hdng 4</td>
        <td>hdng 5</td>
    </tr>
</tbody>
</table>
Second Table:
<table id="table2" width="600" border="1" cellspacing="0" cellpadding="0">
<tbody>
    <tr>
        <td>content content content</td>
        <td>con</td>
        <td>content content content</td>
        <td>content content content</td>
        <td>content content content</td>
    </tr>
</tbody>
</table>
Vince Wang
  • 21
  • 3
0

Define any css class and format the it and then use that class on both the tables e-g

your temp.css

.anyClass tr td{
width: 150p;
etc...
}

and in HTML file

    <table id="table1" class="anyClass">

        ......
        ......
        </table>

        <table id="table2" class="anyClass">        
        ......
        ......
        </table>
NoNaMe
  • 6,020
  • 30
  • 82
  • 110
  • Your answer will not work at all. You are setting the class on the `table` and then setting the width for that `table` to be `150px`. You need to set the class names to all the cells. But then you are forcing all the cells to be a fixed width that the op does not want. – sarcastyx Aug 30 '12 at 05:43
  • @sarcastyx thank you for your comment, updated the answer and this will work fine, – NoNaMe Aug 30 '12 at 05:54
  • this will work. But it comes back to the problem where the OP does not want to set a fixed width on the table cells. – sarcastyx Aug 30 '12 at 06:11
  • I dont want to fix any width for the table. It has to set on the fly. For example: If THEAD TH is greater than TBODY TD. Then, THEAD TH width should assign to TBODY TD. Otherwise, TBODY TD width should assign to THEAD TH. I knew only the TABLE width. Rest all should happen dynamically. Can use jQuery. – Raju Sarvasiddi Sep 03 '12 at 06:13
0

I created this in jQuery for my div tables where I have two tables and table-cells are labels and form fields. jQuery:

    $(".table").last().children().find("label").css("table", $(".table").first().children().find("label").css("width"));

CSS:

    .table {display:table;}
    .table div {display: table-row;}
    .table .formTitle {text-align: center;display: table-caption;}
    .table select,
    .table input,
    .table label {display: table-cell;}

HTML:

    <div class="table">
        <div class="formTitle"><span id="txtBI"></span></div>
        <div class="visTog"><label></label><input type="text" id="EntName"></div>
        <div class="visTog opac"><label></label><select id="EntYear"></select></div>
        <div class="visTog opac"><label></label><select id="EntMonth"></select></div>
        <div class="visTog opac"><label></label><select id="EntDay"></select></div>
    </div>
    <div class="table">
        <div class="visTog locrdsC formTitle"><span id="txtCalVal"></span></div>
        <div class="visTog locrdsC"><label></label><input type="text" name="gmt" id="EntposGMT" class="locrds"></div>
        <div class="visTog locrdsC"><label></label><input type="text" name="EntJday" id="EntJday" class="locrds"></div>
    </div>

</div>

This has a catch though. Could write a script to measure which one is bigger but in my case that isn't necessary.

I tend to make forms more interactive to improve usability; hence the visibility toggle and opacity classes, but are of no consequence to the cell width function.

iRoen
  • 1
  • 2
-1

You can sync the column widths by combining the tables with a tbody for each (as suggested by @Relequestual), and using <th scope="rowgroup"> for the headers:

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

CletusW
  • 3,890
  • 1
  • 27
  • 42