Prehistory
The story begins with a single ancient project with a web interface written under IE5-6. Of course, this mammoth under new versions of IE only works in quirks mode, under other browsers it is even difficult to draw, and you don’t have to dream about performance.
One bright day, a voice came from heaven to begin gradually rewriting it all on modern browsers and the work began to boil.
99% of the system were registries in the form of tables and forms of a separate card from this registry. The heading of the table should be fixed. In the old version, this was done by some specific crutches of c position that did not work already in IE7. jQuery has already been connected, the plugin for the fixed table header is easy to google. Doesn't support headers with multiple lines and different combinations of col and rowspans? Well, okay, you can do some work yourself, still go into the plug-in code and adapt it to the specific wrapper for the tables.
It would seem that everything is fine, but from time to time artifacts began to arise in the form of column crawl by 1 pixel, in some places the shift disappeared or accumulated to 3-4 pixels. And in Chrome, this bug was not observed.

Vain attempts to rectify the situation
Artifact arbitrarily manifested itself, then was absent on various tables and depended also on the width of the browser window. None of the columns in the table explicitly set the width. Therefore, the first thing that came to mind was the differences in the width of the original table and the new table with a fixed header. Having played around with the width, I couldn’t adjust anything, if in one place the table was displayed correctly, then where it was displayed it started to break normally. So it's not the width.
The second thing I decided to try was to play with the indentation on the right for the scrollbar. Added and turned off 1 pixel to the width, completely removed this indent. As a result, the result was the same as in the first attempt.
Then I decided to check the width of the columns after drawing and formatting the table header. Suddenly somewhere there was an error in the markup and the width of the table could change after the new element was drawn, but the width values ​​turned out to be identical before and after. No tricks with styles like border-box and display of the desired result were also given - the tables were also different.
')
Scandals, intrigues and investigations
Desperately, he picked up a calculator, opened the firebug and started folding the width of each column in an attempt to find where the table starts to leave. And ... firebug said that they all have the same width! How so? They are even visually different. Maybe a firebug issue in a bookmark with object markup? I look in DOM'e - there is the same value in clientWidth, the built-in inspector in FF produces similar values.
The eye can and can be deceived, but paint is unlikely. I copy the screen of the browser window into the editor and start reading the width of the columns. I reach the first curved column and paint gives a width of 1 pixel less than what the browser says! Returning back to the page. All browser tools and jQuery mother swear that the column width is 473 pixels, but paint firmly insists that in fact 472. Immediately I remembered Zadornov's monologue about roulette glued in the middle. Did the mother-in-law get to the developers? By the way, in IE, the situation exactly repeated what is happening in FF. Conspiracy?

The next hour I spend in Google trying to find existing column counting bugs or some features of the clientWidth or .width () functions. And to no avail. All that can be found is either about fractional values ​​in css or explicit jamb of authors of markup.
Drunk (s)
There must be a way to find out the correct width of the column, somehow the table is drawn by the browser and nothing crawls anywhere. Nothing remains except sorting out possible differences in the properties of the cells. I deduced properties of a column from DOM of the initial table and generated by a plug-in. I compare. It seems everything is the same ... except for offsetLeft. How so? Insert the crutch with the calculation of the width of the offset, for the last cell we will use the usual width:
this.nextSibling.offsetLeft - this.offsetLeft = 472
And now the tables have become the same in all my browsers.
What happens
The table layout does not contain the width of the columns and the browser automatically adjusts the width of the columns as desired based on the contents of the table. Somewhere the calculated value of the width is fractional, and then it seems that implementation problems begin.
Since the fractional width can not be drawn - the value is rounded, and this rounded value is substituted into the DOM. At certain ratios, a rounding error may accumulate and the overall width of the table will grow or shrink. If you believe the article
habrahabr.ru/post/31392 then FF tries to enter the content exactly the size of the parent and reduces the values ​​of some columns by 1 pixel so that they do not exceed the width of the table, the offsetLeft changes with the offset columns, but clientWidth is not! Therefore, when you try to create a copy of the table header, the script returns a width that is not reduced (or increased) by 1 pixel and the columns crawl away.
I do not see another option.
The situation is similar in IE, only there the inspector shows the fractional value of the column width, the clientWidth has a rounded value, and it is still drawn 1 pixel less. The same diagnosis, only the inspector does not lie.
In order to eliminate the situation that some error in the layout of the page we try to reproduce the bug in greenhouse conditions:
Hidden text <!DOCTYPE html> <html> <head> <script src="calc/jquery.js"></script> <script> $(document).ready(function(){ $(window).resize(function() { $('#tr > *').each(function() { var width1 = this.clientWidth; var width2; if ($(this).next('td').length) { width2 = $(this).next('td')[0].offsetLeft - this.offsetLeft; } console.log(width1, width2); }); }); }); </script> </head> <body> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr id="tr"> <td>1234556</td> <td>123455644</td> <td>12345</td> <td>12345565645</td> <td>123455643</td> <td>12345563453433</td> <td>12345565645</td> <td>123455643</td> <td>12345563453433</td> </tr> </table> </body> </html>
Indeed, in FF, when I change the width of the window, width1 and width2 sometimes differ by 1 pixel. Moreover, the difference may be either up or down, which excludes the use of different rounding methods when filling in the DOM and when drawing the page, but the problem is really somewhere at the stage of “compaction” of the table columns.
Of course, the location of elements with a fractional width or height is not a trivial task and can be solved differently, but I consider the inconsistency between the width specified in the DOM and the real one on the page to be forgivable.
Maybe I'm wrong in this situation and it is not necessary to create a bug reporter? This behavior is quite expected and in my case you need to use such a crutch to correctly align the width of the columns? I would like to hear your opinion.