How to keep fixed width HTML tables/columns fixed

I wrote a little PHP script that shows data from any table in an HTML table, and I had a little frustration in trying to keep the HTML table and column widths fixed.  I wanted to do this, because I want very large tables to appear to load very quickly, and not have columns “jump” or move as additional rows are outputted to the browser.  I needed to ensure the browser can determine the final width of all columns after it reads the first row in the table, and to never re-adjust it, regardless of what it finds in later rows.

I tried to control the “em” width of every column.  I wanted to base the “em” width on the contents of each column.  One might think this can be done by specifying a width in “em” in CSS for each <th>/</td> or <col>.  Nope.  I found I had to do all the following:

  1. In my CSS style sheet, I specify “table-layout: fixed;” for the table.  
  2. Specify an absolute width for the overall table.  By absolute, I mean anything other than “%”, which is relative to the parent width (e.g. page width).  I used “em”, which has a size based on the current font size.
  3. Specify relative (%) widths for each column, in the CSS for each <col> tag.  It’s best to use <col><colgroup> instead of styling every <th></td>.
In theory “table-layout: fixed;” alone should guarantee a fixed table layout (regardless of whether it looks pretty).  But, no.  Without table level width, the column widths are taken as merely minor hints, and the column widths jump around as the table loads.  One would think that specifying the column width in em’s alone could determine the width of the table (since it can just add them up).  But, the browser still made adjustments.  Even “max-width” would be violated to adjust for varying data lengths.
So, I found it’s better to specify the table width in “em” , and make the column widths “%:.  Specifying the “em” of each column and the table wouldn’t work, because I’d have to factor into padding and border widths to do the addition (which has to be changed with certain formatting changes in the table, and may vary by browser).  The relative (%) border widths are easily calculated, and effectively give me fixed column widths.
Now, the first rows of the table appear almost instantly when the page loads, and they never get adjusted.