52

I'm trying to create a page with a number of static html tables on them.

What do I need to do to get them to display each column the same size as each other column in the table?

The HTML is as follows:

<span class="Emphasis">Interest rates</span><br />
<table cellpadding="0px" cellspacing="0px" class="PerformanceTable">
    <tr><th class="TableHeader"></th><th class="TableHeader">Current rate as at 31 March 2010</th><th class="TableHeader">31 December 2009</th><th class="TableHeader">31 March 2009</th></tr>
    <tr class="TableRow"><td>Index1</td><td class="PerformanceCell">1.00%</td><td>1.00%</td><td>1.50%</td></tr>
    <tr class="TableRow"><td>index2</td><td class="PerformanceCell">0.50%</td><td>0.50%</td><td>0.50%</td></tr>
    <tr class="TableRow"><td>index3</td><td class="PerformanceCell">0.25%</td><td>0.25%</td><td>0.25%</td></tr>
</table>
<span>Source: Bt</span><br /><br />

<span class="Emphasis">Stock markets</span><br />
<table cellpadding="0px" cellspacing="0px" class="PerformanceTable">
    <tr><th class="TableHeader"></th><th class="TableHeader">As at 31 March 2010</th><th class="TableHeader">1 month change</th><th class="TableHeader">QTD change</th><th class="TableHeader">12 months change</th></tr>
    <tr class="TableRow"><td>index1</td><td class="PerformanceCell">1169.43</td><td class="PerformanceCell">5.88%</td><td class="PerformanceCell">4.87%</td><td class="PerformanceCell">46.57%</td></tr>
    <tr class="TableRow"><td>index2</td><td class="PerformanceCell">1958.34</td><td class="PerformanceCell">7.68%</td><td class="PerformanceCell">5.27%</td><td class="PerformanceCell">58.31%</td></tr>
    <tr class="TableRow"><td>index3</td><td class="PerformanceCell">5679.64</td><td class="PerformanceCell">6.07%</td><td class="PerformanceCell">4.93%</td><td class="PerformanceCell">44.66%</td></tr>
    <tr class="TableRow"><td>index4</td><td class="PerformanceCell">2943.92</td><td class="PerformanceCell">8.30%</td><td class="PerformanceCell">-0.98%</td><td class="PerformanceCell">44.52%</td></tr>
    <tr class="TableRow"><td>index5</td><td class="PerformanceCell">978.81</td><td class="PerformanceCell">9.47%</td><td class="PerformanceCell">7.85%</td><td class="PerformanceCell">26.52%</td></tr>
    <tr class="TableRow"><td>index6</td><td class="PerformanceCell">3177.77</td><td class="PerformanceCell">10.58%</td><td class="PerformanceCell">6.82%</td><td class="PerformanceCell">44.84%</td></tr>
</table>
<span>Source: B</span><br /><br />

I'm also open to suggestion on how to tidy this up, if there are any? :-)

edit: I should add that the cellpadding & cellspacing attributes are require by a 3rd party PDF conversion app that we use

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
DaveDev
  • 41,155
  • 72
  • 223
  • 385

8 Answers8

63

You can use CSS. One way is to set table-layout to fixed, which stops the table and its children from sizing according to their content. You can then set a fixed width on the relevant td elements. This should do the trick:

table.PerformanceTable {
    table-layout: fixed;
    width: 500px;
}
    table.PerformanceTable td.PerformanceCell {
        width: 75px;
    }

Suggestions for for tidying up? You don't need the cellpadding or cellspacing attributes, or the TableRow and TableHeader classes. You can cover those off in CSS:

table {
    /* cellspacing */
    border-collapse: collapse;
    border-spacing: 0;
}
th {
    /* This covers the th elements */
}
tr {
    /* This covers the tr elements */
}
th, td {
    /* cellpadding */
    padding: 0;
}

You should use a heading (e.g. <h2>) instead of <span class="Emphasis"> and a <p> or a table <caption> instead of the Source <span>. You wouldn't need the <br> elements either, because you'd be using proper block level elements.

Olly Hodgson
  • 15,076
  • 3
  • 40
  • 60
  • 2
    Be careful, though, because setting `white-space: nowrap` will negate the `table-layout: fixed`; the cells will again expand to fit the contents. Also, if you put in an image with a width greater than the cell width, the cell will again expand. Also, you won't be able to set a height on the cells (but you never could anyway, really). – Robusto May 18 '10 at 16:58
  • 1
    Very good point. text-overflow can help negate the nowrap issue though, see http://www.quirksmode.org/css/textoverflow.html – Olly Hodgson May 18 '10 at 17:07
  • 5
    Worth noting that if you do *not* set `width` on any of the ``'s their width's are split evenly. Ie, 3 column table = 33.3% each, 5 columns = 20% each, etc... – Zach Lysobey Nov 23 '15 at 17:38
  • This squishes my table. Only other attribute in the table is td colspan=2. Please update to cover more general cases. – Philip Rego Apr 19 '19 at 15:09
  • @PhilipRego It squishes it to the size you specify in the CSS, rather than the size the content wants to take up. In my example above, it sets the `` to 500px wide, and `
    ` to 75px wide. It's up to you to specify appropriate widths for your use case.
    – Olly Hodgson Apr 19 '19 at 16:52
  • Thanks this worked. My only issue is when the string doesn't have spaces it continues horizonally instead of using a hyphen. https://jsfiddle.net/whatthephil/qptL2e81/ – Philip Rego Apr 19 '19 at 17:15
  • 1
    You might want to have a look into CSS hyphenation: https://justmarkup.com/log/2019/01/a-look-at-css-hyphenation-in-2019/ – Olly Hodgson Apr 19 '19 at 17:56
22

You could always just set the width of each td to 100%/N columns.

<td width="x%"></td>
Matt
  • 9,068
  • 12
  • 64
  • 84
James Van Boxtel
  • 2,365
  • 4
  • 22
  • 33
  • I would suggest using CSS rather than the width attribute. Just add width: ### to .PerformanceCell. You can generate a definition for .PerformanceCell in the particular HTML page with a width appropriate for that page if the width depends on the actual data or other factors. – Eric J. May 18 '10 at 16:37
  • @JamesVanBoxtel If you're generating the code using JQuery, `$('.myTableClass td'.css('width','100/NumberOfColumns%')` – acrawly Apr 03 '14 at 16:52
  • `width` property is now deprecated in HTML. – YektaDev Mar 13 '21 at 10:21
1

In your CSS file:

.TableHeader { width: 100px; }

This will set all of the td tags below each header to 100px. You can also add a width definition (in the markup) to each individual th tag, but the above solution would be easier.

ground5hark
  • 4,464
  • 8
  • 30
  • 35
1

If you want all your columns a fixed size, you could use CSS:

td.PerformanceCell
{
    width: 100px;
}

Or better, use th.TableHeader (I didn't notice that the first time around).

JYelton
  • 35,664
  • 27
  • 132
  • 191
1

I was designing a html email and had a similar problem. But having every cell with the fixed width is not what I want. I'd like to have the equal spacing between the contents of the columns, like the following

|---something---|---a very long thing---|---short---|

After a lot of trial and error, I came up with the following

<style>
    .content {padding: 0 20px;}
</style>

table width="400"
    tr
        td
            a.content something
        td 
            a.content a very long thing
        td 
            a.content short

Issues of concern:

  1. Outlook 2007/2010/2013 don't support padding. Having the width of the table set will allow the widths of the columns to automatically set. This way, though the contents will not have equal spacing. They at least have some spacing between them.

  2. Automatic width setting for table columns will not give equal spacing between the contents The padding added for the contents will force the equal spacing.

hexinpeter
  • 1,470
  • 1
  • 16
  • 14
1

Make a surrounding div-tag, and set for it display: grid in its style attribute.

<div style='display: grid; 
            text-align: center;
            background-color: antiquewhite'
>
  <table>
    <tr>
      <th>Month</th>
      <th>Savings</th>
    </tr>
    <tr>
      <td>January</td>
      <td>$100</td>
    </tr>
    <tr>
      <td>February</td>
      <td>$80</td>
    </tr>
  </table>
</div>

The text-align property is set only to show, that the text in the regular table cells are affected by it, even though it is set on the surrounding div. The same with the background-color but it is hard to say which element actually holds the background-color.

0

I'm also open to suggestion on how to tidy this up, if there are any? :-)

Well, you could not use the span element, for semantic reasons. And you don't have to define the class PerformanceCell. The cells and rows can be accessed by using PerformanceTable tr {} and PerformanceTable tr {}, respectively.

For the spacing part, I have got the same problem several times. I shamefully admit I avoided the problem, so I am very curious to any answers too.

BRUL
  • 41
  • 5
0

Take the width of the table and divide it by the number of cell ().

PerformanceTable {width:500px;}    
PerformanceTable.td {width:100px;}

If the table dynamically widens or shrinks you could dynamically increase the cell size with a little javascript.

Chuck Conway
  • 16,287
  • 11
  • 58
  • 101